1/*! 2 * @copyright Copyright © Kartik Visweswaran, Krajee.com, 2014 - 2025 3 * @version 1.3.6 4 * 5 * Date formatter utility library that allows formatting date/time variables or Date objects using PHP DateTime format. 6 * This library is a standalone javascript library and does not depend on other libraries or plugins like jQuery. The 7 * library also adds support for Universal Module Definition (UMD). 8 * 9 * @see http://php.net/manual/en/function.date.php 10 * 11 * For more JQuery plugins visit http://plugins.krajee.com 12 * For more Yii related demos visit http://demos.krajee.com 13 */ 14(function (root, factory) { 15 // noinspection JSUnresolvedVariable 16 if (typeof define === 'function' && define.amd) { // AMD 17 // noinspection JSUnresolvedFunction 18 define([], factory); 19 } else { 20 // noinspection JSUnresolvedVariable 21 if (typeof module === 'object' && module.exports) { // Node 22 // noinspection JSUnresolvedVariable 23 module.exports = factory(); 24 } else { // Browser globals 25 root.DateFormatter = factory(); 26 } 27 } 28}(typeof self !== 'undefined' ? self : this, function () { 29 var DateFormatter, $h; 30 /** 31 * Global helper object 32 */ 33 $h = { 34 DAY: 1000 * 60 * 60 * 24, 35 HOUR: 3600, 36 defaults: { 37 dateSettings: { 38 days: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], 39 daysShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], 40 months: [ 41 'January', 'February', 'March', 'April', 'May', 'June', 'July', 42 'August', 'September', 'October', 'November', 'December' 43 ], 44 monthsShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], 45 meridiem: ['AM', 'PM'], 46 ordinal: function (number) { 47 var n = number % 10, suffixes = {1: 'st', 2: 'nd', 3: 'rd'}; 48 return Math.floor(number % 100 / 10) === 1 || !suffixes[n] ? 'th' : suffixes[n]; 49 } 50 }, 51 separators: /[ \-+\/.:@]/g, 52 validParts: /[dDjlNSwzWFmMntLoYyaABgGhHisueTIOPZcrU]/g, 53 intParts: /[djwNzmnyYhHgGis]/g, 54 tzParts: /\b(?:[PMCEA][SDP]T|(?:Australian|Pacific|Mountain|Central|Eastern|Atlantic) (?:Eastern) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g, 55 tzClip: /[^-+\dA-Z]/g 56 }, 57 getInt: function (str, radix) { 58 return parseInt(str, (radix ? radix : 10)); 59 }, 60 compare: function (str1, str2) { 61 return typeof (str1) === 'string' && typeof (str2) === 'string' && str1.toLowerCase() === str2.toLowerCase(); 62 }, 63 lpad: function (value, length, chr) { 64 var val = value.toString(); 65 chr = chr || '0'; 66 return val.length < length ? $h.lpad(chr + val, length) : val; 67 }, 68 merge: function (out) { 69 var i, obj; 70 out = out || {}; 71 for (i = 1; i < arguments.length; i++) { 72 obj = arguments[i]; 73 if (!obj) { 74 continue; 75 } 76 for (var key in obj) { 77 if (obj.hasOwnProperty(key)) { 78 if (typeof obj[key] === 'object') { 79 $h.merge(out[key], obj[key]); 80 } else { 81 out[key] = obj[key]; 82 } 83 } 84 } 85 } 86 return out; 87 }, 88 getIndex: function (val, arr) { 89 for (var i = 0; i < arr.length; i++) { 90 if (arr[i].toLowerCase() === val.toLowerCase()) { 91 return i; 92 } 93 } 94 return -1; 95 } 96 }; 97 98 /** 99 * Date Formatter Library Constructor 100 * @param options 101 * @constructor 102 */ 103 DateFormatter = function (options) {
104 var self = this, config = $h.merge($h.defaults, options); 105 self.dateSettings = config.dateSettings; 106 self.separators = config.separators; 107 self.validParts = config.validParts; 108 self.intParts = config.intParts; 109 self.tzParts = config.tzParts; 110 self.tzClip = config.tzClip; 111 }; 112 113 /** 114 * DateFormatter Library Prototype 115 */ 116 DateFormatter.prototype = { 117 constructor: DateFormatter, 118 getMonth: function (val) { 119 var self = this, i; 120 i = $h.getIndex(val, self.dateSettings.monthsShort) + 1; 121 if (i === 0) { 122 i = $h.getIndex(val, self.dateSettings.months) + 1; 123 } 124 return i; 125 }, 126 parseDate: function (vDate, vFormat) { 127 var self = this, vFormatParts, vDateParts, i, vDateFlag = false, vTimeFlag = false, vDatePart, iDatePart, 128 vSettings = self.dateSettings, vMonth, vMeriIndex, vMeriOffset, len, mer, 129 out = {date: null, year: null, month: null, day: null, hour: 0, min: 0, sec: 0}; 130 if (!vDate) { 131 return null; 132 } 133 if (vDate instanceof Date) { 134 return vDate; 135 } 136 if (vFormat === 'U') { 137 i = $h.getInt(vDate); 138 return i ? new Date(i * 1000) : vDate; 139 } 140 switch (typeof vDate) { 141 case 'number': 142 return new Date(vDate); 143 case 'string': 144 break; 145 default: 146 return null; 147 } 148 vFormatParts = vFormat.match(self.validParts); 149 if (!vFormatParts || vFormatParts.length === 0) { 150 throw new Error('Invalid date format definition.'); 151 } 152 for (i = vFormatParts.length - 1; i >= 0; i--) { 153 if (vFormatParts[i] === 'S') { 154 vFormatParts.splice(i, 1); 155 } 156 } 157 vDateParts = vDate.replace(self.separators, '\0').split('\0'); 158 for (i = 0; i < vDateParts.length; i++) { 159 vDatePart = vDateParts[i]; 160 iDatePart = $h.getInt(vDatePart); 161 switch (vFormatParts[i]) { 162 case 'y': 163 case 'Y': 164 if (iDatePart) { 165 len = vDatePart.length; 166 out.year = len === 2 ? $h.getInt((iDatePart < 70 ? '20' : '19') + vDatePart) : iDatePart; 167 } else { 168 return null; 169 } 170 vDateFlag = true; 171 break; 172 case 'm': 173 case 'n': 174 case 'M': 175 case 'F': 176 if (isNaN(iDatePart)) { 177 vMonth = self.getMonth(vDatePart); 178 if (vMonth > 0) { 179 out.month = vMonth; 180 } else { 181 return null; 182 } 183 } else { 184 if (iDatePart >= 1 && iDatePart <= 12) { 185 out.month = iDatePart; 186 } else { 187 return null; 188 } 189 } 190 vDateFlag = true; 191 break; 192 case 'd': 193 case 'j': 194 if (iDatePart >= 1 && iDatePart <= 31) { 195 out.day = iDatePart; 196 } else { 197 return null; 198 } 199 vDateFlag = true; 200 break; 201 case 'g': 202 case 'h': 203 vMeriIndex = (vFormatParts.indexOf('a') > -1) ? vFormatParts.indexOf('a') : 204 ((vFormatParts.indexOf('A') > -1) ? vFormatParts.indexOf('A') : -1); 205 mer = vDateParts[vMeriIndex]; 206 if (vMeriIndex !== -1) { 207 vMeriOffset = $h.compare(mer, vSettings.meridiem[0]) ? 0 : 208 ($h.compare(mer, vSettings.meridiem[1]) ? 12 : -1); 209 if (iDatePart >= 1 && iDatePart <= 12 && vMeriOffset !== -1) { 210 out.hour = iDatePart % 12 === 0 ? vMeriOffset : iD
210atePart + vMeriOffset; 211 } else { 212 if (iDatePart >= 0 && iDatePart <= 23) { 213 out.hour = iDatePart; 214 } 215 } 216 } else { 217 if (iDatePart >= 0 && iDatePart <= 23) { 218 out.hour = iDatePart; 219 } else { 220 return null; 221 } 222 } 223 vTimeFlag = true; 224 break; 225 case 'G': 226 case 'H': 227 if (iDatePart >= 0 && iDatePart <= 23) { 228 out.hour = iDatePart; 229 } else { 230 return null; 231 } 232 vTimeFlag = true; 233 break; 234 case 'i': 235 if (iDatePart >= 0 && iDatePart <= 59) { 236 out.min = iDatePart; 237 } else { 238 return null; 239 } 240 vTimeFlag = true; 241 break; 242 case 's': 243 if (iDatePart >= 0 && iDatePart <= 59) { 244 out.sec = iDatePart; 245 } else { 246 return null; 247 } 248 vTimeFlag = true; 249 break; 250 } 251 } 252 if (vDateFlag === true) { 253 var varY = out.year || 0, varM = out.month ? out.month - 1 : 0, varD = out.day || 1; 254 out.date = new Date(varY, varM, varD, out.hour, out.min, out.sec, 0); 255 } else { 256 if (vTimeFlag !== true) { 257 return null; 258 } 259 out.date = new Date(0, 0, 0, out.hour, out.min, out.sec, 0); 260 } 261 return out.date; 262 }, 263 guessDate: function (vDateStr, vFormat) { 264 if (typeof vDateStr !== 'string') { 265 return vDateStr; 266 } 267 var self = this, vParts = vDateStr.replace(self.separators, '\0').split('\0'), vPattern = /^[djmn]/g, len, 268 vFormatParts = vFormat.match(self.validParts), vDate = new Date(), vDigit = 0, vYear, i, n, iPart, iSec; 269 270 if (!vPattern.test(vFormatParts[0])) { 271 return vDateStr; 272 } 273 274 for (i = 0; i < vParts.length; i++) { 275 vDigit = 2; 276 iPart = vParts[i]; 277 iSec = $h.getInt(iPart.substr(0, 2)); 278 if (isNaN(iSec)) { 279 return null; 280 } 281 switch (i) { 282 case 0: 283 if (vFormatParts[0] === 'm' || vFormatParts[0] === 'n') { 284 vDate.setMonth(iSec - 1); 285 } else { 286 vDate.setDate(iSec); 287 } 288 break; 289 case 1: 290 if (vFormatParts[0] === 'm' || vFormatParts[0] === 'n') { 291 vDate.setDate(iSec); 292 } else { 293 vDate.setMonth(iSec - 1); 294 } 295 break; 296 case 2: 297 vYear = vDate.getFullYear(); 298 len = iPart.length; 299 vDigit = len < 4 ? len : 4; 300 vYear = $h.getInt(len < 4 ? vYear.toString().substr(0, 4 - len) + iPart : iPart.substr(0, 4)); 301 if (!vYear) { 302 return null; 303 } 304 vDate.setFullYear(vYear); 305 break; 306 case 3: 307 vDate.setHours(iSec); 308 break; 309 case 4: 310 vDate.setMinutes(iSec); 311 break; 312 case 5: 313 vDate.setSeconds(iSec); 314 break; 315 } 316 n = iPart.substr(vDigit); 317 if (n.length > 0) { 318 vParts.splice(i + 1, 0, n); 319 } 320 } 321 return vDate; 322 }, 323 parseFormat: function (vChar, vDate) { 324 var self = this, vSettings = self.dateSettings, fmt, backslash = /\\?(.?)/gi, doFormat = function (t, s) { 325 return fmt[t] ? fmt[t]() : s; 326 }; 327 fmt = {
328 ///////// 329 // DAY // 330 ///////// 331 /** 332 * Day of month with leading 0: `01..31` 333 * @return {string} 334 */ 335 d: function () { 336 return $h.lpad(fmt.j(), 2); 337 }, 338 /** 339 * Shorthand day name: `Mon...Sun` 340 * @return {string} 341 */ 342 D: function () { 343 return vSettings.daysShort[fmt.w()]; 344 }, 345 /** 346 * Day of month: `1..31` 347 * @return {number} 348 */ 349 j: function () { 350 return vDate.getDate(); 351 }, 352 /** 353 * Full day name: `Monday...Sunday` 354 * @return {string} 355 */ 356 l: function () { 357 return vSettings.days[fmt.w()]; 358 }, 359 /** 360 * ISO-8601 day of week: `1[Mon]..7[Sun]` 361 * @return {number} 362 */ 363 N: function () { 364 return fmt.w() || 7; 365 }, 366 /** 367 * Day of week: `0[Sun]..6[Sat]` 368 * @return {number} 369 */ 370 w: function () { 371 return vDate.getDay(); 372 }, 373 /** 374 * Day of year: `0..365` 375 * @return {number} 376 */ 377 z: function () { 378 var a = new Date(fmt.Y(), fmt.n() - 1, fmt.j()), b = new Date(fmt.Y(), 0, 1); 379 return Math.round((a - b) / $h.DAY); 380 }, 381
382 ////////// 383 // WEEK // 384 ////////// 385 /** 386 * ISO-8601 week number 387 * @return {number} 388 */ 389 W: function () { 390 var a = new Date(fmt.Y(), fmt.n() - 1, fmt.j() - fmt.N() + 3), b = new Date(a.getFullYear(), 0, 4); 391 return $h.lpad(1 + Math.round((a - b) / $h.DAY / 7), 2); 392 }, 393 394 /////////// 395 // MONTH // 396 /////////// 397 /** 398 * Full month name: `January...December` 399 * @return {string} 400 */ 401 F: function () { 402 return vSettings.months[vDate.getMonth()]; 403 }, 404 /** 405 * Month w/leading 0: `01..12` 406 * @return {string} 407 */ 408 m: function () { 409 return $h.lpad(fmt.n(), 2); 410 }, 411 /** 412 * Shorthand month name; `Jan...Dec` 413 * @return {string} 414 */ 415 M: function () { 416 return vSettings.monthsShort[vDate.getMonth()]; 417 }, 418 /** 419 * Month: `1...12` 420 * @return {number} 421 */ 422 n: function () { 423 return vDate.getMonth() + 1; 424 }, 425 /** 426 * Days in month: `28...31` 427 * @return {number} 428 */ 429 t: function () { 430 return (new Date(fmt.Y(), fmt.n(), 0)).getDate(); 431 }, 432
433 ////////// 434 // YEAR // 435 ////////// 436 /** 437 * Is leap year? `0 or 1` 438 * @return {number} 439 */ 440 L: function () { 441 var Y = fmt.Y(); 442 return (Y % 4 === 0 && Y % 100 !== 0 || Y % 400 === 0) ? 1 : 0; 443 }, 444 /** 445 * ISO-8601 year 446 * @return {number} 447 */ 448 o: function () { 449 var n = fmt.n(), W = fmt.W(), Y = fmt.Y(); 450 return Y + (n === 12 && W < 9 ? 1 : n === 1 && W > 9 ? -1 : 0); 451 }, 452 /** 453 * Full year: `e.g. 1980...2010` 454 * @return {number} 455 */ 456 Y: function () { 457 return vDate.getFullYear(); 458 }, 459 /** 460 * Last two digits of year: `00...99` 461 * @return {string} 462 */ 463 y: function () { 464 return fmt.Y().toString().slice(-2); 465 }, 466
467 ////////// 468 // TIME // 469 ////////// 470 /** 471 * Meridian lower: `am or pm` 472 * @return {string} 473 */ 474 a: function () { 475 return fmt.A().toLowerCase(); 476 }, 477 /** 478 * Meridian upper: `AM or PM` 479 * @return {string} 480 */ 481 A: function () { 482 var n = fmt.G() < 12 ? 0 : 1; 483 return vSettings.meridiem[n]; 484 }, 485 /** 486 * Swatch Internet time: `000..999` 487 * @return {string} 488 */ 489 B: function () { 490 var H = vDate.getUTCHours() * $h.HOUR, i = vDate.getUTCMinutes() * 60, s = vDate.getUTCSeconds(); 491 return $h.lpad(Math.floor((H + i + s + $h.HOUR) / 86.4) % 1000, 3); 492 }, 493 /** 494 * 12-Hours: `1..12` 495 * @return {number} 496 */ 497 g: function () { 498 return fmt.G() % 12 || 12; 499 }, 500 /** 501 * 24-Hours: `0..23` 502 * @return {number} 503 */ 504 G: function () { 505 return vDate.getHours(); 506 }, 507 /** 508 * 12-Hours with leading 0: `01..12` 509 * @return {string} 510 */ 511 h: function () { 512 return $h.lpad(fmt.g(), 2); 513 }, 514 /** 515 * 24-Hours w/leading 0: `00..23` 516 * @return {string} 517 */ 518 H: function () { 519 return $h.lpad(fmt.G(), 2); 520 }, 521 /** 522 * Minutes w/leading 0: `00..59` 523 * @return {string} 524 */ 525 i: function () { 526 return $h.lpad(vDate.getMinutes(), 2); 527 }, 528 /** 529 * Seconds w/leading 0: `00..59` 530 * @return {string} 531 */ 532 s: function () { 533 return $h.lpad(vDate.getSeconds(), 2); 534 }, 535 /** 536 * Microseconds: `000000-999000` 537 * @return {string} 538 */ 539 u: function () { 540 return $h.lpad(vDate.getMilliseconds() * 1000, 6); 541 }, 542
543 ////////////// 544 // TIMEZONE // 545 ////////////// 546 /** 547 * Timezone identifier: `e.g. Atlantic/Azores, ...` 548 * @return {string} 549 */ 550 e: function () { 551 var str = /\((.*)\)/.exec(String(vDate))[1]; 552 return str || 'Coordinated Universal Time'; 553 }, 554 /** 555 * DST observed? `0 or 1` 556 * @return {number} 557 */ 558 I: function () { 559 var a = new Date(fmt.Y(), 0), c = Date.UTC(fmt.Y(), 0), 560 b = new Date(fmt.Y(), 6), d = Date.UTC(fmt.Y(), 6); 561 return ((a - c) !== (b - d)) ? 1 : 0; 562 }, 563 /** 564 * Difference to GMT in hour format: `e.g. +0200` 565 * @return {string} 566 */ 567 O: function () { 568 var tzo = vDate.getTimezoneOffset(), a = Math.abs(tzo); 569 return (tzo > 0 ? '-' : '+') + $h.lpad(Math.floor(a / 60) * 100 + a % 60, 4); 570 }, 571 /** 572 * Difference to GMT with colon: `e.g. +02:00` 573 * @return {string} 574 */ 575 P: function () { 576 var O = fmt.O(); 577 return (O.substr(0, 3) + ':' + O.substr(3, 2)); 578 }, 579 /** 580 * Timezone abbreviation: `e.g. EST, MDT, ...` 581 * @return {string} 582 */ 583 T: function () { 584 var str = (String(vDate).match(self.tzParts) || ['']).pop().replace(self.tzClip, ''); 585 return str || 'UTC'; 586 }, 587 /** 588 * Timezone offset in seconds: `-43200...50400` 589 * @return {number} 590 */ 591 Z: function () { 592 return -vDate.getTimezoneOffset() * 60; 593 }, 594
595 //////////////////// 596 // FULL DATE TIME // 597 //////////////////// 598 /** 599 * ISO-8601 date 600 * @return {string} 601 */ 602 c: function () { 603 return 'Y-m-d\\TH:i:sP'.replace(backslash, doFormat); 604 }, 605 /** 606 * RFC 2822 date 607 * @return {string} 608 */ 609 r: function () { 610 return 'D, d M Y H:i:s O'.replace(backslash, doFormat); 611 }, 612 /** 613 * Seconds since UNIX epoch 614 * @return {number} 615 */ 616 U: function () { 617 return vDate.getTime() / 1000 || 0; 618 } 619 }; 620 return doFormat(vChar, vChar); 621 }, 622 formatDate: function (vDate, vFormat) { 623 var self = this, i, n, len, str, vChar, vDateStr = '', BACKSLASH = '\\'; 624 if (typeof vDate === 'string') { 625 vDate = self.parseDate(vDate, vFormat); 626 if (!vDate) { 627 return null; 628 } 629 } 630 if (vDate instanceof Date) { 631 len = vFormat.length; 632 for (i = 0; i < len; i++) { 633 vChar = vFormat.charAt(i); 634 if (vChar === 'S' || vChar === BACKSLASH) { 635 continue; 636 } 637 if (i > 0 && vFormat.charAt(i - 1) === BACKSLASH) { 638 vDateStr += vChar; 639 continue; 640 } 641 str = self.parseFormat(vChar, vDate); 642 if (i !== (len - 1) && self.intParts.test(vChar) && vFormat.charAt(i + 1) === 'S') { 643 n = $h.getInt(str) || 0; 644 str += self.dateSettings.ordinal(n); 645 } 646 vDateStr += str; 647 } 648 return vDateStr; 649 } 650 return ''; 651 } 652 }; 653 Object.freeze(DateFormatter); 654 return DateFormatter; 655}));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.