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