/*! * @copyright Copyright © Kartik Visweswaran, Krajee.com, 2014 - 2020 * @version 1.3.6 * * Date formatter utility library that allows formatting date/time variables or Date objects using PHP DateTime format. * This library is a standalone javascript library and does not depend on other libraries or plugins like jQuery. The * library also adds support for Universal Module Definition (UMD). * * @see http://php.net/manual/en/function.date.php * * For more JQuery plugins visit http://plugins.krajee.com * For more Yii related demos visit http://demos.krajee.com */ (function (root, factory) { // noinspection JSUnresolvedVariable if (typeof define === 'function' && define.amd) { // AMD // noinspection JSUnresolvedFunction define([], factory); } else { // noinspection JSUnresolvedVariable if (typeof module === 'object' && module.exports) { // Node // noinspection JSUnresolvedVariable module.exports = factory(); } else { // Browser globals root.DateFormatter = factory(); } } }(typeof self !== 'undefined' ? self : this, function () { var DateFormatter, $h; /** * Global helper object */ $h = { DAY: 1000 * 60 * 60 * 24, HOUR: 3600, defaults: { dateSettings: { days: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], daysShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], months: [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ], monthsShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], meridiem: ['AM', 'PM'], ordinal: function (number) { var n = number % 10, suffixes = {1: 'st', 2: 'nd', 3: 'rd'}; return Math.floor(number % 100 / 10) === 1 || !suffixes[n] ? 'th' : suffixes[n]; } }, separators: /[ \-+\/.:@]/g, validParts: /[dDjlNSwzWFmMntLoYyaABgGhHisueTIOPZcrU]/g, intParts: /[djwNzmnyYhHgGis]/g, tzParts: /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g, tzClip: /[^-+\dA-Z]/g }, getInt: function (str, radix) { return parseInt(str, (radix ? radix : 10)); }, compare: function (str1, str2) { return typeof (str1) === 'string' && typeof (str2) === 'string' && str1.toLowerCase() === str2.toLowerCase(); }, lpad: function (value, length, chr) { var val = value.toString(); chr = chr || '0'; return val.length < length ? $h.lpad(chr + val, length) : val; }, merge: function (out) { var i, obj; out = out || {}; for (i = 1; i < arguments.length; i++) { obj = arguments[i]; if (!obj) { continue; } for (var key in obj) { if (obj.hasOwnProperty(key)) { if (typeof obj[key] === 'object') { $h.merge(out[key], obj[key]); } else { out[key] = obj[key]; } } } } return out; }, getIndex: function (val, arr) { for (var i = 0; i < arr.length; i++) { if (arr[i].toLowerCase() === val.toLowerCase()) { return i; } } return -1; } }; /** * Date Formatter Library Constructor * @param options * @constructor */ DateFormatter = function (options) { var self = this, config = $h.merge($h.defaults, options); self.dateSettings = config.dateSettings; self.separators = config.separators; self.validParts = config.validParts; self.intParts = config.intParts; self.tzParts = config.tzParts; self.tzClip = config.tzClip; }; /** * DateFormatter Library Prototype */ DateFormatter.prototype = { constructor: DateFormatter, getMonth: function (val) { var self = this, i; i = $h.getIndex(val, self.dateSettings.monthsShort) + 1; if (i === 0) { i = $h.getIndex(val, self.dateSettings.months) + 1; } return i; }, parseDate: function (vDate, vFormat) { var self = this, vFormatParts, vDateParts, i, vDateFlag = false, vTimeFlag = false, vDatePart, iDatePart, vSettings = self.dateSettings, vMonth, vMeriIndex, vMeriOffset, len, mer, out = {date: null, year: null, month: null, day: null, hour: 0, min: 0, sec: 0}; if (!vDate) { return null; } if (vDate instanceof Date) { return vDate; } if (vFormat === 'U') { i = $h.getInt(vDate); return i ? new Date(i * 1000) : vDate; } switch (typeof vDate) { case 'number': return new Date(vDate); case 'string': break; default: return null; } vFormatParts = vFormat.match(self.validParts); if (!vFormatParts || vFormatParts.length === 0) { throw new Error('Invalid date format definition.'); } for (i = vFormatParts.length - 1; i >= 0; i--) { if (vFormatParts[i] === 'S') { vFormatParts.splice(i, 1); } } vDateParts = vDate.replace(self.separators, '\0').split('\0'); for (i = 0; i < vDateParts.length; i++) { vDatePart = vDateParts[i]; iDatePart = $h.getInt(vDatePart); switch (vFormatParts[i]) { case 'y': case 'Y': if (iDatePart) { len = vDatePart.length; out.year = len === 2 ? $h.getInt((iDatePart < 70 ? '20' : '19') + vDatePart) : iDatePart; } else { return null; } vDateFlag = true; break; case 'm': case 'n': case 'M': case 'F': if (isNaN(iDatePart)) { vMonth = self.getMonth(vDatePart); if (vMonth > 0) { out.month = vMonth; } else { return null; } } else { if (iDatePart >= 1 && iDatePart <= 12) { out.month = iDatePart; } else { return null; } } vDateFlag = true; break; case 'd': case 'j': if (iDatePart >= 1 && iDatePart <= 31) { out.day = iDatePart; } else { return null; } vDateFlag = true; break; case 'g': case 'h': vMeriIndex = (vFormatParts.indexOf('a') > -1) ? vFormatParts.indexOf('a') : ((vFormatParts.indexOf('A') > -1) ? vFormatParts.indexOf('A') : -1); mer = vDateParts[vMeriIndex]; if (vMeriIndex !== -1) { vMeriOffset = $h.compare(mer, vSettings.meridiem[0]) ? 0 : ($h.compare(mer, vSettings.meridiem[1]) ? 12 : -1); if (iDatePart >= 1 && iDatePart <= 12 && vMeriOffset !== -1) { out.hour = iDatePart % 12 === 0 ? vMeriOffset : iDatePart + vMeriOffset; } else { if (iDatePart >= 0 && iDatePart <= 23) { out.hour = iDatePart; } } } else { if (iDatePart >= 0 && iDatePart <= 23) { out.hour = iDatePart; } else { return null; } } vTimeFlag = true; break; case 'G': case 'H': if (iDatePart >= 0 && iDatePart <= 23) { out.hour = iDatePart; } else { return null; } vTimeFlag = true; break; case 'i': if (iDatePart >= 0 && iDatePart <= 59) { out.min = iDatePart; } else { return null; } vTimeFlag = true; break; case 's': if (iDatePart >= 0 && iDatePart <= 59) { out.sec = iDatePart; } else { return null; } vTimeFlag = true; break; } } if (vDateFlag === true) { var varY = out.year || 0, varM = out.month ? out.month - 1 : 0, varD = out.day || 1; out.date = new Date(varY, varM, varD, out.hour, out.min, out.sec, 0); } else { if (vTimeFlag !== true) { return null; } out.date = new Date(0, 0, 0, out.hour, out.min, out.sec, 0); } return out.date; }, guessDate: function (vDateStr, vFormat) { if (typeof vDateStr !== 'string') { return vDateStr; } var self = this, vParts = vDateStr.replace(self.separators, '\0').split('\0'), vPattern = /^[djmn]/g, len, vFormatParts = vFormat.match(self.validParts), vDate = new Date(), vDigit = 0, vYear, i, n, iPart, iSec; if (!vPattern.test(vFormatParts[0])) { return vDateStr; } for (i = 0; i < vParts.length; i++) { vDigit = 2; iPart = vParts[i]; iSec = $h.getInt(iPart.substr(0, 2)); if (isNaN(iSec)) { return null; } switch (i) { case 0: if (vFormatParts[0] === 'm' || vFormatParts[0] === 'n') { vDate.setMonth(iSec - 1); } else { vDate.setDate(iSec); } break; case 1: if (vFormatParts[0] === 'm' || vFormatParts[0] === 'n') { vDate.setDate(iSec); } else { vDate.setMonth(iSec - 1); } break; case 2: vYear = vDate.getFullYear(); len = iPart.length; vDigit = len < 4 ? len : 4; vYear = $h.getInt(len < 4 ? vYear.toString().substr(0, 4 - len) + iPart : iPart.substr(0, 4)); if (!vYear) { return null; } vDate.setFullYear(vYear); break; case 3: vDate.setHours(iSec); break; case 4: vDate.setMinutes(iSec); break; case 5: vDate.setSeconds(iSec); break; } n = iPart.substr(vDigit); if (n.length > 0) { vParts.splice(i + 1, 0, n); } } return vDate; }, parseFormat: function (vChar, vDate) { var self = this, vSettings = self.dateSettings, fmt, backslash = /\\?(.?)/gi, doFormat = function (t, s) { return fmt[t] ? fmt[t]() : s; }; fmt = { ///////// // DAY // ///////// /** * Day of month with leading 0: `01..31` * @return {string} */ d: function () { return $h.lpad(fmt.j(), 2); }, /** * Shorthand day name: `Mon...Sun` * @return {string} */ D: function () { return vSettings.daysShort[fmt.w()]; }, /** * Day of month: `1..31` * @return {number} */ j: function () { return vDate.getDate(); }, /** * Full day name: `Monday...Sunday` * @return {string} */ l: function () { return vSettings.days[fmt.w()]; }, /** * ISO-8601 day of week: `1[Mon]..7[Sun]` * @return {number} */ N: function () { return fmt.w() || 7; }, /** * Day of week: `0[Sun]..6[Sat]` * @return {number} */ w: function () { return vDate.getDay(); }, /** * Day of year: `0..365` * @return {number} */ z: function () { var a = new Date(fmt.Y(), fmt.n() - 1, fmt.j()), b = new Date(fmt.Y(), 0, 1); return Math.round((a - b) / $h.DAY); }, ////////// // WEEK // ////////// /** * ISO-8601 week number * @return {number} */ W: function () { var a = new Date(fmt.Y(), fmt.n() - 1, fmt.j() - fmt.N() + 3), b = new Date(a.getFullYear(), 0, 4); return $h.lpad(1 + Math.round((a - b) / $h.DAY / 7), 2); }, /////////// // MONTH // /////////// /** * Full month name: `January...December` * @return {string} */ F: function () { return vSettings.months[vDate.getMonth()]; }, /** * Month w/leading 0: `01..12` * @return {string} */ m: function () { return $h.lpad(fmt.n(), 2); }, /** * Shorthand month name; `Jan...Dec` * @return {string} */ M: function () { return vSettings.monthsShort[vDate.getMonth()]; }, /** * Month: `1...12` * @return {number} */ n: function () { return vDate.getMonth() + 1; }, /** * Days in month: `28...31` * @return {number} */ t: function () { return (new Date(fmt.Y(), fmt.n(), 0)).getDate(); }, ////////// // YEAR // ////////// /** * Is leap year? `0 or 1` * @return {number} */ L: function () { var Y = fmt.Y(); return (Y % 4 === 0 && Y % 100 !== 0 || Y % 400 === 0) ? 1 : 0; }, /** * ISO-8601 year * @return {number} */ o: function () { var n = fmt.n(), W = fmt.W(), Y = fmt.Y(); return Y + (n === 12 && W < 9 ? 1 : n === 1 && W > 9 ? -1 : 0); }, /** * Full year: `e.g. 1980...2010` * @return {number} */ Y: function () { return vDate.getFullYear(); }, /** * Last two digits of year: `00...99` * @return {string} */ y: function () { return fmt.Y().toString().slice(-2); }, ////////// // TIME // ////////// /** * Meridian lower: `am or pm` * @return {string} */ a: function () { return fmt.A().toLowerCase(); }, /** * Meridian upper: `AM or PM` * @return {string} */ A: function () { var n = fmt.G() < 12 ? 0 : 1; return vSettings.meridiem[n]; }, /** * Swatch Internet time: `000..999` * @return {string} */ B: function () { var H = vDate.getUTCHours() * $h.HOUR, i = vDate.getUTCMinutes() * 60, s = vDate.getUTCSeconds(); return $h.lpad(Math.floor((H + i + s + $h.HOUR) / 86.4) % 1000, 3); }, /** * 12-Hours: `1..12` * @return {number} */ g: function () { return fmt.G() % 12 || 12; }, /** * 24-Hours: `0..23` * @return {number} */ G: function () { return vDate.getHours(); }, /** * 12-Hours with leading 0: `01..12` * @return {string} */ h: function () { return $h.lpad(fmt.g(), 2); }, /** * 24-Hours w/leading 0: `00..23` * @return {string} */ H: function () { return $h.lpad(fmt.G(), 2); }, /** * Minutes w/leading 0: `00..59` * @return {string} */ i: function () { return $h.lpad(vDate.getMinutes(), 2); }, /** * Seconds w/leading 0: `00..59` * @return {string} */ s: function () { return $h.lpad(vDate.getSeconds(), 2); }, /** * Microseconds: `000000-999000` * @return {string} */ u: function () { return $h.lpad(vDate.getMilliseconds() * 1000, 6); }, ////////////// // TIMEZONE // ////////////// /** * Timezone identifier: `e.g. Atlantic/Azores, ...` * @return {string} */ e: function () { var str = /\((.*)\)/.exec(String(vDate))[1]; return str || 'Coordinated Universal Time'; }, /** * DST observed? `0 or 1` * @return {number} */ I: function () { var a = new Date(fmt.Y(), 0), c = Date.UTC(fmt.Y(), 0), b = new Date(fmt.Y(), 6), d = Date.UTC(fmt.Y(), 6); return ((a - c) !== (b - d)) ? 1 : 0; }, /** * Difference to GMT in hour format: `e.g. +0200` * @return {string} */ O: function () { var tzo = vDate.getTimezoneOffset(), a = Math.abs(tzo); return (tzo > 0 ? '-' : '+') + $h.lpad(Math.floor(a / 60) * 100 + a % 60, 4); }, /** * Difference to GMT with colon: `e.g. +02:00` * @return {string} */ P: function () { var O = fmt.O(); return (O.substr(0, 3) + ':' + O.substr(3, 2)); }, /** * Timezone abbreviation: `e.g. EST, MDT, ...` * @return {string} */ T: function () { var str = (String(vDate).match(self.tzParts) || ['']).pop().replace(self.tzClip, ''); return str || 'UTC'; }, /** * Timezone offset in seconds: `-43200...50400` * @return {number} */ Z: function () { return -vDate.getTimezoneOffset() * 60; }, //////////////////// // FULL DATE TIME // //////////////////// /** * ISO-8601 date * @return {string} */ c: function () { return 'Y-m-d\\TH:i:sP'.replace(backslash, doFormat); }, /** * RFC 2822 date * @return {string} */ r: function () { return 'D, d M Y H:i:s O'.replace(backslash, doFormat); }, /** * Seconds since UNIX epoch * @return {number} */ U: function () { return vDate.getTime() / 1000 || 0; } }; return doFormat(vChar, vChar); }, formatDate: function (vDate, vFormat) { var self = this, i, n, len, str, vChar, vDateStr = '', BACKSLASH = '\\'; if (typeof vDate === 'string') { vDate = self.parseDate(vDate, vFormat); if (!vDate) { return null; } } if (vDate instanceof Date) { len = vFormat.length; for (i = 0; i < len; i++) { vChar = vFormat.charAt(i); if (vChar === 'S' || vChar === BACKSLASH) { continue; } if (i > 0 && vFormat.charAt(i - 1) === BACKSLASH) { vDateStr += vChar; continue; } str = self.parseFormat(vChar, vDate); if (i !== (len - 1) && self.intParts.test(vChar) && vFormat.charAt(i + 1) === 'S') { n = $h.getInt(str) || 0; str += self.dateSettings.ordinal(n); } vDateStr += str; } return vDateStr; } return ''; } }; return DateFormatter; }));