/*jshint indent:2, curly:true, eqeqeq:true, immed:true, latedef:true,
newcap:true, noarg:true, regexp:true, undef:true, strict:true, trailing:true,
white:true*/
/*global XT:true, _:true, console:true */
(function () {
"use strict";
/**
An object for performing operations on dates.
*/
XT.date = {
/**
@param {Date} date
@param {Boolean} isForward
returns {Date} The new date
*/
applyTimezoneOffset: function (date, isForward) {
var direction = isForward ? 1 : -1;
return new Date(date.valueOf() + direction * 60000 * date.getTimezoneOffset());
},
/**
Converts the date in d to a date-object. The input can be:
a date object: returned without modification
an array : Interpreted as [year,month,day]. NOTE: month is 0-11.
a number : Interpreted as number of milliseconds
since 1 Jan 1970 (a timestamp)
a string : Any format supported by the javascript engine, like
"YYYY/MM/DD", "MM/DD/YYYY", "Jan 31 2009" etc.
an object : Interpreted as an object with year, month and date
attributes. **NOTE** month is 0-11.
@param {Any}
@returns {Date}
*/
convert: function (d) {
return (
d.constructor === Date ? d :
d.constructor === Array ? new Date(d[0], d[1], d[2]) :
d.constructor === Number ? new Date(d) :
d.constructor === String ? new Date(d) :
typeof d === "object" ? new Date(d.year, d.month, d.date) :
NaN
);
},
/**
Compare two dates (could be of any type supported by the convert
function above) and returns:
-1 : if a < b
0 : if a = b
1 : if a > b
NaN : if a or b is an illegal date
NOTE: The code inside isFinite does an assignment (=).
@param {Date} Date a
@param {Date} Date b
@returns {Number}
*/
compare: function (a, b) {
return (
isFinite(a = this.convert(a).valueOf()) &&
isFinite(b = this.convert(b).valueOf()) ?
(a > b) - (a < b) :
NaN
);
},
/**
Compare two dates on date part (could be of any type supported by the
convert function above) and returns:
-1 : if a < b
0 : if a = b
1 : if a > b
NaN : if a or b is an illegal date
NOTE: The code inside isFinite does an assignment (=).
@param {Any} Date a
@param {Any} Date b
@returns {Number}
*/
compareDate: function (a, b) {
if (!a || !b) {
return NaN;
}
var x = new Date(a.valueOf()),
y = new Date(b.valueOf());
x.setHours(0, 0, 0, 0);
y.setHours(0, 0, 0, 0);
return this.compare(x, y);
},
/**
Return the difference between two dates in days.
@param {Date} Start date
@param {Date} End date
@returns {Number}
*/
daysBetween: function (start, end) {
var day = 1000 * 60 * 60 * 24,
delta = start.getTime() - end.getTime();
return Math.round(delta / day);
},
/**
Checks if date in d is between dates in start and end.
Returns a boolean or NaN:
true : if d is between start and end (inclusive)
false : if d is before start or after end
NaN : if one or more of the dates is illegal.
NOTE: The code inside isFinite does an assignment (=).
@param {Date} Reference
@param {Date} Start
@param {Date} End
*/
inRange: function (d, start, end) {
return (
isFinite(d = this.convert(d).valueOf()) &&
isFinite(start = this.convert(start).valueOf()) &&
isFinite(end = this.convert(end).valueOf()) ?
start <= d && d <= end :
NaN
);
},
/**
Returns date passed at midnight.
@params {Date} Date
@returns {Date}
*/
toMidnight: function (d) {
d.setHours(0);
d.setMinutes(0);
d.setSeconds(0);
d.setMilliseconds(0);
return d;
},
/**
Returns today's date at midnight.
returns {Date}
*/
today: function () {
var today = new Date();
return this.toMidnight(today);
},
/**
Returns a date object with a time of 2100-01-01T00:00:00.000Z.
@returns {Date}
*/
endOfTime: function () {
return new Date("2100-01-01T00:00:00.000Z");
},
/**
Returns a date object with a time of 1970-01-01T00:00:00.000Z.
@returns {Date}
*/
startOfTime: function () {
return new Date("1970-01-01T00:00:00.000Z");
},
/**
Evaluates whether the passed date is equal to the date returned by `endOfTime`.
@seealso endOfTime
@param {Date}
@returns {Boolean}
*/
isEndOfTime: function (d) {
return d instanceof Date ? this.compare(this.endOfTime(), d) === 0 : false;
},
/**
Evaluates whether the passed date is equal to the date returned by `startOfTime`.
@seealso startOfTime
@param {Date}
@returns {Boolean}
*/
isStartOfTime: function (d) {
return d instanceof Date ? this.compare(this.startOfTime(), d) === 0 : false;
}
};
}());