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