/**
* YAHOO.widget.DateMath is used for simple date manipulation. The class is a static utility
* used for adding, subtracting, and comparing dates.
* @namespace YAHOO.widget
* @class DateMath
*/
YAHOO.widget.DateMath = {
/**
* Constant field representing Day
* @property DAY
* @static
* @final
* @type String
*/
DAY : "D",
/**
* Constant field representing Week
* @property WEEK
* @static
* @final
* @type String
*/
WEEK : "W",
/**
* Constant field representing Year
* @property YEAR
* @static
* @final
* @type String
*/
YEAR : "Y",
/**
* Constant field representing Month
* @property MONTH
* @static
* @final
* @type String
*/
MONTH : "M",
/**
* Constant field representing one day, in milliseconds
* @property ONE_DAY_MS
* @static
* @final
* @type Number
*/
ONE_DAY_MS : 1000*60*60*24,
/**
* Adds the specified amount of time to the this instance.
* @method add
* @param {Date} date The JavaScript Date object to perform addition on
* @param {String} field The field constant to be used for performing addition.
* @param {Number} amount The number of units (measured in the field constant) to add to the date.
* @return {Date} The resulting Date object
*/
add : function(date, field, amount) {
var d = new Date(date.getTime());
switch (field) {
case this.MONTH:
var newMonth = date.getMonth() + amount;
var years = 0;
if (newMonth < 0) {
while (newMonth < 0) {
newMonth += 12;
years -= 1;
}
} else if (newMonth > 11) {
while (newMonth > 11) {
newMonth -= 12;
years += 1;
}
}
d.setMonth(newMonth);
d.setFullYear(date.getFullYear() + years);
break;
case this.DAY:
d.setDate(date.getDate() + amount);
break;
case this.YEAR:
d.setFullYear(date.getFullYear() + amount);
break;
case this.WEEK:
d.setDate(date.getDate() + (amount * 7));
break;
}
return d;
},
/**
* Subtracts the specified amount of time from the this instance.
* @method subtract
* @param {Date} date The JavaScript Date object to perform subtraction on
* @param {Number} field The this field constant to be used for performing subtraction.
* @param {Number} amount The number of units (measured in the field constant) to subtract from the date.
* @return {Date} The resulting Date object
*/
subtract : function(date, field, amount) {
return this.add(date, field, (amount*-1));
},
/**
* Determines whether a given date is before another date on the calendar.
* @method before
* @param {Date} date The Date object to compare with the compare argument
* @param {Date} compareTo The Date object to use for the comparison
* @return {Boolean} true if the date occurs before the compared date; false if not.
*/
before : function(date, compareTo) {
var ms = compareTo.getTime();
if (date.getTime() < ms) {
return true;
} else {
return false;
}
},
/**
* Determines whether a given date is after another date on the calendar.
* @method after
* @param {Date} date The Date object to compare with the compare argument
* @param {Date} compareTo The Date object to use for the comparison
* @return {Boolean} true if the date occurs after the compared date; false if not.
*/
after : function(date, compareTo) {
var ms = compareTo.getTime();
if (date.getTime() > ms) {
return true;
} else {
return false;
}
},
/**
* Determines whether a given date is between two other dates on the calendar.
* @method between
* @param {Date} date The date to check for
* @param {Date} dateBegin The start of the range
* @param {Date} dateEnd The end of the range
* @return {Boolean} true if the date occurs between the compared dates; false if not.
*/
between : function(date, dateBegin, dateEnd) {
if (this.after(date, dateBegin) && this.before(date, dateEnd)) {
return true;
} else {
return false;
}
},
/**
* Retrieves a JavaScript Date object representing January 1 of any given year.
* @method getJan1
* @param {Number} calendarYear The calendar year for which to retrieve January 1
* @return {Date} January 1 of the calendar year specified.
*/
getJan1 : function(calendarYear) {
return new Date(calendarYear,0,1);
},
/**
* Calculates the number of days the specified date is from January 1 of the specified calendar year.
* Passing January 1 to this function would return an offset value of zero.
* @method getDayOffset
* @param {Date} date The JavaScript date for which to find the offset
* @param {Number} calendarYear The calendar year to use for determining the offset
* @return {Number} The number of days since January 1 of the given year
*/
getDayOffset : function(date, calendarYear) {
var beginYear = this.getJan1(calendarYear); // Find the start of the year. This will be in week 1.
// Find the number of days the passed in date is away from the calendar year start
var dayOffset = Math.ceil((date.getTime()-beginYear.getTime()) / this.ONE_DAY_MS);
return dayOffset;
},
/**
* Calculates the week number for the given date. This function assumes that week 1 is the
* week in which January 1 appears, regardless of whether the week consists of a full 7 days.
* The calendar year can be specified to help find what a the week number would be for a given
* date if the date overlaps years. For instance, a week may be considered week 1 of 2005, or
* week 53 of 2004. Specifying the optional calendarYear allows one to make this distinction
* easily.
* @method getWeekNumber
* @param {Date} date The JavaScript date for which to find the week number
* @param {Number} calendarYear OPTIONAL - The calendar year to use for determining the week number. Default is
* the calendar year of parameter "date".
* @param {Number} weekStartsOn OPTIONAL - The integer (0-6) representing which day a week begins on. Default is 0 (for Sunday).
* @return {Number} The week number of the given date.
*/
getWeekNumber : function(date, calendarYear) {
date = this.clearTime(date);
var nearestThurs = new Date(date.getTime() + (4 * this.ONE_DAY_MS) - ((date.getDay()) * this.ONE_DAY_MS));
var jan1 = new Date(nearestThurs.getFullYear(),0,1);
var dayOfYear = ((nearestThurs.getTime() - jan1.getTime()) / this.ONE_DAY_MS) - 1;
var weekNum = Math.ceil((dayOfYear)/ 7);
return weekNum;
},
/**
* Determines if a given week overlaps two different years.
* @method isYearOverlapWeek
* @param {Date} weekBeginDate The JavaScript Date representing the first day of the week.
* @return {Boolean} true if the date overlaps two different years.
*/
isYearOverlapWeek : function(weekBeginDate) {
var overlaps = false;
var nextWeek = this.add(weekBeginDate, this.DAY, 6);
if (nextWeek.getFullYear() != weekBeginDate.getFullYear()) {
overlaps = true;
}
return overlaps;
},
/**
* Determines if a given week overlaps two different months.
* @method isMonthOverlapWeek
* @param {Date} weekBeginDate The JavaScript Date representing the first day of the week.
* @return {Boolean} true if the date overlaps two different months.
*/
isMonthOverlapWeek : function(weekBeginDate) {
var overlaps = false;
var nextWeek = this.add(weekBeginDate, this.DAY, 6);
if (nextWeek.getMonth() != weekBeginDate.getMonth()) {
overlaps = true;
}
return overlaps;
},
/**
* Gets the first day of a month containing a given date.
* @method findMonthStart
* @param {Date} date The JavaScript Date used to calculate the month start
* @return {Date} The JavaScript Date representing the first day of the month
*/
findMonthStart : function(date) {
var start = new Date(date.getFullYear(), date.getMonth(), 1);
return start;
},
/**
* Gets the last day of a month containing a given date.
* @method findMonthEnd
* @param {Date} date The JavaScript Date used to calculate the month end
* @return {Date} The JavaScript Date representing the last day of the month
*/
findMonthEnd : function(date) {
var start = this.findMonthStart(date);
var nextMonth = this.add(start, this.MONTH, 1);
var end = this.subtract(nextMonth, this.DAY, 1);
return end;
},
/**
* Clears the time fields from a given date, effectively setting the time to 12 noon.
* @method clearTime
* @param {Date} date The JavaScript Date for which the time fields will be cleared
* @return {Date} The JavaScript Date cleared of all time fields
*/
clearTime : function(date) {
date.setHours(12,0,0,0);
return date;
}
};