Skip to content

Instantly share code, notes, and snippets.

@JerrySievert
Created March 29, 2016 21:21
Show Gist options
  • Save JerrySievert/26c64ef68c71ab85ff9932532c5d7dae to your computer and use it in GitHub Desktop.
Save JerrySievert/26c64ef68c71ab85ff9932532c5d7dae to your computer and use it in GitHub Desktop.
hacked cromag
/*
© 2012 by Jerry Sievert
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// constants
var monthsAbbr = [
'Jan',
'Feb',
'Mar',
'Apr',
'May',
'Jun',
'Jul',
'Aug',
'Sep',
'Oct',
'Nov',
'Dec'
];
var monthsFull = [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December'
];
var daysAbbr = [
'Sun',
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat'
];
var daysFull = [
'Sunday',
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday'
];
var dayNames = {
'su': 0,
'sun': 0,
'sunday': 0,
'mo': 1,
'mon': 1,
'monday': 1,
'tu': 2,
'tue': 2,
'tuesday': 2,
'we': 3,
'wed': 3,
'wednesday': 3,
'th': 4,
'thu': 4,
'thursday': 4,
'fr': 5,
'fri': 5,
'friday': 5,
'sa': 6,
'sat': 6,
'saturday': 6
};
var monthsAll = monthsFull.concat(monthsAbbr);
var daysAll = [
'su',
'sun',
'sunday',
'mo',
'mon',
'monday',
'tu',
'tue',
'tuesday',
'we',
'wed',
'wednesday',
'th',
'thu',
'thursday',
'fr',
'fri',
'friday',
'sa',
'sat',
'saturday'
];
var monthNames = {
'jan': 0,
'january': 0,
'feb': 1,
'february': 1,
'mar': 2,
'march': 2,
'apr': 3,
'april': 3,
'may': 4,
'jun': 5,
'june': 5,
'jul': 6,
'july': 6,
'aug': 7,
'august': 7,
'sep': 8,
'september': 8,
'oct': 9,
'october': 9,
'nov': 10,
'november': 10,
'dec': 11,
'december': 11
};
var daysInMonth = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ];
// private helper functions
/** @ignore */
function pad(str, length) {
str = String(str);
while (str.length < length) {
str = '0' + str;
}
return str;
}
var isInteger = function (str) {
if (str.match(/^(\d+)$/)) {
return true;
}
return false;
};
var getInt = function (str, i, minlength, maxlength) {
for (var x = maxlength; x >= minlength; x--) {
var token = str.substring(i, i + x);
if (token.length < minlength) {
return null;
}
if (isInteger(token)) {
return token;
}
}
return null;
};
var Cromag = function () {
var args = Array.prototype.slice.call(arguments);
// this is horrible. there has to be a better way for this, dealing
// with the Date object is painful at best due to its "special"
// constrainsts
if (args.length === 1) {
this.date = new Date(args[0]);
} else if (args.length === 3) {
this.date = new Date(args[0], args[1], args[2]);
} else if (args.length === 4) {
this.date = new Date(args[0], args[1], args[2], args[3]);
} else if (args.length === 5) {
this.date = new Date(args[0], args[1], args[2], args[3], args[4]);
} else if (args.length === 6) {
this.date = new Date(args[0], args[1], args[2], args[3], args[4], args[5]);
} else if (args.length === 7) {
this.date = new Date(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
} else {
this.date = new Date();
}
};
// static class methods
Cromag.now = Date.now;
Cromag.UTC = Date.UTC;
// ------------------------------------------------------------------
// getDateFromFormat( date_string , format_string )
//
// This function takes a date string and a format string. It matches
// If the date string matches the format string, it returns the
// getTime() of the date. If it does not match, it returns NaN.
// Original Author: Matt Kruse <[email protected]>
// WWW: http://www.mattkruse.com/
// Adapted from: http://www.mattkruse.com/javascript/date/source.html
// ------------------------------------------------------------------
var getDateFromFormat = function (val, format) {
val = val + "";
format = format + "";
var iVal = 0;
var iFormat = 0;
var c = "";
var token = "";
var token2 = "";
var x, y;
var now = new Cromag();
var year = now.getYear();
var month = now.getMonth() + 1;
var date = 1;
var hh = 0;
var mm = 0;
var ss = 0;
var ampm = "";
while (iFormat < format.length) {
// Get next token from format string
c = format.charAt(iFormat);
token = "";
while ((format.charAt(iFormat) === c) && (iFormat < format.length)) {
token += format.charAt(iFormat++);
}
// Extract contents of value based on format token
if (token === "yyyy" || token === "yy" || token === "y") {
if (token === "yyyy") {
x = 4;
y = 4;
}
if (token === "yy") {
x = 2;
y = 2;
}
if (token === "y") {
x = 2;
y = 4;
}
year = getInt(val, iVal, x, y);
if (year === null) {
return NaN;
}
iVal += year.length;
if (year.length === 2) {
if (year > 70) {
year = 1900 + (year - 0);
} else {
year = 2000 + (year - 0);
}
}
} else if (token === "MMM" || token === "NNN") {
month = 0;
for (var i = 0; i < monthsAll.length; i++) {
var monthName = monthsAll[i];
if (val.substring(iVal, iVal + monthName.length).toLowerCase() === monthName.toLowerCase()) {
if (token === "MMM" || (token === "NNN" && i > 11)) {
month = i + 1;
if (month > 12) {
month -= 12;
}
iVal += monthName.length;
break;
}
}
}
if ((month < 1) || (month > 12)) {
return NaN;
}
} else if (token === "EE" || token === "E") {
for (var n = 0; n < daysAll.length; n++) {
var dayName = daysAll[n];
if (val.substring(iVal, iVal + dayName.length).toLowerCase() === dayName.toLowerCase()) {
iVal += dayName.length;
break;
}
}
} else if (token === "MM" || token === "M") {
month = getInt(val, iVal, token.length, 2);
if (month === null || (month < 1) || (month > 12)) {
return NaN;
}
iVal += month.length;
} else if (token === "dd" || token === "d") {
date = getInt(val, iVal, token.length, 2);
if (date === null || (date < 1) || (date > 31)) {
return NaN;
}
iVal += date.length;
} else if (token === "hh" || token === "h") {
hh = getInt(val, iVal, token.length, 2);
if (hh === null || (hh < 1) || (hh > 12)) {
return NaN;
}
iVal += hh.length;
} else if (token === "HH" || token === "H") {
hh = getInt(val, iVal, token.length, 2);
if (hh === null || (hh < 0) || (hh > 23)) {
return NaN;
}
iVal += hh.length;
} else if (token === "KK" || token === "K") {
hh = getInt(val, iVal, token.length, 2);
if (hh === null || (hh < 0) || (hh > 11)) {
return NaN;
}
iVal += hh.length;
} else if (token === "kk" || token === "k") {
hh = getInt(val, iVal, token.length, 2);
if (hh === null || (hh < 1) || (hh > 24)) {
return NaN;
}
iVal += hh.length;
hh--;
} else if (token === "mm" || token === "m") {
mm = getInt(val, iVal, token.length, 2);
if (mm === null || (mm < 0) || (mm > 59)) {
return NaN;
}
iVal += mm.length;
} else if (token === "ss" || token === "s") {
ss = getInt(val, iVal, token.length, 2);
if (ss === null || (ss < 0) || (ss > 59)) {
return NaN;
}
iVal += ss.length;
} else if (token === "a") {
if (val.substring(iVal, iVal + 2).toLowerCase() === "am") {
ampm = "AM";
} else if (val.substring(iVal, iVal + 2).toLowerCase() === "pm") {
ampm = "PM";
} else {
return NaN;
}
iVal += 2;
} else {
if (val.substring(iVal, iVal + token.length) !== token) {
return NaN;
} else {
iVal += token.length;
}
}
}
// If there are any trailing characters left in the value, it doesn't match
if (iVal !== val.length) {
return NaN;
}
// Is date valid for month?
if (month === 2) {
// Check for leap year
if (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0)) { // leap year
if (date > 29) {
return NaN;
}
} else {
if (date > 28) {
return NaN;
}
}
}
if ((month === 4) || (month === 6) || (month === 9) || (month === 11)) {
if (date > 30) {
return NaN;
}
}
// Correct hours value
if (hh < 12 && ampm === "PM") {
hh = hh - 0 + 12;
} else if (hh > 11 && ampm === "AM") {
hh -= 12;
}
var newdate = new Date(year, month - 1, date, hh, mm, ss);
return newdate.getTime();
};
/** @ignore */
Cromag.parse = function (date, format) {
if (format) {
return getDateFromFormat(date, format);
}
var timestamp = Date.parse(date), minutesOffset = 0, match;
if (isNaN(timestamp) && (match = /^(\d{4}|[+\-]\d{6})-(\d{2})-(\d{2})(?:[T ](\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3,}))?)?(?:(Z)|([+\-])(\d{2})(?::?(\d{2}))?))?/.exec(date))) {
if (match[8] !== 'Z') {
minutesOffset = +match[10] * 60 + (+match[11]);
if (match[9] === '+') {
minutesOffset = 0 - minutesOffset;
}
}
timestamp = Cromag.UTC(+match[1], +match[2] - 1, +match[3], +match[4], +match[5] + minutesOffset, +match[6], +match[7].substr(0, 3));
}
return timestamp;
};
function polyfill(name, func) {
if (Cromag.prototype[name] === undefined) {
Cromag.prototype[name] = func;
}
}
/**
Returns new instance of Cromag object with the date set to today and
the time set to midnight
@returns {Cromag} Today's Date
@function
*/
Cromag.today = function () {
return new Cromag().clearTime();
};
/**
Returns new instance of Cromag object with the date set to today and
the time set to midnight in UTC
@returns {Cromag} Today's Date in UTC
@function
*/
Cromag.UTCtoday = function () {
return new Cromag().clearUTCTime();
};
/**
Returns new instance of Cromag object with the date set to tomorrow and
the time set to midnight
@returns {Cromag} Tomorrow's Date
@function
*/
Cromag.tomorrow = function () {
return Cromag.today().add({days: 1});
};
/**
Returns new instance of Cromag object with the date set to tomorrow and
the time set to midnight in UTC
@returns {Cromag} Tomorrow's Date in UTC
@function
*/
Cromag.UTCtomorrow = function () {
return Cromag.UTCtoday().add({days: 1});
};
/**
Returns new instance of Cromag object with the date set to yesterday and
the time set to midnight
@returns {Cromag} Yesterday's Date
@function
*/
Cromag.yesterday = function () {
return Cromag.today().add({days: -1});
};
/**
Returns new instance of Cromag object with the date set to yesterday and
the time set to midnight in UTC
@returns {Cromag} Yesterday's Date in UTC
@function
*/
Cromag.UTCyesterday = function () {
return Cromag.UTCtoday().add({days: -1});
};
Cromag.validateDay = function (day, year, month) {
var date = new Cromag(year, month, day);
return (date.getFullYear() === year &&
date.getMonth() === month &&
date.getDate() === day);
};
Cromag.validateYear = function (year) {
return (year >= 0 && year <= 9999);
};
Cromag.validateSecond = function (second) {
return (second >= 0 && second < 60);
};
Cromag.validateMonth = function (month) {
return (month >= 0 && month < 12);
};
Cromag.validateMinute = function (minute) {
return (minute >= 0 && minute < 60);
};
Cromag.validateMillisecond = function (milli) {
return (milli >= 0 && milli < 1000);
};
Cromag.validateHour = function (hour) {
return (hour >= 0 && hour < 24);
};
Cromag.compare = function (date1, date2) {
if (date1.valueOf() < date2.valueOf()) {
return -1;
} else if (date1.valueOf() > date2.valueOf()) {
return 1;
}
return 0;
};
Cromag.equals = function (date1, date2) {
return date1.valueOf() === date2.valueOf();
};
Cromag.getDayNumberFromName = function (name) {
return dayNames[name.toLowerCase()];
};
Cromag.getMonthNumberFromName = function (name) {
return monthNames[name.toLowerCase()];
};
Cromag.isLeapYear = function (year) {
return (new Cromag(year, 1, 29).getDate() === 29);
};
Cromag.getDaysInMonth = function (year, month) {
if (month === 1) {
return Cromag.isLeapYear(year) ? 29 : 28;
}
return daysInMonth[month];
};
function shadow(name) {
Cromag.prototype[name] = function () {
return this.date[name]();
};
}
function shadow1(name) {
Cromag.prototype[name] = function (arg) {
this.date[name](arg);
return this;
};
}
shadow('getDate');
shadow('getDay');
shadow('getFullYear');
shadow('getYear');
shadow('getMilliseconds');
shadow('getHours');
shadow('getMinutes');
shadow('getMonth');
shadow('getSeconds');
shadow('getTime');
shadow('getTimezoneOffset');
shadow('getUTCDate');
shadow('getUTCDay');
shadow('getUTCFullYear');
shadow('getUTCHours');
shadow('getUTCMilliseconds');
shadow('getUTCMinutes');
shadow('getUTCMonth');
shadow('getUTCSeconds');
shadow1('setDate');
shadow1('setFullYear');
shadow1('setHours');
shadow1('setMilliseconds');
shadow1('setMinutes');
shadow1('setMonth');
shadow1('setSeconds');
shadow1('setTime');
shadow1('setUTCDate');
shadow1('setUTCFullYear');
shadow1('setUTCHours');
shadow1('setUTCMilliseconds');
shadow1('setUTCMinutes');
shadow1('setUTCMonth');
shadow1('setUTCSeconds');
shadow('toDateString');
shadow('toISOString');
shadow('toJSON');
shadow('toLocaleDateString');
shadow('toLocaleTimeString');
shadow('toString');
shadow('toTimeString');
shadow('toUTCString');
shadow('valueOf');
polyfill('getMonthAbbr', function () {
return monthsAbbr[this.getMonth()];
});
polyfill('getMonthName', function () {
return monthsFull[this.getMonth()];
});
polyfill('getUTCOffset', function () {
var tz = pad(Math.abs(this.getTimezoneOffset() / 0.6), 4);
if (this.getTimezoneOffset() > 0) {
tz = '-' + tz;
}
return tz;
});
polyfill('toCLFString', function () {
return pad(this.getDate(), 2) + '/' + this.getMonthAbbr() + '/' +
this.getFullYear() + ':' + pad(this.getHours(), 2) + ':' +
pad(this.getMinutes(), 2) + ':' + pad(this.getSeconds(), 2) +
' ' + this.getUTCOffset();
});
polyfill('toYMD', function (separator) {
separator = typeof separator === 'undefined' ? '-' : separator;
return this.getUTCFullYear() + separator + pad(this.getUTCMonth() + 1, 2) +
separator + pad(this.getUTCDate(), 2);
});
polyfill('toDBString', function () {
return this.getUTCFullYear() + '-' + pad(this.getUTCMonth() + 1, 2) +
'-' + pad(this.getUTCDate(), 2) + ' ' + pad(this.getUTCHours(), 2) +
':' + pad(this.getUTCMinutes(), 2) + ':' + pad(this.getUTCSeconds(), 2);
});
polyfill('clearTime', function () {
this.setHours(0);
this.setMinutes(0);
this.setSeconds(0);
this.setMilliseconds(0);
return this;
});
polyfill('clearUTCTime', function () {
this.setUTCHours(0);
this.setUTCMinutes(0);
this.setUTCSeconds(0);
this.setUTCMilliseconds(0);
return this;
});
polyfill('add', function (obj) {
if (obj.milliseconds !== undefined) {
this.setMilliseconds(this.getMilliseconds() + obj.milliseconds);
}
if (obj.seconds !== undefined) {
this.setSeconds(this.getSeconds() + obj.seconds);
}
if (obj.minutes !== undefined) {
this.setMinutes(this.getMinutes() + obj.minutes);
}
if (obj.hours !== undefined) {
this.setHours(this.getHours() + obj.hours);
}
if (obj.days !== undefined) {
this.setDate(this.getDate() + obj.days);
}
if (obj.weeks !== undefined) {
this.setDate(this.getDate() + (obj.weeks * 7));
}
if (obj.months !== undefined) {
this.setMonth(this.getMonth() + obj.months);
}
if (obj.years !== undefined) {
this.setFullYear(this.getFullYear() + obj.years);
}
return this;
});
polyfill('addMilliseconds', function (milliseconds) {
return this.add({ milliseconds: milliseconds });
});
polyfill('addSeconds', function (seconds) {
return this.add({ seconds: seconds });
});
polyfill('addMinutes', function (minutes) {
return this.add({ minutes: minutes });
});
polyfill('addHours', function (hours) {
return this.add({ hours: hours });
});
polyfill('addDays', function (days) {
return this.add({ days: days });
});
polyfill('addWeeks', function (weeks) {
return this.add({ days: (weeks * 7) });
});
polyfill('addMonths', function (months) {
return this.add({ months: months });
});
polyfill('addYears', function (years) {
return this.add({ years: years });
});
polyfill('setTimeToNow', function () {
var n = new Date();
this.setMilliseconds(n.getMilliseconds());
this.setSeconds(n.getSeconds());
this.setMinutes(n.getMinutes());
this.setHours(n.getHours());
});
polyfill('clone', function () {
return new Cromag(this.valueOf());
});
polyfill('between', function (start, end) {
return (this.valueOf() >= start.valueOf() &&
this.valueOf() <= end.valueOf());
});
polyfill('compareTo', function (date) {
return Cromag.compare(this, date);
});
polyfill('equals', function (date) {
return Cromag.equals(this, date);
});
polyfill('isAfter', function (date) {
date = date ? date : new Cromag();
return (this.compareTo(date) > 0);
});
polyfill('isBefore', function (date) {
date = date ? date : new Cromag();
return (this.compareTo(date) < 0);
});
polyfill('getDaysBetween', function (date) {
return ((date.clone().valueOf() - this.valueOf()) / 86400000) | 0;
});
polyfill('getHoursBetween', function (date) {
return ((date.clone().valueOf() - this.valueOf()) / 3600000) | 0;
});
polyfill('getMinutesBetween', function (date) {
return ((date.clone().valueOf() - this.valueOf()) / 60000) | 0;
});
polyfill('getSecondsBetween', function (date) {
return ((date.clone().valueOf() - this.valueOf()) / 1000) | 0;
});
polyfill('getOrdinalNumber', function () {
return Math.ceil((this.clone().clearTime() - new Cromag(this.getFullYear(), 0, 1)) / 86400000) + 1;
});
polyfill('toFormat', function (format) {
var f = [ format ], i, l, s;
var replace = function (str, rep) {
var i = 0, l = f.length, j, ll, t, n = [];
for (; i < l; i++) {
if (typeof f[i] == 'string') {
t = f[i].split(str);
for (j = 0, ll = t.length - 1; j < ll; j++) {
n.push(t[j]);
n.push([rep]); // replacement pushed as non-string
}
n.push(t[ll]);
} else {
// must be a replacement, don't process, just push
n.push(f[i]);
}
}
f = n;
};
var hours = (this.getHours() % 12) ? this.getHours() % 12 : 12;
replace('YYYY', this.getFullYear());
replace('YY', String(this.getFullYear()).slice(-2));
replace('MMMM', monthsFull[this.getMonth()]);
replace('MMM', monthsAbbr[this.getMonth()]);
replace('MM', pad(this.getMonth() + 1, 2));
replace('MI', pad(this.getMinutes(), 2));
replace('M', this.getMonth() + 1);
replace('DDDD', daysFull[this.getDay()]);
replace('DDD', daysAbbr[this.getDay()]);
replace('DD', pad(this.getDate(), 2));
replace('D', this.getDate());
replace('HH24', pad(this.getHours(), 2));
replace('HH', pad(hours, 2));
replace('H', hours);
replace('SS', pad(this.getSeconds(), 2));
replace('PP', (this.getHours() >= 12) ? 'PM' : 'AM');
replace('P', (this.getHours() >= 12) ? 'pm' : 'am');
replace('LL', pad(this.getMilliseconds(), 3));
s = '';
for (l = f.length; i < l; i++) {
s += typeof f[i] == 'string' ? f[i] : f[i][0];
}
return f.join('');
});
exports = module.exports = Cromag;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment