+//
+// strftime
+// github.com/samsonjs/strftime
+// @_sjs
+//
+// Copyright 2010 - 2016 Sami Samhuri <sami@samhuri.net>
+//
+// MIT License
+// http://sjs.mit-license.org
+//
+
+;(function() {
+
+ var Locales = {
+ de_DE: {
+ days: ['Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'],
+ shortDays: ['So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa'],
+ months: ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'],
+ shortMonths: ['Jan', 'Feb', 'Mär', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez'],
+ AM: 'AM',
+ PM: 'PM',
+ am: 'am',
+ pm: 'pm',
+ formats: {
+ c: '%a %d %b %Y %X %Z',
+ D: '%d.%m.%Y',
+ F: '%Y-%m-%d',
+ R: '%H:%M',
+ r: '%I:%M:%S %p',
+ T: '%H:%M:%S',
+ v: '%e-%b-%Y',
+ X: '%T',
+ x: '%D'
+ }
+ },
+
+ en_CA: {
+ days: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ],
+ shortDays: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
+ months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
+ shortMonths: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
+ ordinalSuffixes: [
+ 'st', 'nd', 'rd', 'th', 'th', 'th', 'th', 'th', 'th', 'th',
+ 'th', 'th', 'th', 'th', 'th', 'th', 'th', 'th', 'th', 'th',
+ 'st', 'nd', 'rd', 'th', 'th', 'th', 'th', 'th', 'th', 'th',
+ 'st'
+ ],
+ AM: 'AM',
+ PM: 'PM',
+ am: 'am',
+ pm: 'pm',
+ formats: {
+ c: '%a %d %b %Y %X %Z',
+ D: '%d/%m/%y',
+ F: '%Y-%m-%d',
+ R: '%H:%M',
+ r: '%I:%M:%S %p',
+ T: '%H:%M:%S',
+ v: '%e-%b-%Y',
+ X: '%r',
+ x: '%D'
+ }
+ },
+
+ en_US: {
+ days: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ],
+ shortDays: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
+ months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
+ shortMonths: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
+ ordinalSuffixes: [
+ 'st', 'nd', 'rd', 'th', 'th', 'th', 'th', 'th', 'th', 'th',
+ 'th', 'th', 'th', 'th', 'th', 'th', 'th', 'th', 'th', 'th',
+ 'st', 'nd', 'rd', 'th', 'th', 'th', 'th', 'th', 'th', 'th',
+ 'st'
+ ],
+ AM: 'AM',
+ PM: 'PM',
+ am: 'am',
+ pm: 'pm',
+ formats: {
+ c: '%a %d %b %Y %X %Z',
+ D: '%m/%d/%y',
+ F: '%Y-%m-%d',
+ R: '%H:%M',
+ r: '%I:%M:%S %p',
+ T: '%H:%M:%S',
+ v: '%e-%b-%Y',
+ X: '%r',
+ x: '%D'
+ }
+ },
+
+ es_MX: {
+ days: ['domingo', 'lunes', 'martes', 'miércoles', 'jueves', 'viernes', 'sábado'],
+ shortDays: ['dom', 'lun', 'mar', 'mié', 'jue', 'vie', 'sáb'],
+ months: ['enero', 'febrero', 'marzo', 'abril', 'mayo', 'junio', 'julio', 'agosto', 'septiembre', 'octubre', 'noviembre',' diciembre'],
+ shortMonths: ['ene', 'feb', 'mar', 'abr', 'may', 'jun', 'jul', 'ago', 'sep', 'oct', 'nov', 'dic'],
+ AM: 'AM',
+ PM: 'PM',
+ am: 'am',
+ pm: 'pm',
+ formats: {
+ c: '%a %d %b %Y %X %Z',
+ D: '%d/%m/%Y',
+ F: '%Y-%m-%d',
+ R: '%H:%M',
+ r: '%I:%M:%S %p',
+ T: '%H:%M:%S',
+ v: '%e-%b-%Y',
+ X: '%T',
+ x: '%D'
+ }
+ },
+
+ fr_FR: {
+ days: ['dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi'],
+ shortDays: ['dim.', 'lun.', 'mar.', 'mer.', 'jeu.', 'ven.', 'sam.'],
+ months: ['janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre'],
+ shortMonths: ['janv.', 'févr.', 'mars', 'avril', 'mai', 'juin', 'juil.', 'août', 'sept.', 'oct.', 'nov.', 'déc.'],
+ AM: 'AM',
+ PM: 'PM',
+ am: 'am',
+ pm: 'pm',
+ formats: {
+ c: '%a %d %b %Y %X %Z',
+ D: '%d/%m/%Y',
+ F: '%Y-%m-%d',
+ R: '%H:%M',
+ r: '%I:%M:%S %p',
+ T: '%H:%M:%S',
+ v: '%e-%b-%Y',
+ X: '%T',
+ x: '%D'
+ }
+ },
+
+ it_IT: {
+ days: ['domenica', 'lunedì', 'martedì', 'mercoledì', 'giovedì', 'venerdì', 'sabato'],
+ shortDays: ['dom', 'lun', 'mar', 'mer', 'gio', 'ven', 'sab'],
+ months: ['gennaio', 'febbraio', 'marzo', 'aprile', 'maggio', 'giugno', 'luglio', 'agosto', 'settembre', 'ottobre', 'novembre', 'dicembre'],
+ shortMonths: ['pr', 'mag', 'giu', 'lug', 'ago', 'set', 'ott', 'nov', 'dic'],
+ AM: 'AM',
+ PM: 'PM',
+ am: 'am',
+ pm: 'pm',
+ formats: {
+ c: '%a %d %b %Y %X %Z',
+ D: '%d/%m/%Y',
+ F: '%Y-%m-%d',
+ R: '%H:%M',
+ r: '%I:%M:%S %p',
+ T: '%H:%M:%S',
+ v: '%e-%b-%Y',
+ X: '%T',
+ x: '%D'
+ }
+ },
+
+ nl_NL: {
+ days: ['zondag', 'maandag', 'dinsdag', 'woensdag', 'donderdag', 'vrijdag', 'zaterdag'],
+ shortDays: ['zo', 'ma', 'di', 'wo', 'do', 'vr', 'za'],
+ months: ['januari', 'februari', 'maart', 'april', 'mei', 'juni', 'juli', 'augustus', 'september', 'oktober', 'november', 'december'],
+ shortMonths: ['jan', 'feb', 'mrt', 'apr', 'mei', 'jun', 'jul', 'aug', 'sep', 'okt', 'nov', 'dec'],
+ AM: 'AM',
+ PM: 'PM',
+ am: 'am',
+ pm: 'pm',
+ formats: {
+ c: '%a %d %b %Y %X %Z',
+ D: '%d-%m-%y',
+ F: '%Y-%m-%d',
+ R: '%H:%M',
+ r: '%I:%M:%S %p',
+ T: '%H:%M:%S',
+ v: '%e-%b-%Y',
+ X: '%T',
+ x: '%D'
+ }
+ },
+
+ pt_BR: {
+ days: ['domingo', 'segunda', 'terça', 'quarta', 'quinta', 'sexta', 'sábado'],
+ shortDays: ['Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sáb'],
+ months: ['janeiro', 'fevereiro', 'março', 'abril', 'maio', 'junho', 'julho', 'agosto', 'setembro', 'outubro', 'novembro', 'dezembro'],
+ shortMonths: ['Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez'],
+ AM: 'AM',
+ PM: 'PM',
+ am: 'am',
+ pm: 'pm',
+ formats: {
+ c: '%a %d %b %Y %X %Z',
+ D: '%d-%m-%Y',
+ F: '%Y-%m-%d',
+ R: '%H:%M',
+ r: '%I:%M:%S %p',
+ T: '%H:%M:%S',
+ v: '%e-%b-%Y',
+ X: '%T',
+ x: '%D'
+ }
+ },
+
+ ru_RU: {
+ days: ['Воскресенье', 'Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота'],
+ shortDays: ['Вс', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб'],
+ months: ['Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь'],
+ shortMonths: ['янв', 'фев', 'мар', 'апр', 'май', 'июн', 'июл', 'авг', 'сен', 'окт', 'ноя', 'дек'],
+ AM: 'AM',
+ PM: 'PM',
+ am: 'am',
+ pm: 'pm',
+ formats: {
+ c: '%a %d %b %Y %X',
+ D: '%d.%m.%y',
+ F: '%Y-%m-%d',
+ R: '%H:%M',
+ r: '%I:%M:%S %p',
+ T: '%H:%M:%S',
+ v: '%e-%b-%Y',
+ X: '%T',
+ x: '%D'
+ }
+ },
+
+ tr_TR: {
+ days: ['Pazar', 'Pazartesi', 'Salı','Çarşamba', 'Perşembe', 'Cuma', 'Cumartesi'],
+ shortDays: ['Paz', 'Pzt', 'Sal', 'Çrş', 'Prş', 'Cum', 'Cts'],
+ months: ['Ocak', 'Şubat', 'Mart', 'Nisan', 'Mayıs', 'Haziran', 'Temmuz', 'Ağustos', 'Eylül', 'Ekim', 'Kasım', 'Aralık'],
+ shortMonths: ['Oca', 'Şub', 'Mar', 'Nis', 'May', 'Haz', 'Tem', 'Ağu', 'Eyl', 'Eki', 'Kas', 'Ara'],
+ AM: 'ÖÖ',
+ PM: 'ÖS',
+ am: 'ÖÖ',
+ pm: 'ÖS',
+ formats: {
+ c: '%a %d %b %Y %X %Z',
+ D: '%d-%m-%Y',
+ F: '%Y-%m-%d',
+ R: '%H:%M',
+ r: '%I:%M:%S %p',
+ T: '%H:%M:%S',
+ v: '%e-%b-%Y',
+ X: '%T',
+ x: '%D'
+ }
+ },
+
+ // By michaeljayt<michaeljayt@gmail.com>
+ // https://github.com/michaeljayt/strftime/commit/bcb4c12743811d51e568175aa7bff3fd2a77cef3
+ zh_CN: {
+ days: ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'],
+ shortDays: ['日', '一', '二', '三', '四', '五', '六'],
+ months: ['一月份', '二月份', '三月份', '四月份', '五月份', '六月份', '七月份', '八月份', '九月份', '十月份', '十一月份', '十二月份'],
+ shortMonths: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'],
+ AM: '上午',
+ PM: '下午',
+ am: '上午',
+ pm: '下午',
+ formats: {
+ c: '%a %d %b %Y %X %Z',
+ D: '%d/%m/%y',
+ F: '%Y-%m-%d',
+ R: '%H:%M',
+ r: '%I:%M:%S %p',
+ T: '%H:%M:%S',
+ v: '%e-%b-%Y',
+ X: '%r',
+ x: '%D'
+ }
+ }
+ };
+
+ var DefaultLocale = Locales['en_US'],
+ defaultStrftime = new Strftime(DefaultLocale, 0, false),
+ isCommonJS = typeof module !== 'undefined',
+ namespace;
+
+ // CommonJS / Node module
+ if (isCommonJS) {
+ namespace = module.exports = defaultStrftime;
+ }
+ // Browsers and other environments
+ else {
+ // Get the global object. Works in ES3, ES5, and ES5 strict mode.
+ namespace = (function() { return this || (1,eval)('this'); }());
+ namespace.strftime = defaultStrftime;
+ }
+
+ // Polyfill Date.now for old browsers.
+ if (typeof Date.now !== 'function') {
+ Date.now = function() {
+ return +new Date();
+ };
+ }
+
+ function Strftime(locale, customTimezoneOffset, useUtcTimezone) {
+ var _locale = locale || DefaultLocale,
+ _customTimezoneOffset = customTimezoneOffset || 0,
+ _useUtcBasedDate = useUtcTimezone || false,
+
+ // we store unix timestamp value here to not create new Date() each iteration (each millisecond)
+ // Date.now() is 2 times faster than new Date()
+ // while millisecond precise is enough here
+ // this could be very helpful when strftime triggered a lot of times one by one
+ _cachedDateTimestamp = 0,
+ _cachedDate;
+
+ function _strftime(format, date) {
+ var timestamp;
+
+ if (!date) {
+ var currentTimestamp = Date.now();
+ if (currentTimestamp > _cachedDateTimestamp) {
+ _cachedDateTimestamp = currentTimestamp;
+ _cachedDate = new Date(_cachedDateTimestamp);
+
+ timestamp = _cachedDateTimestamp;
+
+ if (_useUtcBasedDate) {
+ // how to avoid duplication of date instantiation for utc here?
+ // we tied to getTimezoneOffset of the current date
+ _cachedDate = new Date(_cachedDateTimestamp + getTimestampToUtcOffsetFor(_cachedDate) + _customTimezoneOffset);
+ }
+ }
+ else {
+ timestamp = _cachedDateTimestamp;
+ }
+ date = _cachedDate;
+ }
+ else {
+ timestamp = date.getTime();
+
+ if (_useUtcBasedDate) {
+ var utcOffset = getTimestampToUtcOffsetFor(date);
+ date = new Date(timestamp + utcOffset + _customTimezoneOffset);
+ // If we've crossed a DST boundary with this calculation we need to
+ // adjust the new date accordingly or it will be off by an hour in UTC.
+ if (getTimestampToUtcOffsetFor(date) !== utcOffset) {
+ var newUTCOffset = getTimestampToUtcOffsetFor(date);
+ date = new Date(timestamp + newUTCOffset + _customTimezoneOffset);
+ }
+ }
+ }
+
+ return _processFormat(format, date, _locale, timestamp);
+ }
+
+ function _processFormat(format, date, locale, timestamp) {
+ var resultString = '',
+ padding = null,
+ isInScope = false,
+ length = format.length,
+ extendedTZ = false;
+
+ for (var i = 0; i < length; i++) {
+
+ var currentCharCode = format.charCodeAt(i);
+
+ if (isInScope === true) {
+ // '-'
+ if (currentCharCode === 45) {
+ padding = '';
+ continue;
+ }
+ // '_'
+ else if (currentCharCode === 95) {
+ padding = ' ';
+ continue;
+ }
+ // '0'
+ else if (currentCharCode === 48) {
+ padding = '0';
+ continue;
+ }
+ // ':'
+ else if (currentCharCode === 58) {
+ if (extendedTZ) {
+ warn("[WARNING] detected use of unsupported %:: or %::: modifiers to strftime");
+ }
+ extendedTZ = true;
+ continue;
+ }
+
+ switch (currentCharCode) {
+
+ // Examples for new Date(0) in GMT
+
+ // '%'
+ // case '%':
+ case 37:
+ resultString += '%';
+ break;
+
+ // 'Thursday'
+ // case 'A':
+ case 65:
+ resultString += locale.days[date.getDay()];
+ break;
+
+ // 'January'
+ // case 'B':
+ case 66:
+ resultString += locale.months[date.getMonth()];
+ break;
+
+ // '19'
+ // case 'C':
+ case 67:
+ resultString += padTill2(Math.floor(date.getFullYear() / 100), padding);
+ break;
+
+ // '01/01/70'
+ // case 'D':
+ case 68:
+ resultString += _processFormat(locale.formats.D, date, locale, timestamp);
+ break;
+
+ // '1970-01-01'
+ // case 'F':
+ case 70:
+ resultString += _processFormat(locale.formats.F, date, locale, timestamp);
+ break;
+
+ // '00'
+ // case 'H':
+ case 72:
+ resultString += padTill2(date.getHours(), padding);
+ break;
+
+ // '12'
+ // case 'I':
+ case 73:
+ resultString += padTill2(hours12(date.getHours()), padding);
+ break;
+
+ // '000'
+ // case 'L':
+ case 76:
+ resultString += padTill3(Math.floor(timestamp % 1000));
+ break;
+
+ // '00'
+ // case 'M':
+ case 77:
+ resultString += padTill2(date.getMinutes(), padding);
+ break;
+
+ // 'am'
+ // case 'P':
+ case 80:
+ resultString += date.getHours() < 12 ? locale.am : locale.pm;
+ break;
+
+ // '00:00'
+ // case 'R':
+ case 82:
+ resultString += _processFormat(locale.formats.R, date, locale, timestamp);
+ break;
+
+ // '00'
+ // case 'S':
+ case 83:
+ resultString += padTill2(date.getSeconds(), padding);
+ break;
+
+ // '00:00:00'
+ // case 'T':
+ case 84:
+ resultString += _processFormat(locale.formats.T, date, locale, timestamp);
+ break;
+
+ // '00'
+ // case 'U':
+ case 85:
+ resultString += padTill2(weekNumber(date, 'sunday'), padding);
+ break;
+
+ // '00'
+ // case 'W':
+ case 87:
+ resultString += padTill2(weekNumber(date, 'monday'), padding);
+ break;
+
+ // '16:00:00'
+ // case 'X':
+ case 88:
+ resultString += _processFormat(locale.formats.X, date, locale, timestamp);
+ break;
+
+ // '1970'
+ // case 'Y':
+ case 89:
+ resultString += date.getFullYear();
+ break;
+
+ // 'GMT'
+ // case 'Z':
+ case 90:
+ if (_useUtcBasedDate && _customTimezoneOffset === 0) {
+ resultString += "GMT";
+ }
+ else {
+ // fixme optimize
+ var tzString = date.toString().match(/\(([\w\s]+)\)/);
+ resultString += tzString && tzString[1] || '';
+ }
+ break;
+
+ // 'Thu'
+ // case 'a':
+ case 97:
+ resultString += locale.shortDays[date.getDay()];
+ break;
+
+ // 'Jan'
+ // case 'b':
+ case 98:
+ resultString += locale.shortMonths[date.getMonth()];
+ break;
+
+ // ''
+ // case 'c':
+ case 99:
+ resultString += _processFormat(locale.formats.c, date, locale, timestamp);
+ break;
+
+ // '01'
+ // case 'd':
+ case 100:
+ resultString += padTill2(date.getDate(), padding);
+ break;
+
+ // ' 1'
+ // case 'e':
+ case 101:
+ resultString += padTill2(date.getDate(), padding == null ? ' ' : padding);
+ break;
+
+ // 'Jan'
+ // case 'h':
+ case 104:
+ resultString += locale.shortMonths[date.getMonth()];
+ break;
+
+ // '000'
+ // case 'j':
+ case 106:
+ var y = new Date(date.getFullYear(), 0, 1);
+ var day = Math.ceil((date.getTime() - y.getTime()) / (1000 * 60 * 60 * 24));
+ resultString += padTill3(day);
+ break;
+
+ // ' 0'
+ // case 'k':
+ case 107:
+ resultString += padTill2(date.getHours(), padding == null ? ' ' : padding);
+ break;
+
+ // '12'
+ // case 'l':
+ case 108:
+ resultString += padTill2(hours12(date.getHours()), padding == null ? ' ' : padding);
+ break;
+
+ // '01'
+ // case 'm':
+ case 109:
+ resultString += padTill2(date.getMonth() + 1, padding);
+ break;
+
+ // '\n'
+ // case 'n':
+ case 110:
+ resultString += '\n';
+ break;
+
+ // '1st'
+ // case 'o':
+ case 111:
+ // Try to use an ordinal suffix from the locale, but fall back to using the old
+ // function for compatibility with old locales that lack them.
+ var day = date.getDate();
+ if (locale.ordinalSuffixes) {
+ resultString += String(day) + (locale.ordinalSuffixes[day - 1] || ordinal(day));
+ }
+ else {
+ resultString += String(day) + ordinal(day);
+ }
+ break;
+
+ // 'AM'
+ // case 'p':
+ case 112:
+ resultString += date.getHours() < 12 ? locale.AM : locale.PM;
+ break;
+
+ // '12:00:00 AM'
+ // case 'r':
+ case 114:
+ resultString += _processFormat(locale.formats.r, date, locale, timestamp);
+ break;
+
+ // '0'
+ // case 's':
+ case 115:
+ resultString += Math.floor(timestamp / 1000);
+ break;
+
+ // '\t'
+ // case 't':
+ case 116:
+ resultString += '\t';
+ break;
+
+ // '4'
+ // case 'u':
+ case 117:
+ var day = date.getDay();
+ resultString += day === 0 ? 7 : day;
+ break; // 1 - 7, Monday is first day of the week
+
+ // ' 1-Jan-1970'
+ // case 'v':
+ case 118:
+ resultString += _processFormat(locale.formats.v, date, locale, timestamp);
+ break;
+
+ // '4'
+ // case 'w':
+ case 119:
+ resultString += date.getDay();
+ break; // 0 - 6, Sunday is first day of the week
+
+ // '12/31/69'
+ // case 'x':
+ case 120:
+ resultString += _processFormat(locale.formats.x, date, locale, timestamp);
+ break;
+
+ // '70'
+ // case 'y':
+ case 121:
+ resultString += ('' + date.getFullYear()).slice(2);
+ break;
+
+ // '+0000'
+ // case 'z':
+ case 122:
+ if (_useUtcBasedDate && _customTimezoneOffset === 0) {
+ resultString += extendedTZ ? "+00:00" : "+0000";
+ }
+ else {
+ var off;
+ if (_customTimezoneOffset !== 0) {
+ off = _customTimezoneOffset / (60 * 1000);
+ }
+ else {
+ off = -date.getTimezoneOffset();
+ }
+ var sign = off < 0 ? '-' : '+';
+ var sep = extendedTZ ? ':' : '';
+ var hours = Math.floor(Math.abs(off / 60));
+ var mins = Math.abs(off % 60);
+ resultString += sign + padTill2(hours) + sep + padTill2(mins);
+ }
+ break;
+
+ default:
+ if (isInScope) {
+ resultString += '%';
+ }
+ resultString += format[i];
+ break;
+ }
+
+ padding = null;
+ isInScope = false;
+ continue;
+ }
+
+ // '%'
+ if (currentCharCode === 37) {
+ isInScope = true;
+ continue;
+ }
+
+ resultString += format[i];
+ }
+
+ return resultString;
+ }
+
+ var strftime = _strftime;
+
+ strftime.localize = function(locale) {
+ return new Strftime(locale || _locale, _customTimezoneOffset, _useUtcBasedDate);
+ };
+
+ strftime.localizeByIdentifier = function(localeIdentifier) {
+ var locale = Locales[localeIdentifier];
+ if (!locale) {
+ warn('[WARNING] No locale found with identifier "' + localeIdentifier + '".');
+ return strftime;
+ }
+ return strftime.localize(locale);
+ };
+
+ strftime.timezone = function(timezone) {
+ var customTimezoneOffset = _customTimezoneOffset;
+ var useUtcBasedDate = _useUtcBasedDate;
+
+ var timezoneType = typeof timezone;
+ if (timezoneType === 'number' || timezoneType === 'string') {
+ useUtcBasedDate = true;
+
+ // ISO 8601 format timezone string, [-+]HHMM
+ if (timezoneType === 'string') {
+ var sign = timezone[0] === '-' ? -1 : 1,
+ hours = parseInt(timezone.slice(1, 3), 10),
+ minutes = parseInt(timezone.slice(3, 5), 10);
+
+ customTimezoneOffset = sign * ((60 * hours) + minutes) * 60 * 1000;
+ // in minutes: 420
+ }
+ else if (timezoneType === 'number') {
+ customTimezoneOffset = timezone * 60 * 1000;
+ }
+ }
+
+ return new Strftime(_locale, customTimezoneOffset, useUtcBasedDate);
+ };
+
+ strftime.utc = function() {
+ return new Strftime(_locale, _customTimezoneOffset, true);
+ };
+
+ return strftime;
+ }
+
+ function padTill2(numberToPad, paddingChar) {
+ if (paddingChar === '' || numberToPad > 9) {
+ return numberToPad;
+ }
+ if (paddingChar == null) {
+ paddingChar = '0';
+ }
+ return paddingChar + numberToPad;
+ }
+
+ function padTill3(numberToPad) {
+ if (numberToPad > 99) {
+ return numberToPad;
+ }
+ if (numberToPad > 9) {
+ return '0' + numberToPad;
+ }
+ return '00' + numberToPad;
+ }
+
+ function hours12(hour) {
+ if (hour === 0) {
+ return 12;
+ }
+ else if (hour > 12) {
+ return hour - 12;
+ }
+ return hour;
+ }
+
+ // firstWeekday: 'sunday' or 'monday', default is 'sunday'
+ //
+ // Pilfered & ported from Ruby's strftime implementation.
+ function weekNumber(date, firstWeekday) {
+ firstWeekday = firstWeekday || 'sunday';
+
+ // This works by shifting the weekday back by one day if we
+ // are treating Monday as the first day of the week.
+ var weekday = date.getDay();
+ if (firstWeekday === 'monday') {
+ if (weekday === 0) // Sunday
+ weekday = 6;
+ else
+ weekday--;
+ }
+
+ var firstDayOfYearUtc = Date.UTC(date.getFullYear(), 0, 1),
+ dateUtc = Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()),
+ yday = Math.floor((dateUtc - firstDayOfYearUtc) / 86400000),
+ weekNum = (yday + 7 - weekday) / 7;
+
+ return Math.floor(weekNum);
+ }
+
+ // Get the ordinal suffix for a number: st, nd, rd, or th
+ function ordinal(number) {
+ var i = number % 10;
+ var ii = number % 100;
+
+ if ((ii >= 11 && ii <= 13) || i === 0 || i >= 4) {
+ return 'th';
+ }
+ switch (i) {
+ case 1: return 'st';
+ case 2: return 'nd';
+ case 3: return 'rd';
+ }
+ }
+
+ function getTimestampToUtcOffsetFor(date) {
+ return (date.getTimezoneOffset() || 0) * 60000;
+ }
+
+ function warn(message) {
+ if (typeof console !== 'undefined' && typeof console.warn == 'function') {
+ console.warn(message)
+ }
+ }
+
+}());