PageSourceSearch

https://teatr-rosta.ru/bitrix/js/main/date/main.date.js

js teatr-rosta.ru collected 2026-10-06 18:57:55 UTC 29,748 bytes, 950 lines download raw bytes

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