Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
YUI.add('yui2-datemath', function(Y) {
2
    var YAHOO    = Y.YUI2;
3
    /*
4
Copyright (c) 2011, Yahoo! Inc. All rights reserved.
5
Code licensed under the BSD License:
6
http://developer.yahoo.com/yui/license.html
7
version: 2.9.0
8
*/
9
/**
10
* The datemath module provides utility methods for basic JavaScript Date object manipulation and
11
* comparison.
12
*
13
* @module datemath
14
*/
15
 
16
/**
17
* YAHOO.widget.DateMath is used for simple date manipulation. The class is a static utility
18
* used for adding, subtracting, and comparing dates.
19
* @namespace YAHOO.widget
20
* @class DateMath
21
*/
22
YAHOO.widget.DateMath = {
23
    /**
24
    * Constant field representing Day
25
    * @property DAY
26
    * @static
27
    * @final
28
    * @type String
29
    */
30
    DAY : "D",
31
 
32
    /**
33
    * Constant field representing Week
34
    * @property WEEK
35
    * @static
36
    * @final
37
    * @type String
38
    */
39
    WEEK : "W",
40
 
41
    /**
42
    * Constant field representing Year
43
    * @property YEAR
44
    * @static
45
    * @final
46
    * @type String
47
    */
48
    YEAR : "Y",
49
 
50
    /**
51
    * Constant field representing Month
52
    * @property MONTH
53
    * @static
54
    * @final
55
    * @type String
56
    */
57
    MONTH : "M",
58
 
59
    /**
60
    * Constant field representing one day, in milliseconds
61
    * @property ONE_DAY_MS
62
    * @static
63
    * @final
64
    * @type Number
65
    */
66
    ONE_DAY_MS : 1000*60*60*24,
67
 
68
    /**
69
     * Constant field representing the date in first week of January
70
     * which identifies the first week of the year.
71
     * <p>
72
     * In the U.S, Jan 1st is normally used based on a Sunday start of week.
73
     * ISO 8601, used widely throughout Europe, uses Jan 4th, based on a Monday start of week.
74
     * </p>
75
     * @property WEEK_ONE_JAN_DATE
76
     * @static
77
     * @type Number
78
     */
79
    WEEK_ONE_JAN_DATE : 1,
80
 
81
    /**
82
    * Adds the specified amount of time to the this instance.
83
    * @method add
84
    * @param {Date} date The JavaScript Date object to perform addition on
85
    * @param {String} field The field constant to be used for performing addition.
86
    * @param {Number} amount The number of units (measured in the field constant) to add to the date.
87
    * @return {Date} The resulting Date object
88
    */
89
    add : function(date, field, amount) {
90
        var d = new Date(date.getTime());
91
        switch (field) {
92
            case this.MONTH:
93
                var newMonth = date.getMonth() + amount;
94
                var years = 0;
95
 
96
                if (newMonth < 0) {
97
                    while (newMonth < 0) {
98
                        newMonth += 12;
99
                        years -= 1;
100
                    }
101
                } else if (newMonth > 11) {
102
                    while (newMonth > 11) {
103
                        newMonth -= 12;
104
                        years += 1;
105
                    }
106
                }
107
 
108
                d.setMonth(newMonth);
109
                d.setFullYear(date.getFullYear() + years);
110
                break;
111
            case this.DAY:
112
                this._addDays(d, amount);
113
                // d.setDate(date.getDate() + amount);
114
                break;
115
            case this.YEAR:
116
                d.setFullYear(date.getFullYear() + amount);
117
                break;
118
            case this.WEEK:
119
                this._addDays(d, (amount * 7));
120
                // d.setDate(date.getDate() + (amount * 7));
121
                break;
122
        }
123
        return d;
124
    },
125
 
126
    /**
127
     * Private helper method to account for bug in Safari 2 (webkit < 420)
128
     * when Date.setDate(n) is called with n less than -128 or greater than 127.
129
     * <p>
130
     * Fix approach and original findings are available here:
131
     * http://brianary.blogspot.com/2006/03/safari-date-bug.html
132
     * </p>
133
     * @method _addDays
134
     * @param {Date} d JavaScript date object
135
     * @param {Number} nDays The number of days to add to the date object (can be negative)
136
     * @private
137
     */
138
    _addDays : function(d, nDays) {
139
        if (YAHOO.env.ua.webkit && YAHOO.env.ua.webkit < 420) {
140
            if (nDays < 0) {
141
                // Ensure we don't go below -128 (getDate() is always 1 to 31, so we won't go above 127)
142
                for(var min = -128; nDays < min; nDays -= min) {
143
                    d.setDate(d.getDate() + min);
144
                }
145
            } else {
146
                // Ensure we don't go above 96 + 31 = 127
147
                for(var max = 96; nDays > max; nDays -= max) {
148
                    d.setDate(d.getDate() + max);
149
                }
150
            }
151
            // nDays should be remainder between -128 and 96
152
        }
153
        d.setDate(d.getDate() + nDays);
154
    },
155
 
156
    /**
157
    * Subtracts the specified amount of time from the this instance.
158
    * @method subtract
159
    * @param {Date} date The JavaScript Date object to perform subtraction on
160
    * @param {Number} field The this field constant to be used for performing subtraction.
161
    * @param {Number} amount The number of units (measured in the field constant) to subtract from the date.
162
    * @return {Date} The resulting Date object
163
    */
164
    subtract : function(date, field, amount) {
165
        return this.add(date, field, (amount*-1));
166
    },
167
 
168
    /**
169
    * Determines whether a given date is before another date on the calendar.
170
    * @method before
171
    * @param {Date} date  The Date object to compare with the compare argument
172
    * @param {Date} compareTo The Date object to use for the comparison
173
    * @return {Boolean} true if the date occurs before the compared date; false if not.
174
    */
175
    before : function(date, compareTo) {
176
        var ms = compareTo.getTime();
177
        if (date.getTime() < ms) {
178
            return true;
179
        } else {
180
            return false;
181
        }
182
    },
183
 
184
    /**
185
    * Determines whether a given date is after another date on the calendar.
186
    * @method after
187
    * @param {Date} date  The Date object to compare with the compare argument
188
    * @param {Date} compareTo The Date object to use for the comparison
189
    * @return {Boolean} true if the date occurs after the compared date; false if not.
190
    */
191
    after : function(date, compareTo) {
192
        var ms = compareTo.getTime();
193
        if (date.getTime() > ms) {
194
            return true;
195
        } else {
196
            return false;
197
        }
198
    },
199
 
200
    /**
201
    * Determines whether a given date is between two other dates on the calendar.
202
    * @method between
203
    * @param {Date} date  The date to check for
204
    * @param {Date} dateBegin The start of the range
205
    * @param {Date} dateEnd  The end of the range
206
    * @return {Boolean} true if the date occurs between the compared dates; false if not.
207
    */
208
    between : function(date, dateBegin, dateEnd) {
209
        if (this.after(date, dateBegin) && this.before(date, dateEnd)) {
210
            return true;
211
        } else {
212
            return false;
213
        }
214
    },
215
 
216
    /**
217
    * Retrieves a JavaScript Date object representing January 1 of any given year.
218
    * @method getJan1
219
    * @param {Number} calendarYear  The calendar year for which to retrieve January 1
220
    * @return {Date} January 1 of the calendar year specified.
221
    */
222
    getJan1 : function(calendarYear) {
223
        return this.getDate(calendarYear,0,1);
224
    },
225
 
226
    /**
227
    * Calculates the number of days the specified date is from January 1 of the specified calendar year.
228
    * Passing January 1 to this function would return an offset value of zero.
229
    * @method getDayOffset
230
    * @param {Date} date The JavaScript date for which to find the offset
231
    * @param {Number} calendarYear The calendar year to use for determining the offset
232
    * @return {Number} The number of days since January 1 of the given year
233
    */
234
    getDayOffset : function(date, calendarYear) {
235
        var beginYear = this.getJan1(calendarYear); // Find the start of the year. This will be in week 1.
236
 
237
        // Find the number of days the passed in date is away from the calendar year start
238
        var dayOffset = Math.ceil((date.getTime()-beginYear.getTime()) / this.ONE_DAY_MS);
239
        return dayOffset;
240
    },
241
 
242
    /**
243
    * Calculates the week number for the given date. Can currently support standard
244
    * U.S. week numbers, based on Jan 1st defining the 1st week of the year, and
245
    * ISO8601 week numbers, based on Jan 4th defining the 1st week of the year.
246
    *
247
    * @method getWeekNumber
248
    * @param {Date} date The JavaScript date for which to find the week number
249
    * @param {Number} firstDayOfWeek The index of the first day of the week (0 = Sun, 1 = Mon ... 6 = Sat).
250
    * Defaults to 0
251
    * @param {Number} janDate The date in the first week of January which defines week one for the year
252
    * Defaults to the value of YAHOO.widget.DateMath.WEEK_ONE_JAN_DATE, which is 1 (Jan 1st).
253
    * For the U.S, this is normally Jan 1st. ISO8601 uses Jan 4th to define the first week of the year.
254
    *
255
    * @return {Number} The number of the week containing the given date.
256
    */
257
    getWeekNumber : function(date, firstDayOfWeek, janDate) {
258
 
259
        // Setup Defaults
260
        firstDayOfWeek = firstDayOfWeek || 0;
261
        janDate = janDate || this.WEEK_ONE_JAN_DATE;
262
 
263
        var targetDate = this.clearTime(date),
264
            startOfWeek,
265
            endOfWeek;
266
 
267
        if (targetDate.getDay() === firstDayOfWeek) {
268
            startOfWeek = targetDate;
269
        } else {
270
            startOfWeek = this.getFirstDayOfWeek(targetDate, firstDayOfWeek);
271
        }
272
 
273
        var startYear = startOfWeek.getFullYear();
274
 
275
        // DST shouldn't be a problem here, math is quicker than setDate();
276
        endOfWeek = new Date(startOfWeek.getTime() + 6*this.ONE_DAY_MS);
277
 
278
        var weekNum;
279
        if (startYear !== endOfWeek.getFullYear() && endOfWeek.getDate() >= janDate) {
280
            // If years don't match, endOfWeek is in Jan. and if the
281
            // week has WEEK_ONE_JAN_DATE in it, it's week one by definition.
282
            weekNum = 1;
283
        } else {
284
            // Get the 1st day of the 1st week, and
285
            // find how many days away we are from it.
286
            var weekOne = this.clearTime(this.getDate(startYear, 0, janDate)),
287
                weekOneDayOne = this.getFirstDayOfWeek(weekOne, firstDayOfWeek);
288
 
289
            // Round days to smoothen out 1 hr DST diff
290
            var daysDiff  = Math.round((targetDate.getTime() - weekOneDayOne.getTime())/this.ONE_DAY_MS);
291
 
292
            // Calc. Full Weeks
293
            var rem = daysDiff % 7;
294
            var weeksDiff = (daysDiff - rem)/7;
295
            weekNum = weeksDiff + 1;
296
        }
297
        return weekNum;
298
    },
299
 
300
    /**
301
     * Get the first day of the week, for the give date.
302
     * @param {Date} dt The date in the week for which the first day is required.
303
     * @param {Number} startOfWeek The index for the first day of the week, 0 = Sun, 1 = Mon ... 6 = Sat (defaults to 0)
304
     * @return {Date} The first day of the week
305
     */
306
    getFirstDayOfWeek : function (dt, startOfWeek) {
307
        startOfWeek = startOfWeek || 0;
308
        var dayOfWeekIndex = dt.getDay(),
309
            dayOfWeek = (dayOfWeekIndex - startOfWeek + 7) % 7;
310
 
311
        return this.subtract(dt, this.DAY, dayOfWeek);
312
    },
313
 
314
    /**
315
    * Determines if a given week overlaps two different years.
316
    * @method isYearOverlapWeek
317
    * @param {Date} weekBeginDate The JavaScript Date representing the first day of the week.
318
    * @return {Boolean} true if the date overlaps two different years.
319
    */
320
    isYearOverlapWeek : function(weekBeginDate) {
321
        var overlaps = false;
322
        var nextWeek = this.add(weekBeginDate, this.DAY, 6);
323
        if (nextWeek.getFullYear() != weekBeginDate.getFullYear()) {
324
            overlaps = true;
325
        }
326
        return overlaps;
327
    },
328
 
329
    /**
330
    * Determines if a given week overlaps two different months.
331
    * @method isMonthOverlapWeek
332
    * @param {Date} weekBeginDate The JavaScript Date representing the first day of the week.
333
    * @return {Boolean} true if the date overlaps two different months.
334
    */
335
    isMonthOverlapWeek : function(weekBeginDate) {
336
        var overlaps = false;
337
        var nextWeek = this.add(weekBeginDate, this.DAY, 6);
338
        if (nextWeek.getMonth() != weekBeginDate.getMonth()) {
339
            overlaps = true;
340
        }
341
        return overlaps;
342
    },
343
 
344
    /**
345
    * Gets the first day of a month containing a given date.
346
    * @method findMonthStart
347
    * @param {Date} date The JavaScript Date used to calculate the month start
348
    * @return {Date}  The JavaScript Date representing the first day of the month
349
    */
350
    findMonthStart : function(date) {
351
        var start = this.getDate(date.getFullYear(), date.getMonth(), 1);
352
        return start;
353
    },
354
 
355
    /**
356
    * Gets the last day of a month containing a given date.
357
    * @method findMonthEnd
358
    * @param {Date} date The JavaScript Date used to calculate the month end
359
    * @return {Date}  The JavaScript Date representing the last day of the month
360
    */
361
    findMonthEnd : function(date) {
362
        var start = this.findMonthStart(date);
363
        var nextMonth = this.add(start, this.MONTH, 1);
364
        var end = this.subtract(nextMonth, this.DAY, 1);
365
        return end;
366
    },
367
 
368
    /**
369
    * Clears the time fields from a given date, effectively setting the time to 12 noon.
370
    * @method clearTime
371
    * @param {Date} date The JavaScript Date for which the time fields will be cleared
372
    * @return {Date}  The JavaScript Date cleared of all time fields
373
    */
374
    clearTime : function(date) {
375
        date.setHours(12,0,0,0);
376
        return date;
377
    },
378
 
379
    /**
380
     * Returns a new JavaScript Date object, representing the given year, month and date. Time fields (hr, min, sec, ms) on the new Date object
381
     * are set to 0. The method allows Date instances to be created with the a year less than 100. "new Date(year, month, date)" implementations
382
     * set the year to 19xx if a year (xx) which is less than 100 is provided.
383
     * <p>
384
     * <em>NOTE:</em>Validation on argument values is not performed. It is the caller's responsibility to ensure
385
     * arguments are valid as per the ECMAScript-262 Date object specification for the new Date(year, month[, date]) constructor.
386
     * </p>
387
     * @method getDate
388
     * @param {Number} y Year.
389
     * @param {Number} m Month index from 0 (Jan) to 11 (Dec).
390
     * @param {Number} d (optional) Date from 1 to 31. If not provided, defaults to 1.
391
     * @return {Date} The JavaScript date object with year, month, date set as provided.
392
     */
393
    getDate : function(y, m, d) {
394
        var dt = null;
395
        if (YAHOO.lang.isUndefined(d)) {
396
            d = 1;
397
        }
398
        if (y >= 100) {
399
            dt = new Date(y, m, d);
400
        } else {
401
            dt = new Date();
402
            dt.setFullYear(y);
403
            dt.setMonth(m);
404
            dt.setDate(d);
405
            dt.setHours(0,0,0,0);
406
        }
407
        return dt;
408
    }
409
};
410
YAHOO.register("datemath", YAHOO.widget.DateMath, {version: "2.9.0", build: "2800"});
411
 
412
}, '2.9.0' ,{"requires": ["yui2-yahoo"]});