1;(function(window) 2{ 3 /****************** ATTENTION ******************************* 4 * Please do not use Bitrix CoreJS in this class. 5 * This class can be called on page without Bitrix Framework 6 *************************************************************/ 7 8 if (!window.BX) 9 { 10 window.BX = {}; 11 } 12 13 if (!window.BX.Main) 14 { 15 window.BX.Main = {}; 16 } 17 else if (window.BX.Main.Date) 18 { 19 return; 20 } 21 22 var BX = window.BX; 23 24 BX.Main.Date = { 25 26 AM_PM_MODE: { 27 UPPER: 1, 28 LOWER: 2, 29 NONE: false 30 }, 31 32 format: function(format, timestamp, now, utc) 33 { 34 var _this = this; 35 36 /* 37 PHP to Javascript: 38 time() = new Date() 39 mktime(...) = new Date(...) 40 gmmktime(...) = new Date(Date.UTC(...)) 41 mktime(0,0,0, 1, 1, 1970) != 0 new Date(1970,0,1).getTime() != 0 42 gmmktime(0,0,0, 1, 1, 1970) == 0 new Date(Date.UTC(1970,0,1)).getTime() == 0 43 date("d.m.Y H:i:s") = BX.Main.Date.format("d.m.Y H:i:s") 44 gmdate("d.m.Y H:i:s") = BX.Main.Date.format("d.m.Y H:i:s", null, null, true); 45 */ 46 var date = Utils.isDate(timestamp) ? new Date(timestamp.getTime()) : Utils.isNumber(timestamp) ? new Date(timestamp * 1000) : new Date(); 47 var nowDate = Utils.isDate(now) ? new Date(now.getTime()) : Utils.isNumber(now) ? new Date(now * 1000) : new Date(); 48 var isUTC = !!utc; 49 50 if (Utils.isArray(format)) 51 return _formatDateInterval(format, date, nowDate, isUTC); 52 else if (!Utils.isNotEmptyString(format)) 53 return ""; 54 55 var replaceMap = (format.match(/{{([^{}]*)}}/g) || []).map(function(x) { return (x.match(/[^{}]+/) || [''])[0]; }); 56 if (replaceMap.length > 0) 57 { 58 replaceMap.forEach(function(element, index) { 59 format = format.replace("{{"+element+"}}", "{{"+index+"}}"); 60 }); 61 } 62 63 var formatRegex = /\\?(sago|iago|isago|Hago|dago|mago|Yago|sdiff|idiff|Hdiff|ddiff|mdiff|Ydiff|sshort|ishort|Hshort|dshort|mhort|Yshort|yesterday|today|tommorow|tomorrow|[a-z])/gi; 64 65 var dateFormats = { 66 d : function() { 67 // Day of the month 01 to 31 68 return Utils.strPadLeft(getDate(date).toString(), 2, "0"); 69 }, 70 71 D : function() { 72 //Mon through Sun 73 return _this._getMessage("DOW_" + getDay(date)); 74 }, 75 76 j : function() { 77 //Day of the month 1 to 31 78 return getDate(date); 79 }, 80 81 l : function() { 82 //Sunday through Saturday 83 return _this._getMessage("DAY_OF_WEEK_" + getDay(date)); 84 }, 85 86 N : function() { 87 //1 (for Monday) through 7 (for Sunday) 88 return getDay(date) || 7; 89 }, 90 91 S : function() { 92 //st, nd, rd or th. Works well with j 93 if (getDate(date) % 10 == 1 && getDate(date) != 11) 94 return "st"; 95 else if (getDate(date) % 10 == 2 && getDate(date) != 12) 96 return "nd"; 97 else if (getDate(date) % 10 == 3 && getDate(date) != 13) 98 return "rd"; 99 else 100 return "th"; 101 }, 102 103 w : function() { 104 //0 (for Sunday) through 6 (for Saturday) 105 return getDay(date); 106 }, 107 108 z : function() { 109 //0 through 365 110 var firstDay = new Date(getFullYear(date), 0, 1); 111 var currentDay = new Date(getFullYear(date), getMonth(date), getDate(date)); 112 return Math.ceil( (currentDay - firstDay) / (24 * 3600 * 1000) ); 113 }, 114 115 W : function() { 116 //ISO-8601 week number of year 117 var newDate = new Date(date.getTime()); 118 var dayNumber = (getDay(date) + 6) % 7; 119 setDate(newDate, getDate(newDate) - dayNumber + 3); 120 var firstThursday = newDate.getTime(); 121 setMonth(newDate, 0, 1); 122 if (getDay(newDate) != 4) 123 setMonth(newDate, 0, 1 + ((4 - getDay(newDate)) + 7) % 7); 124 var weekNumber = 1 + Math.ceil((firstThursday - newDate) / (7 * 24 * 3600 * 1000)); 125 return Utils.strPadLeft(weekNumber.toString(), 2, "0"); 126 }, 127 128 F : function() { 129 //January through December 130 return _this._getMessage("MONTH_" + (getMonth(date) + 1) + "_S"); 131 }, 132 133 f : function() { 134 //January through December 135 return _this._getMessage("MONTH_" + (getMonth(date) + 1)); 136 }, 137 138 m : function() { 139 //Numeric representation of a month 01 through 12 140 return Utils.strPadLeft((getMonth(date) + 1).toString(), 2, "0"); 141 }, 142 143 M : function() { 144 //A short textual representation of a month, three letters Jan through Dec 145 return _this._getMessage("MON_" + (getMonth(date) + 1)); 146 }, 147 148 n : function() { 149 //Numeric representation of a month 1 through 12 150 return getMonth(date) + 1; 151 }, 152 153 t : function() { 154 //Number of days in the given month 28 through 31 155 var lastMonthDay = isUTC ? new Date(Date.UTC(getFullYear(date), getMonth(date) + 1, 0)) : new Date(getFullYear(date), getMonth(date) + 1, 0); 156 return getDate(lastMonthDay); 157 }, 158 159 L : function() { 160 //1 if it is a leap year, 0 otherwise. 161 var year = getFullYear(date); 162 return (year % 4 == 0 && year % 100 != 0 || year % 400 == 0 ? 1 : 0); 163 }, 164 165 o : function() { 166 //ISO-8601 year number 167 var correctDate = new Date(date.getTime()); 168 setDate(correctDate, getDate(correctDate) - ((getDay(date) + 6) % 7) + 3); 169 return getFullYear(correctDate); 170 }, 171 172 Y : function() { 173 //A full numeric representation of a year, 4 digits 174 return getFullYear(date); 175 }, 176 177 y : function() { 178 //A two digit representation of a year 179 return getFullYear(date).toString().slice(2); 180 }, 181 182 a : function() { 183 //am or pm 184 return getHours(date) > 11 ? "pm" : "am"; 185 }, 186 187 A : function() { 188 //AM or PM 189 return getHours(date) > 11 ? "PM" : "AM"; 190 }, 191 192 B : function() { 193 //000 through 999 194 var swatch = ((date.getUTCHours() + 1) % 24) + date.getUTCMinutes() / 60 + date.getUTCSeconds() / 3600; 195 return Utils.strPadLeft(Math.floor(swatch * 1000 / 24).toString(), 3, "0"); 196 }, 197 198 g : function() { 199 //12-hour format of an hour without leading zeros 1 through 12 200 return getHours(date) % 12 || 12; 201 }, 202 203 G : function() { 204 //24-hour format of an hour without leading zeros 0 through 23 205 return getHours(date); 206 }, 207 208 h : function() { 209 //12-hour format of an hour with leading zeros 01 through 12 210 return Utils.strPadLeft((getHours(date) % 12 || 12).toString(), 2, "0"); 211 }, 212 213 H : function() { 214 //24-hour format of an hour with leading zeros 00 through 23 215 return Utils.strPadLeft(getHours(date).toString(), 2, "0"); 216 }, 217 218 i : function() { 219 //Minutes with leading zeros 00 to 59 220 return Utils.strPadLeft(getMinutes(date).toString(), 2, "0"); 221 }, 222 223 s : function() { 224 //Seconds, with leading zeros 00 through 59 225 return Utils.strPadLeft(getSeconds(date).toString(), 2, "0"); 226 }, 227 228 u : function() { 229 //Microseconds 230 return Utils.strPadLeft((getMilliseconds(date) * 1000).toString(), 6, "0"); 231 }, 232 233 e : function() { 234 if (isUTC) 235 return "UTC"; 236 return ""; 237 }, 238 239 I : function() { 240 if (isUTC) 241 return 0; 242 243 //Whether or not the date is in daylight saving time 1 if Daylight Saving Time, 0 otherwise 244 var firstJanuary = new Date(getFullYear(date), 0, 1); 245 var firstJanuaryUTC = Date.UTC(getFullYear(date), 0, 1); 246 var firstJuly = new Date(getFullYear(date), 6, 0); 247 var firstJulyUTC = Date.UTC(getFullYear(date), 6, 0); 248 return 0 + ((firstJanuary - firstJanuaryUTC) !== (firstJuly - firstJulyUTC)); 249 }, 250 251 O : function() { 252 if (isUTC) 253 return "+0000"; 254 255 //Difference to Greenwich time (GMT) in hours +0200 256 var timezoneOffset = date.getTimezoneOffset(); 257 var timezoneOffsetAbs = Math.abs(timezoneOffset); 258 return (timezoneOffset > 0 ? "-" : "+") + Utils.strPadLeft((Math.floor(timezoneOffsetAbs / 60) * 100 + timezoneOffsetAbs % 60).toString(), 4, "0"); 259 }, 260 261 P : function() { 262 if (isUTC) 263 return "+00:00"; 264 265 //Difference to Greenwich time (GMT) with colon between hours and minutes +02:00 266 var difference = this.O(); 267 return difference.substr(0, 3) + ":" + difference.substr(3); 268 }, 269 270 Z : function() { 271 if (isUTC) 272 return 0; 273 //Timezone offset in seconds. The offset for timezones west of UTC is always negative, 274 //and for those east of UTC is always positive. 275 return -date.getTimezoneOffset() * 60; 276 }, 277 278 c : function() { 279 //ISO 8601 date 280 return "Y-m-d\\TH:i:sP".replace(formatRegex, _replaceDateFormat); 281 }, 282 283 r : function() { 284 //RFC 2822 formatted date 285 return "D, d M Y H:i:s O".replace(formatRegex, _replaceDateFormat); 286 }, 287 288 U : function() { 289 //Seconds since the Unix Epoch 290 return Math.floor(date.getTime() / 1000); 291 }, 292 293 sago : function() { 294 return _formatDateMessage(intval((nowDate - date) / 1000), { 295 "0" : "FD_SECOND_AGO_0", 296 "1" : "FD_SECOND_AGO_1", 297 "10_20" : "FD_SECOND_AGO_10_20", 298 "MOD_1" : "FD_SECOND_AGO_MOD_1", 299 "MOD_2_4" : "FD_SECOND_AGO_MOD_2_4", 300 "MOD_OTHER" : "FD_SECOND_AGO_MOD_OTHER" 301 }); 302 }, 303 304 sdiff : function() { 305 return _formatDateMessage(intval((nowDate - date) / 1000), { 306 "0" : "FD_SECOND_DIFF_0", 307 "1" : "FD_SECOND_DIFF_1", 308 "10_20" : "FD_SECOND_DIFF_10_20", 309 "MOD_1" : "FD_SECOND_DIFF_MOD_1", 310 "MOD_2_4" : "FD_SECOND_DIFF_MOD_2_4", 311 "MOD_OTHER" : "FD_SECOND_DIFF_MOD_OTHER" 312 }); 313 }, 314 315 sshort : function() { 316 return _this._getMessage("FD_SECOND_SHORT").replace(/#VALUE#/g, intval((nowDate - date) / 1000)); 317 }, 318 319 iago : function() { 320 return _formatDateMessage(intval((nowDate - date) / 60 / 1000), { 321 "0" : "FD_MINUTE_AGO_0", 322 "1" : "FD_MINUTE_AGO_1", 323 "10_20" : "FD_MINUTE_AGO_10_20", 324 "MOD_1" : "FD_MINUTE_AGO_MOD_1", 325 "MOD_2_4" : "FD_MINUTE_AGO_MOD_2_4", 326 "MOD_OTHER" : "FD_MINUTE_AGO_MOD_OTHER" 327 }); 328 }, 329 330 idiff : function() { 331 return _formatDateMessage(intval((nowDate - date) / 60 / 1000), { 332 "0" : "FD_MINUTE_DIFF_0", 333 "1" : "FD_MINUTE_DIFF_1", 334 "10_20" : "FD_MINUTE_DIFF_10_20", 335 "MOD_1" : "FD_MINUTE_DIFF_MOD_1", 336 "MOD_2_4" : "FD_MINUTE_DIFF_MOD_2_4", 337 "MOD_OTHER" : "FD_MINUTE_DIFF_MOD_OTHER" 338 }); 339 }, 340 341 isago : function() { 342 var minutesAgo = intval((nowDate - date) / 60 / 1000); 343 var result = _formatDateMessage(minutesAgo, { 344 "0" : "FD_MINUTE_0", 345 "1" : "FD_MINUTE_1", 346 "10_20" : "FD_MINUTE_10_20", 347 "MOD_1" : "FD_MINUTE_MOD_1", 348 "MOD_2_4" : "FD_MINUTE_MOD_2_4", 349 "MOD_OTHER" : "FD_MINUTE_MOD_OTHER" 350 }); 351 352 result += " ";
353 354 var secondsAgo = intval((nowDate - date) / 1000) - (minutesAgo * 60); 355 result += _formatDateMessage(secondsAgo, { 356 "0" : "FD_SECOND_AGO_0", 357 "1" : "FD_SECOND_AGO_1", 358 "10_20" : "FD_SECOND_AGO_10_20", 359 "MOD_1" : "FD_SECOND_AGO_MOD_1", 360 "MOD_2_4" : "FD_SECOND_AGO_MOD_2_4", 361 "MOD_OTHER" : "FD_SECOND_AGO_MOD_OTHER" 362 }); 363 return result; 364 }, 365 366 ishort : function() { 367 return _this._getMessage("FD_MINUTE_SHORT").replace(/#VALUE#/g, intval((nowDate - date) / 60 / 1000)); 368 }, 369 370 Hago : function() { 371 return _formatDateMessage(intval((nowDate - date) / 60 / 60 / 1000), { 372 "0" : "FD_HOUR_AGO_0", 373 "1" : "FD_HOUR_AGO_1", 374 "10_20" : "FD_HOUR_AGO_10_20", 375 "MOD_1" : "FD_HOUR_AGO_MOD_1", 376 "MOD_2_4" : "FD_HOUR_AGO_MOD_2_4", 377 "MOD_OTHER" : "FD_HOUR_AGO_MOD_OTHER" 378 }); 379 }, 380 381 Hdiff : function() { 382 return _formatDateMessage(intval((nowDate - date) / 60 / 60 / 1000), { 383 "0" : "FD_HOUR_DIFF_0", 384 "1" : "FD_HOUR_DIFF_1", 385 "10_20" : "FD_HOUR_DIFF_10_20", 386 "MOD_1" : "FD_HOUR_DIFF_MOD_1", 387 "MOD_2_4" : "FD_HOUR_DIFF_MOD_2_4", 388 "MOD_OTHER" : "FD_HOUR_DIFF_MOD_OTHER" 389 }); 390 }, 391 392 Hshort : function() { 393 return _this._getMessage("FD_HOUR_SHORT").replace(/#VALUE#/g, intval((nowDate - date) / 60 / 60 / 1000)); 394 }, 395 396 yesterday : function() { 397 return _this._getMessage("FD_YESTERDAY"); 398 }, 399 400 today : function() { 401 return _this._getMessage("FD_TODAY"); 402 }, 403 404 tommorow : function() { 405 return _this._getMessage("FD_TOMORROW"); 406 }, 407 408 tomorrow : function() { 409 return _this._getMessage("FD_TOMORROW"); 410 }, 411 412 dago : function() { 413 return _formatDateMessage(intval((nowDate - date) / 60 / 60 / 24 / 1000), { 414 "0" : "FD_DAY_AGO_0", 415 "1" : "FD_DAY_AGO_1", 416 "10_20" : "FD_DAY_AGO_10_20", 417 "MOD_1" : "FD_DAY_AGO_MOD_1", 418 "MOD_2_4" : "FD_DAY_AGO_MOD_2_4", 419 "MOD_OTHER" : "FD_DAY_AGO_MOD_OTHER" 420 }); 421 }, 422 423 ddiff : function() { 424 return _formatDateMessage(intval((nowDate - date) / 60 / 60 / 24 / 1000), { 425 "0" : "FD_DAY_DIFF_0", 426 "1" : "FD_DAY_DIFF_1", 427 "10_20" : "FD_DAY_DIFF_10_20", 428 "MOD_1" : "FD_DAY_DIFF_MOD_1", 429 "MOD_2_4" : "FD_DAY_DIFF_MOD_2_4", 430 "MOD_OTHER" : "FD_DAY_DIFF_MOD_OTHER" 431 }); 432 }, 433 434 dshort : function() { 435 return _this._getMessage("FD_DAY_SHORT").replace(/#VALUE#/g, intval((nowDate - date) / 60 / 60 / 24 / 1000)); 436 }, 437 438 mago : function() { 439 return _formatDateMessage(intval((nowDate - date) / 60 / 60 / 24 / 31 / 1000), { 440 "0" : "FD_MONTH_AGO_0", 441 "1" : "FD_MONTH_AGO_1", 442 "10_20" : "FD_MONTH_AGO_10_20", 443 "MOD_1" : "FD_MONTH_AGO_MOD_1", 444 "MOD_2_4" : "FD_MONTH_AGO_MOD_2_4", 445 "MOD_OTHER" : "FD_MONTH_AGO_MOD_OTHER" 446 }); 447 }, 448 449 mdiff : function() { 450 return _formatDateMessage(intval((nowDate - date) / 60 / 60 / 24 / 31 / 1000), { 451 "0" : "FD_MONTH_DIFF_0", 452 "1" : "FD_MONTH_DIFF_1", 453 "10_20" : "FD_MONTH_DIFF_10_20", 454 "MOD_1" : "FD_MONTH_DIFF_MOD_1", 455 "MOD_2_4" : "FD_MONTH_DIFF_MOD_2_4", 456 "MOD_OTHER" : "FD_MONTH_DIFF_MOD_OTHER" 457 }); 458 }, 459 460 mshort : function() { 461 return _this._getMessage("FD_MONTH_SHORT").replace(/#VALUE#/g, intval((nowDate - date) / 60 / 60 / 24 / 31 / 1000)); 462 }, 463 464 Yago : function() { 465 return _formatDateMessage(intval((nowDate - date) / 60 / 60 / 24 / 365 / 1000), { 466 "0" : "FD_YEARS_AGO_0", 467 "1" : "FD_YEARS_AGO_1", 468 "10_20" : "FD_YEARS_AGO_10_20", 469 "MOD_1" : "FD_YEARS_AGO_MOD_1", 470 "MOD_2_4" : "FD_YEARS_AGO_MOD_2_4", 471 "MOD_OTHER" : "FD_YEARS_AGO_MOD_OTHER" 472 }); 473 }, 474 475 Ydiff : function() { 476 return _formatDateMessage(intval((nowDate - date) / 60 / 60 / 24 / 365 / 1000), { 477 "0" : "FD_YEARS_DIFF_0", 478 "1" : "FD_YEARS_DIFF_1", 479 "10_20" : "FD_YEARS_DIFF_10_20", 480 "MOD_1" : "FD_YEARS_DIFF_MOD_1", 481 "MOD_2_4" : "FD_YEARS_DIFF_MOD_2_4", 482 "MOD_OTHER" : "FD_YEARS_DIFF_MOD_OTHER" 483 }); 484 }, 485 486 Yshort : function() { 487 return _formatDateMessage(intval((nowDate - date) / 60 / 60 / 24 / 365 / 1000), { 488 "0" : "FD_YEARS_SHORT_0", 489 "1" : "FD_YEARS_SHORT_1", 490 "10_20" : "FD_YEARS_SHORT_10_20", 491 "MOD_1" : "FD_YEARS_SHORT_MOD_1", 492 "MOD_2_4" : "FD_YEARS_SHORT_MOD_2_4", 493 "MOD_OTHER" : "FD_YEARS_SHORT_MOD_OTHER" 494 }); 495 }, 496 497 x : function() { 498 var ampm = _this.isAmPmMode(true); 499 var timeFormat = (ampm === _this.AM_PM_MODE.LOWER? "g:i a" : (ampm === _this.AM_PM_MODE.UPPER? "g:i A" : "H:i")); 500 501 return _this.format([ 502 ["tomorrow", "tomorrow, "+timeFormat], 503 ["-", _this.convertBitrixFormat(_this._getMessage("FORMAT_DATETIME")).replace(/:s/g, "")], 504 ["s", "sago"], 505 ["i", "iago"], 506 ["today", "today, "+timeFormat], 507 ["yesterday", "yesterday, "+timeFormat], 508 ["", _this.convertBitrixFormat(_this._getMessage("FORMAT_DATETIME")).replace(/:s/g, "")] 509 ], date, nowDate, isUTC); 510 }, 511 512 X : function() { 513 514 var ampm = _this.isAmPmMode(true); 515 var timeFormat = (ampm === _this.AM_PM_MODE.LOWER? "g:i a" : (ampm === _this.AM_PM_MODE.UPPER? "g:i A" : "H:i")); 516 517 var day = _this.format([ 518 ["tomorrow", "tomorrow"], 519 ["-", _this.convertBitrixFormat(_this._getMessage("FORMAT_DATE"))], 520 ["today", "today"], 521 ["yesterday", "yesterday"], 522 ["", _this.convertBitrixFormat(_this._getMessage("FORMAT_DATE"))] 523 ], date, nowDate, isUTC); 524 525 var time = _this.format([ 526 ["tomorrow", timeFormat], 527 ["today", timeFormat], 528 ["yesterday", timeFormat], 529 ["", ""] 530 ], date, nowDate, isUTC); 531 532 if (time.length > 0) 533 return _this._getMessage("FD_DAY_AT_TIME").replace(/#DAY#/g, day).replace(/#TIME#/g, time); 534 else 535 return day; 536 }, 537 538 Q : function() { 539 var daysAgo = intval((nowDate - date) / 60 / 60 / 24 / 1000); 540 if(daysAgo == 0) 541 return _this._getMessage("FD_DAY_DIFF_1").replace(/#VALUE#/g, 1); 542 else 543 return _this.format([ ["d", "ddiff"], ["m", "mdiff"], ["", "Ydiff"] ], date, nowDate); 544 } 545 }; 546 547 var cutZeroTime = false;
548 if (format[0] && format[0] == "^") 549 { 550 cutZeroTime = true; 551 format = format.substr(1); 552 } 553 554 var result = format.replace(formatRegex, _replaceDateFormat); 555 556 if (cutZeroTime) 557 { 558 /* 15.04.12 13:00:00 => 15.04.12 13:00 559 00:01:00 => 00:01 560 4 may 00:00:00 => 4 may 561 01-01-12 00:00 => 01-01-12 562 */ 563 564 result = result.replace(/\s*00:00:00\s*/g, ""). 565 replace(/(\d\d:\d\d)(:00)/g, "$1"). 566 replace(/(\s*00:00\s*)(?!:)/g, ""); 567 } 568 569 if (replaceMap.length > 0) 570 { 571 replaceMap.forEach(function(element, index) { 572 result = result.replace("{{"+index+"}}", element); 573 }); 574 } 575 576 return result; 577 578 function _formatDateInterval(formats, date, nowDate, isUTC) 579 { 580 var secondsAgo = intval((nowDate - date) / 1000); 581 for (var i = 0; i < formats.length; i++) 582 { 583 var formatInterval = formats[i][0]; 584 var formatValue = formats[i][1]; 585 var match = null; 586 if (formatInterval == "s") 587 { 588 if (secondsAgo < 60) 589 return _this.format(formatValue, date, nowDate, isUTC); 590 } 591 else if ((match = /^s(\d+)\>?(\d+)?/.exec(formatInterval)) != null) 592 { 593 if (match[1] && match[2]) 594 { 595 if ( 596 secondsAgo < match[1] 597 && secondsAgo > match[2] 598 ) 599 { 600 return _this.format(formatValue, date, nowDate, isUTC); 601 } 602 } 603 else if (secondsAgo < match[1]) 604 { 605 return _this.format(formatValue, date, nowDate, isUTC); 606 } 607 } 608 else if (formatInterval == "i") 609 { 610 if (secondsAgo < 60 * 60) 611 return _this.format(formatValue, date, nowDate, isUTC); 612 } 613 else if ((match = /^i(\d+)\>?(\d+)?/.exec(formatInterval)) != null) 614 { 615 if (match[1] && match[2]) 616 { 617 if ( 618 secondsAgo < match[1] * 60 619 && secondsAgo > match[2] * 60 620 ) 621 { 622 return _this.format(formatValue, date, nowDate, isUTC); 623 } 624 } 625 else if (secondsAgo < match[1] * 60) 626 { 627 return _this.format(formatValue, date, nowDate, isUTC); 628 } 629 } 630 else if (formatInterval == "H") 631 { 632 if (secondsAgo < 24 * 60 * 60) 633 return _this.format(formatValue, date, nowDate, isUTC); 634 } 635 else if ((match = /^H(\d+)\>?(\d+)?/.exec(formatInterval)) != null) 636 { 637 if (match[1] && match[2]) 638 { 639 if ( 640 secondsAgo < match[1] * 60 * 60 641 && secondsAgo > match[2] * 60 * 60 642 ) 643 { 644 return _this.format(formatValue, date, nowDate, isUTC); 645 } 646 } 647 else if (secondsAgo < match[1] * 60 * 60) 648 { 649 return _this.format(formatValue, date, nowDate, isUTC); 650 } 651 } 652 else if (formatInterval == "d") 653 { 654 if (secondsAgo < 31 *24 * 60 * 60) 655 return _this.format(formatValue, date, nowDate, isUTC); 656 } 657 else if ((match = /^d(\d+)\>?(\d+)?/.exec(formatInterval)) != null) 658 { 659 if (match[1] && match[2]) 660 { 661 if ( 662 secondsAgo < match[1] * 24 * 60 * 60 663 && secondsAgo > match[2] * 24 * 60 * 60 664 ) 665 { 666 return _this.format(formatValue, date, nowDate, isUTC); 667 } 668 } 669 else if (secondsAgo < match[1] * 24 * 60 * 60) 670 { 671 return _this.format(formatValue, date, nowDate, isUTC); 672 } 673 } 674 else if (formatInterval == "m") 675 { 676 if (secondsAgo < 365 * 24 * 60 * 60) 677 return _this.format(formatValue, date, nowDate, isUTC); 678 } 679 else if ((match = /^m(\d+)\>?(\d+)?/.exec(formatInterval)) != null) 680 { 681 if (match[1] && match[2]) 682 { 683 if ( 684 secondsAgo < match[1] * 31 * 24 * 60 * 60 685 && secondsAgo > match[2] * 31 * 24 * 60 * 60 686 ) 687 { 688 return _this.format(formatValue, date, nowDate, isUTC); 689 } 690 } 691 else if (secondsAgo < match[1] * 31 * 24 * 60 * 60) 692 { 693 return _this.format(formatValue, date, nowDate, isUTC); 694 } 695 } 696 else if (formatInterval == "now") 697 { 698 if (date.getTime() == nowDate.getTime()) 699 { 700 return _this.format(formatValue, date, nowDate, isUTC); 701 } 702 } 703 else if (formatInterval == "today") 704 {
705 var year = getFullYear(nowDate), month = getMonth(nowDate), day = getDate(nowDate); 706 var todayStart = isUTC ? new Date(Date.UTC(year, month, day, 0, 0, 0, 0)) : new Date(year, month, day, 0, 0, 0, 0); 707 var todayEnd = isUTC ? new Date(Date.UTC(year, month, day+1, 0, 0, 0, 0)) : new Date(year, month, day+1, 0, 0, 0, 0); 708 if (date >= todayStart && date < todayEnd) 709 return _this.format(formatValue, date, nowDate, isUTC); 710 } 711 else if (formatInterval == "todayFuture") 712 { 713 var year = getFullYear(nowDate), month = getMonth(nowDate), day = getDate(nowDate); 714 var todayStart = nowDate.getTime(); 715 var todayEnd = isUTC ? new Date(Date.UTC(year, month, day+1, 0, 0, 0, 0)) : new Date(year, month, day+1, 0, 0, 0, 0); 716 if (date >= todayStart && date < todayEnd) 717 return _this.format(formatValue, date, nowDate, isUTC); 718 } 719 else if (formatInterval == "yesterday") 720 { 721 year = getFullYear(nowDate); month = getMonth(nowDate); day = getDate(nowDate); 722 var yesterdayStart = isUTC ? new Date(Date.UTC(year, month, day-1, 0, 0, 0, 0)) : new Date(year, month, day-1, 0, 0, 0, 0); 723 var yesterdayEnd = isUTC ? new Date(Date.UTC(year, month, day, 0, 0, 0, 0)) : new Date(year, month, day, 0, 0, 0, 0); 724 if (date >= yesterdayStart && date < yesterdayEnd) 725 return _this.format(formatValue, date, nowDate, isUTC); 726 } 727 else if (formatInterval == "tommorow" || formatInterval == "tomorrow") 728 { 729 year = getFullYear(nowDate); month = getMonth(nowDate); day = getDate(nowDate); 730 var tomorrowStart = isUTC ? new Date(Date.UTC(year, month, day+1, 0, 0, 0, 0)) : new Date(year, month, day+1, 0, 0, 0, 0); 731 var tomorrowEnd = isUTC ? new Date(Date.UTC(year, month, day+2, 0, 0, 0, 0)) : new Date(year, month, day+2, 0, 0, 0, 0); 732 if (date >= tomorrowStart && date < tomorrowEnd) 733 return _this.format(formatValue, date, nowDate, isUTC); 734 } 735 else if (formatInterval == "-") 736 { 737 if (secondsAgo < 0) 738 return _this.format(formatValue, date, nowDate, isUTC); 739 } 740 } 741 742 //return formats.length > 0 ? _this.format(formats.pop()[1], date, nowDate, isUTC) : ""; 743 return formats.length > 0 ? _this.format(formats[formats.length - 1][1], date, nowDate, isUTC) : ""; 744 } 745 746 function getFullYear(date) { return isUTC ? date.getUTCFullYear() : date.getFullYear(); } 747 function getDate(date) { return isUTC ? date.getUTCDate() : date.getDate(); } 748 function getMonth(date) { return isUTC ? date.getUTCMonth() : date.getMonth(); } 749 function getHours(date) { return isUTC ? date.getUTCHours() : date.getHours(); } 750 function getMinutes(date) { return isUTC ? date.getUTCMinutes() : date.getMinutes(); } 751 function getSeconds(date) { return isUTC ? date.getUTCSeconds() : date.getSeconds(); } 752 function getMilliseconds(date) { return isUTC ? date.getUTCMilliseconds() : date.getMilliseconds(); } 753 function getDay(date) { return isUTC ? date.getUTCDay() : date.getDay(); } 754 function setDate(date, dayValue) { return isUTC ? date.setUTCDate(dayValue) : date.setDate(dayValue); } 755 function setMonth(date, monthValue, dayValue) { return isUTC ? date.setUTCMonth(monthValue, dayValue) : date.setMonth(monthValue, dayValue); } 756 757 function _formatDateMessage(value, messages) 758 { 759 var val = value < 100 ? Math.abs(value) : Math.abs(value % 100); 760 var dec = val % 10; 761 var message = ""; 762 763 if(val == 0) 764 message = _this._getMessage(messages["0"]); 765 else if (val == 1) 766 message = _this._getMessage(messages["1"]); 767 else if (val >= 10 && val <= 20) 768 message = _this._getMessage(messages["10_20"]); 769 else if (dec == 1) 770 message = _this._getMessage(messages["MOD_1"]); 771 else if (2 <= dec && dec <= 4) 772 message = _this._getMessage(messages["MOD_2_4"]); 773 else 774 message = _this._getMessage(messages["MOD_OTHER"]); 775 776 return message.replace(/#VALUE#/g, value); 777 } 778 779 function _replaceDateFormat(match, matchFull) 780 { 781 if (dateFormats[match]) 782 return dateFormats[match](); 783 else 784 return matchFull; 785 } 786 787 function intval(number) 788 { 789 return number >= 0 ? Math.floor(number) : Math.ceil(number); 790 } 791 }, 792 793 convertBitrixFormat: function(format) 794 { 795 if (!Utils.isNotEmptyString(format)) 796 return ""; 797 798 return format.replace("YYYY", "Y") // 1999 799 .replace("MMMM", "F") // January - December 800 .replace("MM", "m") // 01 - 12 801 .replace("M", "M") // Jan - Dec 802 .replace("DD", "d") // 01 - 31 803 .replace("G", "g") // 1 - 12
804 .replace(/GG/i, "G") // 0 - 23 805 .replace("H", "h") // 01 - 12 806 .replace(/HH/i, "H") // 00 - 24 807 .replace("MI", "i") // 00 - 59 808 .replace("SS", "s") // 00 - 59 809 .replace("TT", "A") // AM - PM 810 .replace("T", "a"); // am - pm 811 }, 812 813 convertToUTC: function(date) 814 { 815 if (!Utils.isDate(date)) 816 return null; 817 818 return new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds())); 819 }, 820 821 /** 822 * Function creates and returns Javascript Date() object from server timestamp regardless of local browser (system) timezone. 823 * For example can be used to convert timestamp from some exact date on server to the JS Date object with the same value. 824 * 825 * @param timestamp - timestamp in seconds 826 * @returns {Date} 827 */ 828 getNewDate: function(timestamp) 829 { 830 return new Date(this.getBrowserTimestamp(timestamp)); 831 }, 832 833 /** 834 * Function transforms server timestamp (in sec) to javascript timestamp (calculated depend on local browser timezone offset). Returns timestamp in milliseconds. 835 * Also see BX.Main.Date.getNewDate description. 836 * 837 * @param timestamp - timestamp in seconds 838 * @returns {number} 839 */ 840 getBrowserTimestamp: function(timestamp) 841 { 842 timestamp = parseInt(timestamp, 10); 843 var browserOffset = new Date(timestamp * 1000).getTimezoneOffset() * 60; 844 return (parseInt(timestamp, 10) + parseInt(this._getMessage('SERVER_TZ_OFFSET')) + browserOffset) * 1000; 845 }, 846 847 /** 848 * Function transforms local browser timestamp (in ms) to server timestamp (calculated depend on local browser timezone offset). Returns timestamp in seconds. 849 * 850 * @param timestamp - timestamp in milliseconds 851 * @returns {number} 852 */ 853 getServerTimestamp: function(timestamp) 854 { 855 timestamp = parseInt(timestamp, 10); 856 var browserOffset = new Date(timestamp).getTimezoneOffset() * 60; 857 return Math.round(timestamp / 1000 - (parseInt(this._getMessage('SERVER_TZ_OFFSET'), 10) + parseInt(browserOffset, 10))); 858 }, 859 860 formatLastActivityDate: function(timestamp, now, utc) 861 { 862 var ampm = this.isAmPmMode(true); 863 var timeFormat = (ampm === this.AM_PM_MODE.LOWER? "g:i a" : (ampm === this.AM_PM_MODE.UPPER? "g:i A" : "H:i")); 864 865 var format = [ 866 ["tomorrow", "#01#"+timeFormat], 867 ["now" , "#02#"], 868 ["todayFuture", "#03#"+timeFormat], 869 ["yesterday", "#04#"+timeFormat], 870 ["-", this.convertBitrixFormat(this._getMessage("FORMAT_DATETIME")).replace(/:s/g, "")], 871 ["s60", "sago"], 872 ["i60", "iago"], 873 ["H5", "Hago"], 874 ["H24", "#03#"+timeFormat], 875 ["d31", "dago"], 876 ["m12>1", "mago"], 877 ["m12>0", "dago"], 878 ["", "#05#"] 879 ]; 880 var formattedDate = this.format(format, timestamp, now, utc); 881 var match = null; 882 if ((match = /^#(\d+)#(.*)/.exec(formattedDate)) != null) 883 { 884 switch (match[1]) 885 { 886 case "01": 887 formattedDate = this._getMessage('FD_LAST_SEEN_TOMORROW').replace("#TIME#", match[2]); 888 break; 889 case "02": 890 formattedDate = this._getMessage('FD_LAST_SEEN_NOW'); 891 break; 892 case "03": 893 formattedDate = this._getMessage('FD_LAST_SEEN_TODAY').replace("#TIME#", match[2]); 894 break; 895 case "04": 896 formattedDate = this._getMessage('FD_LAST_SEEN_YESTERDAY').replace("#TIME#", match[2]); 897 break; 898 case "05": 899 formattedDate = this._getMessage('FD_LAST_SEEN_MORE_YEAR'); 900 break; 901 default: 902 formattedDate = match[2]; 903 break; 904 } 905 } 906 907 return formattedDate; 908 }, 909 910 isAmPmMode: function(returnConst) 911 { 912 if (returnConst === true) 913 { 914 return this._getMessage('AMPM_MODE'); 915 } 916 917 return this._getMessage('AMPM_MODE') !== false; 918 }, 919 920 /** 921 * The method is designed to replace the localization storage on sites without Bitrix Framework. 922 * 923 * @param message 924 * @returns {*} 925 * @private 926 */ 927 _getMessage: function(message) 928 { 929 return BX.message(message); 930 }, 931 932 /** 933 * The method used to parse date from string by given format. 934 * 935 * @param {string} str - date in given format 936 * @param {boolean} isUTC - is date in UTC 937 * @param {string} formatDate - format of the date without time 938 * @param {string} formatDatetime - format of the date with time 939 * @returns {Date|null} - returns Date object if string was parsed or null 940 */ 941 parse: function(str, isUTC, formatDate, formatDatetime) 942 { 943 if (Utils.isNotEmptyString(str)) 944 { 945 if (!formatDate) 946 formatDate = this._getMessage('FORMAT_DATE'); 947 if (!formatDatetime) 948 formatDatetime = this._getMessage('FORMAT_DATETIME'); 949 950 var regMonths = ''; 951 for (i = 1; i <= 12; i++) 952 { 953 regMonths = regMonths + '|' + this._getMessage('MON_'+i); 954 } 955 956 var
957 expr = new RegExp('([0-9]+|[a-z]+' + regMonths + ')', 'ig'), 958 aDate = str.match(expr), 959 aFormat = formatDate.match(/(DD|MI|MMMM|MM|M|YYYY)/ig), 960 i, cnt, 961 aDateArgs=[], aFormatArgs=[], 962 aResult={}; 963 964 if (!aDate) 965 { 966 return null; 967 } 968 969 if(aDate.length > aFormat.length) 970 { 971 aFormat = formatDatetime.match(/(DD|MI|MMMM|MM|M|YYYY|HH|H|SS|TT|T|GG|G)/ig); 972 } 973 974 for(i = 0, cnt = aDate.length; i < cnt; i++) 975 { 976 if(aDate[i].trim() !== '') 977 { 978 aDateArgs[aDateArgs.length] = aDate[i]; 979 } 980 } 981 982 for(i = 0, cnt = aFormat.length; i < cnt; i++) 983 { 984 if(aFormat[i].trim() !== '') 985 { 986 aFormatArgs[aFormatArgs.length] = aFormat[i]; 987 } 988 } 989 990 var m = Utils.array_search('MMMM', aFormatArgs); 991 if (m > 0) 992 { 993 aDateArgs[m] = this.getMonthIndex(aDateArgs[m]); 994 aFormatArgs[m] = "MM"; 995 } 996 else 997 { 998 m = Utils.array_search('M', aFormatArgs); 999 if (m > 0) 1000 { 1001 aDateArgs[m] = this.getMonthIndex(aDateArgs[m]); 1002 aFormatArgs[m] = "MM"; 1003 } 1004 } 1005 1006 for(i = 0, cnt = aFormatArgs.length; i < cnt; i++) 1007 { 1008 var k = aFormatArgs[i].toUpperCase(); 1009 aResult[k] = k === 'T' || k === 'TT' ? aDateArgs[i] : parseInt(aDateArgs[i], 10); 1010 } 1011 1012 if(aResult['DD'] > 0 && aResult['MM'] > 0 && aResult['YYYY'] > 0) 1013 { 1014 var d = new Date(); 1015 1016 if(isUTC) 1017 { 1018 d.setUTCDate(1); 1019 d.setUTCFullYear(aResult['YYYY']); 1020 d.setUTCMonth(aResult['MM'] - 1); 1021 d.setUTCDate(aResult['DD']); 1022 d.setUTCHours(0, 0, 0, 0); 1023 } 1024 else 1025 { 1026 d.setDate(1); 1027 d.setFullYear(aResult['YYYY']); 1028 d.setMonth(aResult['MM'] - 1); 1029 d.setDate(aResult['DD']); 1030 d.setHours(0, 0, 0, 0); 1031 } 1032 1033 if( 1034 (!isNaN(aResult['HH']) || !isNaN(aResult['GG']) || !isNaN(aResult['H']) || !isNaN(aResult['G'])) 1035 && !isNaN(aResult['MI']) 1036 ) 1037 { 1038 if (!isNaN(aResult['H']) || !isNaN(aResult['G'])) 1039 { 1040 var 1041 bPM = (aResult['T']||aResult['TT']||'am').toUpperCase() === 'PM', 1042 h = parseInt(aResult['H']||aResult['G']||0, 10); 1043 1044 if(bPM) 1045 { 1046 aResult['HH'] = h + (h === 12 ? 0 : 12); 1047 } 1048 else 1049 { 1050 aResult['HH'] = h < 12 ? h : 0; 1051 } 1052 } 1053 else 1054 { 1055 aResult['HH'] = parseInt(aResult['HH']||aResult['GG']||0, 10); 1056 } 1057 1058 if (isNaN(aResult['SS'])) 1059 aResult['SS'] = 0; 1060 1061 if(isUTC) 1062 { 1063 d.setUTCHours(aResult['HH'], aResult['MI'], aResult['SS']); 1064 } 1065 else 1066 { 1067 d.setHours(aResult['HH'], aResult['MI'], aResult['SS']); 1068 } 1069 } 1070 1071 return d; 1072 } 1073 } 1074 1075 return null; 1076 }, 1077 1078 getMonthIndex: function(month) 1079 { 1080 var 1081 i, 1082 q = month.toUpperCase(), 1083 wordMonthCut = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec'], 1084 wordMonth = ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december']; 1085 1086 for (i = 1; i <= 12; i++) 1087 { 1088 if (q === this._getMessage('MON_'+i).toUpperCase() 1089 || q === this._getMessage('MONTH_'+i).toUpperCase() 1090 || q === wordMonthCut[i-1].toUpperCase() 1091 || q === wordMonth[i-1].toUpperCase()) 1092 { 1093 return i; 1094 } 1095 } 1096 return month; 1097 } 1098 }; 1099 1100 /** 1101 * @private 1102 */ 1103 var Utils = { 1104 isDate: function(item) { 1105 return item && Object.prototype.toString.call(item) == "[object Date]"; 1106 }, 1107 isNumber: function(item) { 1108 return item === 0 ? true : (item ? (typeof (item) == "number" || item instanceof Number) : false); 1109 }, 1110 isArray: function(item) { 1111 return item && Object.prototype.toString.call(item) == "[object Array]"; 1112 }, 1113 isString: function(item) { 1114 return item === '' ? true : (item ? (typeof (item) == "string" || item instanceof String) : false); 1115 }, 1116 isNotEmptyString: function(item) { 1117 return this.isString(item) ? item.length > 0 : false; 1118 }, 1119 strPadLeft: function(input, padLength, padString) 1120 { 1121 var i = input.length, q=padString.length; 1122 if (i >= padLength) return input; 1123 1124 for(;i<padLength;i+=q) 1125 input = padString + input; 1126 1127 return input; 1128 }, 1129 /** 1130 * @deprecated 1131 * @use myArr.findIndex(item => item === needle); 1132 */ 1133 array_search: function(needle, haystack) 1134 { 1135 for(var i = 0; i < haystack.length; i++) 1136 { 1137 if(haystack[i] == needle) 1138 return i; 1139 } 1140 return -1; 1141 }, 1142 }; 1143 1144})(window);
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.