(function () {
var $D = Date,
$P = $D.prototype,
p = function (s, l) {
if (!l) {
l = 2;
}
return ("000" + s).slice(l * -1);
};
if (typeof window !== "undefined" && typeof window.console !== "undefined" && typeof window.console.log !== "undefined") {
$D.console = console; // used only to raise non-critical errors if available
} else {
// set mock so we don't give errors.
$D.console = {
log: function(){},
error: function(){}
};
}
$D.Config = $D.Config || {};
$D.initOverloads = function() {
/**
* Overload of Date.now. Allows an alternate call for Date.now where it returns the
* current Date as an object rather than just milliseconds since the Unix Epoch.
*
* Also provides an implementation of now() for browsers (IE<9) that don't have it.
*
* Backwards compatible so with work with either:
* Date.now() [returns ms]
* or
* Date.now(true) [returns Date]
*/
if (!$D.now) {
$D._now = function now() {
return new Date().getTime();
};
} else if (!$D._now) {
$D._now = $D.now;
}
$D.now = function (returnObj) {
if (returnObj) {
return $D.present();
} else {
return $D._now();
}
};
if ( !$P.toISOString ) {
$P.toISOString = function() {
return this.getUTCFullYear() +
"-" + p(this.getUTCMonth() + 1) +
"-" + p(this.getUTCDate()) +
"T" + p(this.getUTCHours()) +
":" + p(this.getUTCMinutes()) +
":" + p(this.getUTCSeconds()) +
"." + String( (this.getUTCMilliseconds()/1000).toFixed(3)).slice(2, 5) +
"Z";
};
}
// private
if ( $P._toString === undefined ){
$P._toString = $P.toString;
}
};
$D.initOverloads();
/**
* Gets a date that is set to the current date. The time is set to the start of the day (00:00 or 12:00 AM).
* @return {Date} The current date.
*/
$D.today = function () {
return new Date().clearTime();
};
/**
* Gets a date that is set to the current date and time (same as new Date, but chainable)
* @return {Date} The current date.
*/
$D.present = function () {
return new Date();
};
/**
* Compares the first date to the second date and returns an number indication of their relative values.
* @param {Date} First Date object to compare [Required].
* @param {Date} Second Date object to compare to [Required].
* @return {Number} -1 = date1 is lessthan date2. 0 = values are equal. 1 = date1 is greaterthan date2.
*/
$D.compare = function (date1, date2) {
if (isNaN(date1) || isNaN(date2)) {
throw new Error(date1 + " - " + date2);
} else if (date1 instanceof Date && date2 instanceof Date) {
return (date1 < date2) ? -1 : (date1 > date2) ? 1 : 0;
} else {
throw new TypeError(date1 + " - " + date2);
}
};
/**
* Compares the first Date object to the second Date object and returns true if they are equal.
* @param {Date} First Date object to compare [Required]
* @param {Date} Second Date object to compare to [Required]
* @return {Boolean} true if dates are equal. false if they are not equal.
*/
$D.equals = function (date1, date2) {
return (date1.compareTo(date2) === 0);
};
/**
* Gets the language appropriate day name when given the day number(0-6)
* eg - 0 == Sunday
* @return {String} The day name
*/
$D.getDayName = function (n) {
return Date.CultureInfo.dayNames[n];
};
/**
* Gets the day number (0-6) if given a CultureInfo specific string which is a valid dayName, abbreviatedDayName or shortestDayName (two char).
* @param {String} The name of the day (eg. "Monday, "Mon", "tuesday", "tue", "We", "we").
* @return {Number} The day number
*/
$D.getDayNumberFromName = function (name) {
var n = Date.CultureInfo.dayNames, m = Date.CultureInfo.abbreviatedDayNames, o = Date.CultureInfo.shortestDayNames, s = name.toLowerCase();
for (var i = 0; i < n.length; i++) {
if (n[i].toLowerCase() === s || m[i].toLowerCase() === s || o[i].toLowerCase() === s) {
return i;
}
}
return -1;
};
/**
* Gets the month number (0-11) if given a Culture Info specific string which is a valid monthName or abbreviatedMonthName.
* @param {String} The name of the month (eg. "February, "Feb", "october", "oct").
* @return {Number} The day number
*/
$D.getMonthNumberFromName = function (name) {
var n = Date.CultureInfo.monthNames, m = Date.CultureInfo.abbreviatedMonthNames, s = name.toLowerCase();
for (var i = 0; i < n.length; i++) {
if (n[i].toLowerCase() === s || m[i].toLowerCase() === s) {
return i;
}
}
return -1;
};
/**
* Gets the language appropriate month name when given the month number(0-11)
* eg - 0 == January
* @return {String} The month name
*/
$D.getMonthName = function (n) {
return Date.CultureInfo.monthNames[n];
};
/**
* Determines if the current date instance is within a LeapYear.
* @param {Number} The year.
* @return {Boolean} true if date is within a LeapYear, otherwise false.
*/
$D.isLeapYear = function (year) {
return ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0);
};
/**
* Gets the number of days in the month, given a year and month value. Automatically corrects for LeapYear.
* @param {Number} The year.
* @param {Number} The month (0-11).
* @return {Number} The number of days in the month.
*/
$D.getDaysInMonth = function (year, month) {
if (!month && $D.validateMonth(year)) {
month = year;
year = Date.today().getFullYear();
}
return [31, ($D.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
};
$P.getDaysInMonth = function () {
return $D.getDaysInMonth(this.getFullYear(), this.getMonth());
};
$D.getTimezoneAbbreviation = function (offset, dst) {
var p, n = (dst || false) ? Date.CultureInfo.abbreviatedTimeZoneDST : Date.CultureInfo.abbreviatedTimeZoneStandard;
for (p in n) {
if (n.hasOwnProperty(p)) {
if (n[p] === offset) {
return p;
}
}
}
return null;
};
$D.getTimezoneOffset = function (name, dst) {
var i, a =[], z = Date.CultureInfo.timezones;
if (!name) { name = (new Date()).getTimezone();}
for (i = 0; i < z.length; i++) {
if (z[i].name === name.toUpperCase()) {
a.push(i);
}
}
if (!z[a[0]]) {
return null;
}
if (a.length === 1 || !dst) {
return z[a[0]].offset;
} else {
for (i=0; i < a.length; i++) {
if (z[a[i]].dst) {
return z[a[i]].offset;
}
}
}
};
$D.getQuarter = function (d) {
d = d || new Date(); // If no date supplied, use today
var q = [1,2,3,4];
return q[Math.floor(d.getMonth() / 3)]; // ~~~ is a bitwise op. Faster than Math.floor
};
$D.getDaysLeftInQuarter = function (d) {
d = d || new Date();
var qEnd = new Date(d);
qEnd.setMonth(qEnd.getMonth() + 3 - qEnd.getMonth() % 3, 0);
return Math.floor((qEnd - d) / 8.64e7);
};
// private
var validate = function (n, min, max, name) {
name = name ? name : "Object";
if (typeof n === "undefined") {
return false;
} else if (typeof n !== "number") {
throw new TypeError(n + " is not a Number.");
} else if (n < min || n > max) {
// As failing validation is *not* an exceptional circumstance
// lets not throw a RangeError Exception here.
// It's semantically correct but it's not sensible.
return false;
}
return true;
};
/**
* Validates the number is within an acceptable range for milliseconds [0-999].
* @param {Number} The number to check if within range.
* @return {Boolean} true if within range, otherwise false.
*/
$D.validateMillisecond = function (value) {
return validate(value, 0, 999, "millisecond");
};
/**
* Validates the number is within an acceptable range for seconds [0-59].
* @param {Number} The number to check if within range.
* @return {Boolean} true if within range, otherwise false.
*/
$D.validateSecond = function (value) {
return validate(value, 0, 59, "second");
};
/**
* Validates the number is within an acceptable range for minutes [0-59].
* @param {Number} The number to check if within range.
* @return {Boolean} true if within range, otherwise false.
*/
$D.validateMinute = function (value) {
return validate(value, 0, 59, "minute");
};
/**
* Validates the number is within an acceptable range for hours [0-23].
* @param {Number} The number to check if within range.
* @return {Boolean} true if within range, otherwise false.
*/
$D.validateHour = function (value) {
return validate(value, 0, 23, "hour");
};
/**
* Validates the number is within an acceptable range for the days in a month [0-MaxDaysInMonth].
* @param {Number} The number to check if within range.
* @return {Boolean} true if within range, otherwise false.
*/
$D.validateDay = function (value, year, month) {
if (year === undefined || year === null || month === undefined || month === null) { return false;}
return validate(value, 1, $D.getDaysInMonth(year, month), "day");
};
/**
* Validates the number is within an acceptable range for months [0-11].
* @param {Number} The number to check if within range.
* @return {Boolean} true if within range, otherwise false.
*/
$D.validateWeek = function (value) {
return validate(value, 0, 53, "week");
};
/**
* Validates the number is within an acceptable range for months [0-11].
* @param {Number} The number to check if within range.
* @return {Boolean} true if within range, otherwise false.
*/
$D.validateMonth = function (value) {
return validate(value, 0, 11, "month");
};
/**
* Validates the number is within an acceptable range for years.
* @param {Number} The number to check if within range.
* @return {Boolean} true if within range, otherwise false.
*/
$D.validateYear = function (value) {
/**
* Per ECMAScript spec the range of times supported by Date objects is
* exactly -100,000,000 days to +100,000,000 days measured relative to
* midnight at the beginning of 01 January, 1970 UTC.
* This gives a range of 8,640,000,000,000,000 milliseconds to either
* side of 01 January, 1970 UTC.
*
* Earliest possible date: Tue, 20 Apr 271,822 B.C. 00:00:00 UTC
* Latest possible date: Sat, 13 Sep 275,760 00:00:00 UTC
*/
return validate(value, -271822, 275760, "year");
};
$D.validateTimezone = function(value) {
var timezones = {"ACDT":1,"ACST":1,"ACT":1,"ADT":1,"AEDT":1,"AEST":1,"AFT":1,"AKDT":1,"AKST":1,"AMST":1,"AMT":1,"ART":1,"AST":1,"AWDT":1,"AWST":1,"AZOST":1,"AZT":1,"BDT":1,"BIOT":1,"BIT":1,"BOT":1,"BRT":1,"BST":1,"BTT":1,"CAT":1,"CCT":1,"CDT":1,"CEDT":1,"CEST":1,"CET":1,"CHADT":1,"CHAST":1,"CHOT":1,"ChST":1,"CHUT":1,"CIST":1,"CIT":1,"CKT":1,"CLST":1,"CLT":1,"COST":1,"COT":1,"CST":1,"CT":1,"CVT":1,"CWST":1,"CXT":1,"DAVT":1,"DDUT":1,"DFT":1,"EASST":1,"EAST":1,"EAT":1,"ECT":1,"EDT":1,"EEDT":1,"EEST":1,"EET":1,"EGST":1,"EGT":1,"EIT":1,"EST":1,"FET":1,"FJT":1,"FKST":1,"FKT":1,"FNT":1,"GALT":1,"GAMT":1,"GET":1,"GFT":1,"GILT":1,"GIT":1,"GMT":1,"GST":1,"GYT":1,"HADT":1,"HAEC":1,"HAST":1,"HKT":1,"HMT":1,"HOVT":1,"HST":1,"ICT":1,"IDT":1,"IOT":1,"IRDT":1,"IRKT":1,"IRST":1,"IST":1,"JST":1,"KGT":1,"KOST":1,"KRAT":1,"KST":1,"LHST":1,"LINT":1,"MAGT":1,"MART":1,"MAWT":1,"MDT":1,"MET":1,"MEST":1,"MHT":1,"MIST":1,"MIT":1,"MMT":1,"MSK":1,"MST":1,"MUT":1,"MVT":1,"MYT":1,"NCT":1,"NDT":1,"NFT":1,"NPT":1,"NST":1,"NT":1,"NUT":1,"NZDT":1,"NZST":1,"OMST":1,"ORAT":1,"PDT":1,"PET":1,"PETT":1,"PGT":1,"PHOT":1,"PHT":1,"PKT":1,"PMDT":1,"PMST":1,"PONT":1,"PST":1,"PYST":1,"PYT":1,"RET":1,"ROTT":1,"SAKT":1,"SAMT":1,"SAST":1,"SBT":1,"SCT":1,"SGT":1,"SLST":1,"SRT":1,"SST":1,"SYOT":1,"TAHT":1,"THA":1,"TFT":1,"TJT":1,"TKT":1,"TLT":1,"TMT":1,"TOT":1,"TVT":1,"UCT":1,"ULAT":1,"UTC":1,"UYST":1,"UYT":1,"UZT":1,"VET":1,"VLAT":1,"VOLT":1,"VOST":1,"VUT":1,"WAKT":1,"WAST":1,"WAT":1,"WEDT":1,"WEST":1,"WET":1,"WST":1,"YAKT":1,"YEKT":1,"Z":1};
return (timezones[value] === 1);
};
$D.validateTimezoneOffset= function(value) {
// timezones go from +14hrs to -12hrs, the +X hours are negative offsets.
return (value > -841 && value < 721);
};
}());
|