source: Dev/branches/rest-dojo-ui/client/dojo/date.js @ 256

Last change on this file since 256 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

File size: 9.5 KB
RevLine 
[256]1define(["./_base/kernel", "./_base/lang"], function(dojo, lang) {
2        // module:
3        //              dojo/date
4        // summary:
5        //              TODOC
6
7lang.getObject("date", true, dojo);
8
9/*=====
10dojo.date = {
11        // summary: Date manipulation utilities
12}
13=====*/
14
15dojo.date.getDaysInMonth = function(/*Date*/dateObject){
16        //      summary:
17        //              Returns the number of days in the month used by dateObject
18        var month = dateObject.getMonth();
19        var days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
20        if(month == 1 && dojo.date.isLeapYear(dateObject)){ return 29; } // Number
21        return days[month]; // Number
22};
23
24dojo.date.isLeapYear = function(/*Date*/dateObject){
25        //      summary:
26        //              Determines if the year of the dateObject is a leap year
27        //      description:
28        //              Leap years are years with an additional day YYYY-02-29, where the
29        //              year number is a multiple of four with the following exception: If
30        //              a year is a multiple of 100, then it is only a leap year if it is
31        //              also a multiple of 400. For example, 1900 was not a leap year, but
32        //              2000 is one.
33
34        var year = dateObject.getFullYear();
35        return !(year%400) || (!(year%4) && !!(year%100)); // Boolean
36};
37
38// FIXME: This is not localized
39dojo.date.getTimezoneName = function(/*Date*/dateObject){
40        //      summary:
41        //              Get the user's time zone as provided by the browser
42        // dateObject:
43        //              Needed because the timezone may vary with time (daylight savings)
44        //      description:
45        //              Try to get time zone info from toString or toLocaleString method of
46        //              the Date object -- UTC offset is not a time zone.  See
47        //              http://www.twinsun.com/tz/tz-link.htm Note: results may be
48        //              inconsistent across browsers.
49
50        var str = dateObject.toString(); // Start looking in toString
51        var tz = ''; // The result -- return empty string if nothing found
52        var match;
53
54        // First look for something in parentheses -- fast lookup, no regex
55        var pos = str.indexOf('(');
56        if(pos > -1){
57                tz = str.substring(++pos, str.indexOf(')'));
58        }else{
59                // If at first you don't succeed ...
60                // If IE knows about the TZ, it appears before the year
61                // Capital letters or slash before a 4-digit year
62                // at the end of string
63                var pat = /([A-Z\/]+) \d{4}$/;
64                if((match = str.match(pat))){
65                        tz = match[1];
66                }else{
67                // Some browsers (e.g. Safari) glue the TZ on the end
68                // of toLocaleString instead of putting it in toString
69                        str = dateObject.toLocaleString();
70                        // Capital letters or slash -- end of string,
71                        // after space
72                        pat = / ([A-Z\/]+)$/;
73                        if((match = str.match(pat))){
74                                tz = match[1];
75                        }
76                }
77        }
78
79        // Make sure it doesn't somehow end up return AM or PM
80        return (tz == 'AM' || tz == 'PM') ? '' : tz; // String
81};
82
83// Utility methods to do arithmetic calculations with Dates
84
85dojo.date.compare = function(/*Date*/date1, /*Date?*/date2, /*String?*/portion){
86        //      summary:
87        //              Compare two date objects by date, time, or both.
88        //      description:
89        //      Returns 0 if equal, positive if a > b, else negative.
90        //      date1:
91        //              Date object
92        //      date2:
93        //              Date object.  If not specified, the current Date is used.
94        //      portion:
95        //              A string indicating the "date" or "time" portion of a Date object.
96        //              Compares both "date" and "time" by default.  One of the following:
97        //              "date", "time", "datetime"
98
99        // Extra step required in copy for IE - see #3112
100        date1 = new Date(+date1);
101        date2 = new Date(+(date2 || new Date()));
102
103        if(portion == "date"){
104                // Ignore times and compare dates.
105                date1.setHours(0, 0, 0, 0);
106                date2.setHours(0, 0, 0, 0);
107        }else if(portion == "time"){
108                // Ignore dates and compare times.
109                date1.setFullYear(0, 0, 0);
110                date2.setFullYear(0, 0, 0);
111        }
112
113        if(date1 > date2){ return 1; } // int
114        if(date1 < date2){ return -1; } // int
115        return 0; // int
116};
117
118dojo.date.add = function(/*Date*/date, /*String*/interval, /*int*/amount){
119        //      summary:
120        //              Add to a Date in intervals of different size, from milliseconds to years
121        //      date: Date
122        //              Date object to start with
123        //      interval:
124        //              A string representing the interval.  One of the following:
125        //                      "year", "month", "day", "hour", "minute", "second",
126        //                      "millisecond", "quarter", "week", "weekday"
127        //      amount:
128        //              How much to add to the date.
129
130        var sum = new Date(+date); // convert to Number before copying to accomodate IE (#3112)
131        var fixOvershoot = false;
132        var property = "Date";
133
134        switch(interval){
135                case "day":
136                        break;
137                case "weekday":
138                        //i18n FIXME: assumes Saturday/Sunday weekend, but this is not always true.  see dojo.cldr.supplemental
139
140                        // Divide the increment time span into weekspans plus leftover days
141                        // e.g., 8 days is one 5-day weekspan / and two leftover days
142                        // Can't have zero leftover days, so numbers divisible by 5 get
143                        // a days value of 5, and the remaining days make up the number of weeks
144                        var days, weeks;
145                        var mod = amount % 5;
146                        if(!mod){
147                                days = (amount > 0) ? 5 : -5;
148                                weeks = (amount > 0) ? ((amount-5)/5) : ((amount+5)/5);
149                        }else{
150                                days = mod;
151                                weeks = parseInt(amount/5);
152                        }
153                        // Get weekday value for orig date param
154                        var strt = date.getDay();
155                        // Orig date is Sat / positive incrementer
156                        // Jump over Sun
157                        var adj = 0;
158                        if(strt == 6 && amount > 0){
159                                adj = 1;
160                        }else if(strt == 0 && amount < 0){
161                        // Orig date is Sun / negative incrementer
162                        // Jump back over Sat
163                                adj = -1;
164                        }
165                        // Get weekday val for the new date
166                        var trgt = strt + days;
167                        // New date is on Sat or Sun
168                        if(trgt == 0 || trgt == 6){
169                                adj = (amount > 0) ? 2 : -2;
170                        }
171                        // Increment by number of weeks plus leftover days plus
172                        // weekend adjustments
173                        amount = (7 * weeks) + days + adj;
174                        break;
175                case "year":
176                        property = "FullYear";
177                        // Keep increment/decrement from 2/29 out of March
178                        fixOvershoot = true;
179                        break;
180                case "week":
181                        amount *= 7;
182                        break;
183                case "quarter":
184                        // Naive quarter is just three months
185                        amount *= 3;
186                        // fallthrough...
187                case "month":
188                        // Reset to last day of month if you overshoot
189                        fixOvershoot = true;
190                        property = "Month";
191                        break;
192//              case "hour":
193//              case "minute":
194//              case "second":
195//              case "millisecond":
196                default:
197                        property = "UTC"+interval.charAt(0).toUpperCase() + interval.substring(1) + "s";
198        }
199
200        if(property){
201                sum["set"+property](sum["get"+property]()+amount);
202        }
203
204        if(fixOvershoot && (sum.getDate() < date.getDate())){
205                sum.setDate(0);
206        }
207
208        return sum; // Date
209};
210
211dojo.date.difference = function(/*Date*/date1, /*Date?*/date2, /*String?*/interval){
212        //      summary:
213        //              Get the difference in a specific unit of time (e.g., number of
214        //              months, weeks, days, etc.) between two dates, rounded to the
215        //              nearest integer.
216        //      date1:
217        //              Date object
218        //      date2:
219        //              Date object.  If not specified, the current Date is used.
220        //      interval:
221        //              A string representing the interval.  One of the following:
222        //                      "year", "month", "day", "hour", "minute", "second",
223        //                      "millisecond", "quarter", "week", "weekday"
224        //              Defaults to "day".
225
226        date2 = date2 || new Date();
227        interval = interval || "day";
228        var yearDiff = date2.getFullYear() - date1.getFullYear();
229        var delta = 1; // Integer return value
230
231        switch(interval){
232                case "quarter":
233                        var m1 = date1.getMonth();
234                        var m2 = date2.getMonth();
235                        // Figure out which quarter the months are in
236                        var q1 = Math.floor(m1/3) + 1;
237                        var q2 = Math.floor(m2/3) + 1;
238                        // Add quarters for any year difference between the dates
239                        q2 += (yearDiff * 4);
240                        delta = q2 - q1;
241                        break;
242                case "weekday":
243                        var days = Math.round(dojo.date.difference(date1, date2, "day"));
244                        var weeks = parseInt(dojo.date.difference(date1, date2, "week"));
245                        var mod = days % 7;
246
247                        // Even number of weeks
248                        if(mod == 0){
249                                days = weeks*5;
250                        }else{
251                                // Weeks plus spare change (< 7 days)
252                                var adj = 0;
253                                var aDay = date1.getDay();
254                                var bDay = date2.getDay();
255
256                                weeks = parseInt(days/7);
257                                mod = days % 7;
258                                // Mark the date advanced by the number of
259                                // round weeks (may be zero)
260                                var dtMark = new Date(date1);
261                                dtMark.setDate(dtMark.getDate()+(weeks*7));
262                                var dayMark = dtMark.getDay();
263
264                                // Spare change days -- 6 or less
265                                if(days > 0){
266                                        switch(true){
267                                                // Range starts on Sat
268                                                case aDay == 6:
269                                                        adj = -1;
270                                                        break;
271                                                // Range starts on Sun
272                                                case aDay == 0:
273                                                        adj = 0;
274                                                        break;
275                                                // Range ends on Sat
276                                                case bDay == 6:
277                                                        adj = -1;
278                                                        break;
279                                                // Range ends on Sun
280                                                case bDay == 0:
281                                                        adj = -2;
282                                                        break;
283                                                // Range contains weekend
284                                                case (dayMark + mod) > 5:
285                                                        adj = -2;
286                                        }
287                                }else if(days < 0){
288                                        switch(true){
289                                                // Range starts on Sat
290                                                case aDay == 6:
291                                                        adj = 0;
292                                                        break;
293                                                // Range starts on Sun
294                                                case aDay == 0:
295                                                        adj = 1;
296                                                        break;
297                                                // Range ends on Sat
298                                                case bDay == 6:
299                                                        adj = 2;
300                                                        break;
301                                                // Range ends on Sun
302                                                case bDay == 0:
303                                                        adj = 1;
304                                                        break;
305                                                // Range contains weekend
306                                                case (dayMark + mod) < 0:
307                                                        adj = 2;
308                                        }
309                                }
310                                days += adj;
311                                days -= (weeks*2);
312                        }
313                        delta = days;
314                        break;
315                case "year":
316                        delta = yearDiff;
317                        break;
318                case "month":
319                        delta = (date2.getMonth() - date1.getMonth()) + (yearDiff * 12);
320                        break;
321                case "week":
322                        // Truncate instead of rounding
323                        // Don't use Math.floor -- value may be negative
324                        delta = parseInt(dojo.date.difference(date1, date2, "day")/7);
325                        break;
326                case "day":
327                        delta /= 24;
328                        // fallthrough
329                case "hour":
330                        delta /= 60;
331                        // fallthrough
332                case "minute":
333                        delta /= 60;
334                        // fallthrough
335                case "second":
336                        delta /= 1000;
337                        // fallthrough
338                case "millisecond":
339                        delta *= date2.getTime() - date1.getTime();
340        }
341
342        // Round for fractional values and DST leaps
343        return Math.round(delta); // Number (integer)
344};
345
346return dojo.date;
347});
Note: See TracBrowser for help on using the repository browser.