source: trunk/prototype/app/plugins/datejs/core-debug.js @ 5341

Revision 5341, 22.5 KB checked in by wmerlotto, 12 years ago (diff)

Ticket #2434 - Commit inicial do novo módulo de agenda do Expresso - expressoCalendar

Line 
1/**
2 * Version: 1.0 Alpha-1
3 * Build Date: 12-Nov-2007
4 * Copyright (c) 2006-2007, Coolite Inc. (http://www.coolite.com/). All rights reserved.
5 * License: Licensed under The MIT License. See license.txt and http://www.datejs.com/license/.
6 * Website: http://www.datejs.com/ or http://www.coolite.com/datejs/
7 */
8
9/**
10 * Gets the month number (0-11) if given a Culture Info specific string which is a valid monthName or abbreviatedMonthName.
11 * @param {String}   The name of the month (eg. "February, "Feb", "october", "oct").
12 * @return {Number}  The day number
13 */
14Date.getMonthNumberFromName = function (name) {
15    var n = Date.CultureInfo.monthNames, m = Date.CultureInfo.abbreviatedMonthNames, s = name.toLowerCase();
16    for (var i = 0; i < n.length; i++) {
17        if (n[i].toLowerCase() == s || m[i].toLowerCase() == s) {
18            return i;
19        }
20    }
21    return -1;
22};
23
24/**
25 * Gets the day number (0-6) if given a CultureInfo specific string which is a valid dayName, abbreviatedDayName or shortestDayName (two char).
26 * @param {String}   The name of the day (eg. "Monday, "Mon", "tuesday", "tue", "We", "we").
27 * @return {Number}  The day number
28 */
29Date.getDayNumberFromName = function (name) {
30    var n = Date.CultureInfo.dayNames, m = Date.CultureInfo.abbreviatedDayNames, o = Date.CultureInfo.shortestDayNames, s = name.toLowerCase();
31    for (var i = 0; i < n.length; i++) {
32        if (n[i].toLowerCase() == s || m[i].toLowerCase() == s) {
33            return i;
34        }
35    }
36    return -1; 
37};
38
39/**
40 * Determines if the current date instance is within a LeapYear.
41 * @param {Number}   The year (0-9999).
42 * @return {Boolean} true if date is within a LeapYear, otherwise false.
43 */
44Date.isLeapYear = function (year) {
45    return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0));
46};
47
48/**
49 * Gets the number of days in the month, given a year and month value. Automatically corrects for LeapYear.
50 * @param {Number}   The year (0-9999).
51 * @param {Number}   The month (0-11).
52 * @return {Number}  The number of days in the month.
53 */
54Date.getDaysInMonth = function (year, month) {
55    return [31, (Date.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
56};
57
58Date.getTimezoneOffset = function (s, dst) {
59    return (dst || false) ? Date.CultureInfo.abbreviatedTimeZoneDST[s.toUpperCase()] :
60        Date.CultureInfo.abbreviatedTimeZoneStandard[s.toUpperCase()];
61};
62
63Date.getTimezoneAbbreviation = function (offset, dst) {
64    var n = (dst || false) ? Date.CultureInfo.abbreviatedTimeZoneDST : Date.CultureInfo.abbreviatedTimeZoneStandard, p;
65    for (p in n) {
66        if (n[p] === offset) {
67            return p;
68        }
69    }
70    return null;
71};
72
73/**
74 * Returns a new Date object that is an exact date and time copy of the original instance.
75 * @return {Date}    A new Date instance
76 */
77Date.prototype.clone = function () {
78    return new Date(this.getTime());
79};
80
81/**
82 * Compares this instance to a Date object and return an number indication of their relative values. 
83 * @param {Date}     Date object to compare [Required]
84 * @return {Number}  1 = this is greaterthan date. -1 = this is lessthan date. 0 = values are equal
85 */
86Date.prototype.compareTo = function (date) {
87    if (isNaN(this)) {
88        throw new Error(this);
89    }
90    if (date instanceof Date && !isNaN(date)) {
91        return (this > date) ? 1 : (this < date) ? -1 : 0;
92    } else {
93        throw new TypeError(date);
94    }
95};
96
97/**
98 * Compares this instance to another Date object and returns true if they are equal. 
99 * @param {Date}     Date object to compare [Required]
100 * @return {Boolean} true if dates are equal. false if they are not equal.
101 */
102Date.prototype.equals = function (date) {
103    return (this.compareTo(date) === 0);
104};
105
106/**
107 * Determines is this instance is between a range of two dates or equal to either the start or end dates.
108 * @param {Date}     Start of range [Required]
109 * @param {Date}     End of range [Required]
110 * @return {Boolean} true is this is between or equal to the start and end dates, else false
111 */
112Date.prototype.between = function (start, end) {
113    var t = this.getTime();
114    return t >= start.getTime() && t <= end.getTime();
115};
116
117/**
118 * Adds the specified number of milliseconds to this instance.
119 * @param {Number}   The number of milliseconds to add. The number can be positive or negative [Required]
120 * @return {Date}    this
121 */
122Date.prototype.addMilliseconds = function (value) {
123    this.setMilliseconds(this.getMilliseconds() + value);
124    return this;
125};
126
127/**
128 * Adds the specified number of seconds to this instance.
129 * @param {Number}   The number of seconds to add. The number can be positive or negative [Required]
130 * @return {Date}    this
131 */
132Date.prototype.addSeconds = function (value) {
133    return this.addMilliseconds(value * 1000);
134};
135
136/**
137 * Adds the specified number of seconds to this instance.
138 * @param {Number}   The number of seconds to add. The number can be positive or negative [Required]
139 * @return {Date}    this
140 */
141Date.prototype.addMinutes = function (value) {
142    return this.addMilliseconds(value * 60000); /* 60*1000 */
143};
144
145/**
146 * Adds the specified number of hours to this instance.
147 * @param {Number}   The number of hours to add. The number can be positive or negative [Required]
148 * @return {Date}    this
149 */
150Date.prototype.addHours = function (value) {
151    return this.addMilliseconds(value * 3600000); /* 60*60*1000 */
152};
153
154/**
155 * Adds the specified number of days to this instance.
156 * @param {Number}   The number of days to add. The number can be positive or negative [Required]
157 * @return {Date}    this
158 */
159Date.prototype.addDays = function (value) {
160    return this.addMilliseconds(value * 86400000); /* 60*60*24*1000 */
161};
162
163/**
164 * Adds the specified number of weeks to this instance.
165 * @param {Number}   The number of weeks to add. The number can be positive or negative [Required]
166 * @return {Date}    this
167 */
168Date.prototype.addWeeks = function (value) {
169    return this.addMilliseconds(value * 604800000); /* 60*60*24*7*1000 */
170};
171
172/**
173 * Adds the specified number of months to this instance.
174 * @param {Number}   The number of months to add. The number can be positive or negative [Required]
175 * @return {Date}    this
176 */
177Date.prototype.addMonths = function (value) {
178    var n = this.getDate();
179    this.setDate(1);
180    this.setMonth(this.getMonth() + value);
181    this.setDate(Math.min(n, this.getDaysInMonth()));
182    return this;
183};
184
185/**
186 * Adds the specified number of years to this instance.
187 * @param {Number}   The number of years to add. The number can be positive or negative [Required]
188 * @return {Date}    this
189 */
190Date.prototype.addYears = function (value) {
191    return this.addMonths(value * 12);
192};
193
194/**
195 * Adds (or subtracts) to the value of the year, month, day, hour, minute, second, millisecond of the date instance using given configuration object. Positive and Negative values allowed.
196 * Example
197<pre><code>
198Date.today().add( { day: 1, month: 1 } )
199 
200new Date().add( { year: -1 } )
201</code></pre>
202 * @param {Object}   Configuration object containing attributes (month, day, etc.)
203 * @return {Date}    this
204 */
205Date.prototype.add = function (config) {
206    if (typeof config == "number") {
207        this._orient = config;
208        return this;   
209    }
210    var x = config;
211    if (x.millisecond || x.milliseconds) {
212        this.addMilliseconds(x.millisecond || x.milliseconds);
213    }
214    if (x.second || x.seconds) {
215        this.addSeconds(x.second || x.seconds);
216    }
217    if (x.minute || x.minutes) {
218        this.addMinutes(x.minute || x.minutes);
219    }
220    if (x.hour || x.hours) {
221        this.addHours(x.hour || x.hours);
222    }
223    if (x.month || x.months) {
224        this.addMonths(x.month || x.months);
225    }
226    if (x.year || x.years) {
227        this.addYears(x.year || x.years);
228    }
229    if (x.day || x.days) {
230        this.addDays(x.day || x.days);
231    }
232    return this;
233};
234
235// private
236Date._validate = function (value, min, max, name) {
237    if (typeof value != "number") {
238        throw new TypeError(value + " is not a Number.");
239    } else if (value < min || value > max) {
240        throw new RangeError(value + " is not a valid value for " + name + ".");
241    }
242    return true;
243};
244
245/**
246 * Validates the number is within an acceptable range for milliseconds [0-999].
247 * @param {Number}   The number to check if within range.
248 * @return {Boolean} true if within range, otherwise false.
249 */
250Date.validateMillisecond = function (n) {
251    return Date._validate(n, 0, 999, "milliseconds");
252};
253
254/**
255 * Validates the number is within an acceptable range for seconds [0-59].
256 * @param {Number}   The number to check if within range.
257 * @return {Boolean} true if within range, otherwise false.
258 */
259Date.validateSecond = function (n) {
260    return Date._validate(n, 0, 59, "seconds");
261};
262
263/**
264 * Validates the number is within an acceptable range for minutes [0-59].
265 * @param {Number}   The number to check if within range.
266 * @return {Boolean} true if within range, otherwise false.
267 */
268Date.validateMinute = function (n) {
269    return Date._validate(n, 0, 59, "minutes");
270};
271
272/**
273 * Validates the number is within an acceptable range for hours [0-23].
274 * @param {Number}   The number to check if within range.
275 * @return {Boolean} true if within range, otherwise false.
276 */
277Date.validateHour = function (n) {
278    return Date._validate(n, 0, 23, "hours");
279};
280
281/**
282 * Validates the number is within an acceptable range for the days in a month [0-MaxDaysInMonth].
283 * @param {Number}   The number to check if within range.
284 * @return {Boolean} true if within range, otherwise false.
285 */
286Date.validateDay = function (n, year, month) {
287    return Date._validate(n, 1, Date.getDaysInMonth(year, month), "days");
288};
289
290/**
291 * Validates the number is within an acceptable range for months [0-11].
292 * @param {Number}   The number to check if within range.
293 * @return {Boolean} true if within range, otherwise false.
294 */
295Date.validateMonth = function (n) {
296    return Date._validate(n, 0, 11, "months");
297};
298
299/**
300 * Validates the number is within an acceptable range for years [0-9999].
301 * @param {Number}   The number to check if within range.
302 * @return {Boolean} true if within range, otherwise false.
303 */
304Date.validateYear = function (n) {
305    return Date._validate(n, 1, 9999, "seconds");
306};
307
308/**
309 * Set the value of year, month, day, hour, minute, second, millisecond of date instance using given configuration object.
310 * Example
311<pre><code>
312Date.today().set( { day: 20, month: 1 } )
313
314new Date().set( { millisecond: 0 } )
315</code></pre>
316 *
317 * @param {Object}   Configuration object containing attributes (month, day, etc.)
318 * @return {Date}    this
319 */
320Date.prototype.set = function (config) {
321    var x = config;
322
323    if (!x.millisecond && x.millisecond !== 0) {
324        x.millisecond = -1;
325    }
326    if (!x.second && x.second !== 0) {
327        x.second = -1;
328    }
329    if (!x.minute && x.minute !== 0) {
330        x.minute = -1;
331    }
332    if (!x.hour && x.hour !== 0) {
333        x.hour = -1;
334    }
335    if (!x.day && x.day !== 0) {
336        x.day = -1;
337    }
338    if (!x.month && x.month !== 0) {
339        x.month = -1;
340    }
341    if (!x.year && x.year !== 0) {
342        x.year = -1;
343    }
344
345    if (x.millisecond != -1 && Date.validateMillisecond(x.millisecond)) {
346        this.addMilliseconds(x.millisecond - this.getMilliseconds());
347    }
348    if (x.second != -1 && Date.validateSecond(x.second)) {
349        this.addSeconds(x.second - this.getSeconds());
350    }
351    if (x.minute != -1 && Date.validateMinute(x.minute)) {
352        this.addMinutes(x.minute - this.getMinutes());
353    }
354    if (x.hour != -1 && Date.validateHour(x.hour)) {
355        this.addHours(x.hour - this.getHours());
356    }
357    if (x.month !== -1 && Date.validateMonth(x.month)) {
358        this.addMonths(x.month - this.getMonth());
359    }
360    if (x.year != -1 && Date.validateYear(x.year)) {
361        this.addYears(x.year - this.getFullYear());
362    }
363   
364        /* day has to go last because you can't validate the day without first knowing the month */
365    if (x.day != -1 && Date.validateDay(x.day, this.getFullYear(), this.getMonth())) {
366        this.addDays(x.day - this.getDate());
367    }
368    if (x.timezone) {
369        this.setTimezone(x.timezone);
370    }
371    if (x.timezoneOffset) {
372        this.setTimezoneOffset(x.timezoneOffset);
373    }
374   
375    return this;   
376};
377
378/**
379 * Resets the time of this Date object to 12:00 AM (00:00), which is the start of the day.
380 * @return {Date}    this
381 */
382Date.prototype.clearTime = function () {
383    this.setHours(0);
384    this.setMinutes(0);
385    this.setSeconds(0);
386    this.setMilliseconds(0);
387    return this;
388};
389
390/**
391 * Determines whether or not this instance is in a leap year.
392 * @return {Boolean} true if this instance is in a leap year, else false
393 */
394Date.prototype.isLeapYear = function () {
395    var y = this.getFullYear();
396    return (((y % 4 === 0) && (y % 100 !== 0)) || (y % 400 === 0));
397};
398
399/**
400 * Determines whether or not this instance is a weekday.
401 * @return {Boolean} true if this instance is a weekday
402 */
403Date.prototype.isWeekday = function () {
404    return !(this.is().sat() || this.is().sun());
405};
406
407/**
408 * Get the number of days in the current month, adjusted for leap year.
409 * @return {Number}  The number of days in the month
410 */
411Date.prototype.getDaysInMonth = function () {
412    return Date.getDaysInMonth(this.getFullYear(), this.getMonth());
413};
414
415/**
416 * Moves the date to the first day of the month.
417 * @return {Date}    this
418 */
419Date.prototype.moveToFirstDayOfMonth = function () {
420    return this.set({ day: 1 });
421};
422
423/**
424 * Moves the date to the last day of the month.
425 * @return {Date}    this
426 */
427Date.prototype.moveToLastDayOfMonth = function () {
428    return this.set({ day: this.getDaysInMonth()});
429};
430
431/**
432 * Move to the next or last dayOfWeek based on the orient value.
433 * @param {Number}   The dayOfWeek to move to.
434 * @param {Number}   Forward (+1) or Back (-1). Defaults to +1. [Optional]
435 * @return {Date}    this
436 */
437Date.prototype.moveToDayOfWeek = function (day, orient) {
438    var diff = (day - this.getDay() + 7 * (orient || +1)) % 7;
439    return this.addDays((diff === 0) ? diff += 7 * (orient || +1) : diff);
440};
441
442/**
443 * Move to the next or last month based on the orient value.
444 * @param {Number}   The month to move to. 0 = January, 11 = December.
445 * @param {Number}   Forward (+1) or Back (-1). Defaults to +1. [Optional]
446 * @return {Date}    this
447 */
448Date.prototype.moveToMonth = function (month, orient) {
449    var diff = (month - this.getMonth() + 12 * (orient || +1)) % 12;
450    return this.addMonths((diff === 0) ? diff += 12 * (orient || +1) : diff);
451};
452
453/**
454 * Get the numeric day number of the year, adjusted for leap year.
455 * @return {Number} 0 through 364 (365 in leap years)
456 */
457Date.prototype.getDayOfYear = function () {
458    return Math.floor((this - new Date(this.getFullYear(), 0, 1)) / 86400000);
459};
460
461/**
462 * Get the week of the year for the current date instance.
463 * @param {Number}   A Number that represents the first day of the week (0-6) [Optional]
464 * @return {Number}  0 through 53
465 */
466Date.prototype.getWeekOfYear = function (firstDayOfWeek) {
467    var y = this.getFullYear(), m = this.getMonth(), d = this.getDate();
468   
469    var dow = firstDayOfWeek || Date.CultureInfo.firstDayOfWeek;
470       
471    var offset = 7 + 1 - new Date(y, 0, 1).getDay();
472    if (offset == 8) {
473        offset = 1;
474    }
475    var daynum = ((Date.UTC(y, m, d, 0, 0, 0) - Date.UTC(y, 0, 1, 0, 0, 0)) / 86400000) + 1;
476    var w = Math.floor((daynum - offset + 7) / 7);
477    if (w === dow) {
478        y--;
479        var prevOffset = 7 + 1 - new Date(y, 0, 1).getDay();
480        if (prevOffset == 2 || prevOffset == 8) {
481            w = 53;
482        } else {
483            w = 52;
484        }
485    }
486    return w;
487};
488
489/**
490 * Determine whether Daylight Saving Time (DST) is in effect
491 * @return {Boolean} True if DST is in effect.
492 */
493Date.prototype.isDST = function () {
494    console.log('isDST');
495    /* TODO: not sure if this is portable ... get from Date.CultureInfo? */
496    return this.toString().match(/(E|C|M|P)(S|D)T/)[2] == "D";
497};
498
499/**
500 * Get the timezone abbreviation of the current date.
501 * @return {String} The abbreviated timezone name (e.g. "EST")
502 */
503Date.prototype.getTimezone = function () {
504    return Date.getTimezoneAbbreviation(this.getUTCOffset, this.isDST());
505};
506
507Date.prototype.setTimezoneOffset = function (s) {
508    var here = this.getTimezoneOffset(), there = Number(s) * -6 / 10;
509    this.addMinutes(there - here);
510    return this;
511};
512
513Date.prototype.setTimezone = function (s) {
514    return this.setTimezoneOffset(Date.getTimezoneOffset(s));
515};
516
517/**
518 * Get the offset from UTC of the current date.
519 * @return {String} The 4-character offset string prefixed with + or - (e.g. "-0500")
520 */
521Date.prototype.getUTCOffset = function () {
522    var n = this.getTimezoneOffset() * -10 / 6, r;
523    if (n < 0) {
524        r = (n - 10000).toString();
525        return r[0] + r.substr(2);
526    } else {
527        r = (n + 10000).toString(); 
528        return "+" + r.substr(1);
529    }
530};
531
532/**
533 * Gets the name of the day of the week.
534 * @param {Boolean}  true to return the abbreviated name of the day of the week
535 * @return {String}  The name of the day
536 */
537Date.prototype.getDayName = function (abbrev) {
538    return abbrev ? Date.CultureInfo.abbreviatedDayNames[this.getDay()] :
539        Date.CultureInfo.dayNames[this.getDay()];
540};
541
542/**
543 * Gets the month name.
544 * @param {Boolean}  true to return the abbreviated name of the month
545 * @return {String}  The name of the month
546 */
547Date.prototype.getMonthName = function (abbrev) {
548    return abbrev ? Date.CultureInfo.abbreviatedMonthNames[this.getMonth()] :
549        Date.CultureInfo.monthNames[this.getMonth()];
550};
551
552// private
553Date.prototype._toString = Date.prototype.toString;
554
555/**
556 * Converts the value of the current Date object to its equivalent string representation.
557 * Format Specifiers
558<pre>
559Format  Description                                                                  Example
560------  ---------------------------------------------------------------------------  -----------------------
561 s      The seconds of the minute between 1-59.                                      "1" to "59"
562 ss     The seconds of the minute with leading zero if required.                     "01" to "59"
563 
564 m      The minute of the hour between 0-59.                                         "1"  or "59"
565 mm     The minute of the hour with leading zero if required.                        "01" or "59"
566 
567 h      The hour of the day between 1-12.                                            "1"  to "12"
568 hh     The hour of the day with leading zero if required.                           "01" to "12"
569 
570 H      The hour of the day between 1-23.                                            "1"  to "23"
571 HH     The hour of the day with leading zero if required.                           "01" to "23"
572 
573 d      The day of the month between 1 and 31.                                       "1"  to "31"
574 dd     The day of the month with leading zero if required.                          "01" to "31"
575 ddd    Abbreviated day name. Date.CultureInfo.abbreviatedDayNames.                  "Mon" to "Sun"
576 dddd   The full day name. Date.CultureInfo.dayNames.                                "Monday" to "Sunday"
577 
578 M      The month of the year between 1-12.                                          "1" to "12"
579 MM     The month of the year with leading zero if required.                         "01" to "12"
580 MMM    Abbreviated month name. Date.CultureInfo.abbreviatedMonthNames.              "Jan" to "Dec"
581 MMMM   The full month name. Date.CultureInfo.monthNames.                            "January" to "December"
582
583 yy     Displays the year as a maximum two-digit number.                             "99" or "07"
584 yyyy   Displays the full four digit year.                                           "1999" or "2007"
585 
586 t      Displays the first character of the A.M./P.M. designator.                    "A" or "P"
587        Date.CultureInfo.amDesignator or Date.CultureInfo.pmDesignator
588 tt     Displays the A.M./P.M. designator.                                           "AM" or "PM"
589        Date.CultureInfo.amDesignator or Date.CultureInfo.pmDesignator
590</pre>
591 * @param {String}   A format string consisting of one or more format spcifiers [Optional].
592 * @return {String}  A string representation of the current Date object.
593 */
594Date.prototype.toString = function (format) {
595    var self = this;
596
597    var p = function p(s) {
598        return (s.toString().length == 1) ? "0" + s : s;
599    };
600
601    return format ? format.replace(/dd?d?d?|MM?M?M?|yy?y?y?|hh?|HH?|mm?|ss?|tt?|zz?z?/g,
602    function (format) {
603        switch (format) {
604        case "hh":
605            return p(self.getHours() < 13 ? self.getHours() : (self.getHours() - 12));
606        case "h":
607            return self.getHours() < 13 ? self.getHours() : (self.getHours() - 12);
608        case "HH":
609            return p(self.getHours());
610        case "H":
611            return self.getHours();
612        case "mm":
613            return p(self.getMinutes());
614        case "m":
615            return self.getMinutes();
616        case "ss":
617            return p(self.getSeconds());
618        case "s":
619            return self.getSeconds();
620        case "yyyy":
621            return self.getFullYear();
622        case "yy":
623            return self.getFullYear().toString().substring(2, 4);
624        case "dddd":
625            return self.getDayName();
626        case "ddd":
627            return self.getDayName(true);
628        case "dd":
629            return p(self.getDate());
630        case "d":
631            return self.getDate().toString();
632        case "MMMM":
633            return self.getMonthName();
634        case "MMM":
635            return self.getMonthName(true);
636        case "MM":
637            return p((self.getMonth() + 1));
638        case "M":
639            return self.getMonth() + 1;
640        case "t":
641            return self.getHours() < 12 ? Date.CultureInfo.amDesignator.substring(0, 1) : Date.CultureInfo.pmDesignator.substring(0, 1);
642        case "tt":
643            return self.getHours() < 12 ? Date.CultureInfo.amDesignator : Date.CultureInfo.pmDesignator;
644        case "zzz":
645        case "zz":
646        case "z":
647            return "";
648        }
649    }
650    ) : this._toString();
651};
Note: See TracBrowser for help on using the repository browser.