Telegram Web K with changes to work inside I2P
https://web.telegram.i2p/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
381 lines
11 KiB
381 lines
11 KiB
/* |
|
* Date Format 1.2.3 |
|
* (c) 2007-2009 Steven Levithan <stevenlevithan.com> |
|
* MIT license |
|
* |
|
* Includes enhancements by Scott Trenda <scott.trenda.net> |
|
* and Kris Kowal <cixar.com/~kris.kowal/> |
|
* |
|
* Accepts a date, a mask, or a date and a mask. |
|
* Returns a formatted version of the given date. |
|
* The date defaults to the current date/time. |
|
* The mask defaults to dateFormat.masks.default. |
|
*/ |
|
|
|
const dateFormat = (() => { |
|
const token = /d{1,4}|D{3,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|W{1,2}|[LlopSZN]|"[^"]*"|'[^']*'/g; |
|
const timezone = /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g; |
|
const timezoneClip = /[^-+\dA-Z]/g; |
|
|
|
// Regexes and supporting functions are cached through closure |
|
function f(date?: number | Date, mask?: string, utc?: boolean, gmt?: boolean): string { |
|
// You can't provide utc if you skip other args (use the 'UTC:' mask prefix) |
|
/* if( |
|
arguments.length === 1 && |
|
kindOf(date) === "string" && |
|
!/\d/.test(date) |
|
) { |
|
mask = date; |
|
date = undefined; |
|
} */ |
|
|
|
date = date || date === 0 ? date : new Date(); |
|
|
|
if(!(date instanceof Date)) { |
|
date = new Date(date); |
|
} |
|
|
|
/* if(isNaN(date)) { |
|
throw TypeError("Invalid date"); |
|
} */ |
|
|
|
/* mask = String( |
|
dateFormat.masks[mask] || mask || dateFormat.masks["default"] |
|
); */ |
|
|
|
// Allow setting the utc/gmt argument via the mask |
|
const maskSlice = mask.slice(0, 4); |
|
if(maskSlice === "UTC:" || maskSlice === "GMT:") { |
|
mask = mask.slice(4); |
|
utc = true; |
|
if(maskSlice === "GMT:") { |
|
gmt = true; |
|
} |
|
} |
|
|
|
const _ = () => (utc ? "getUTC" : "get"); |
|
const d = (): number => (date as any)[_() + "Date"](); |
|
const D = (): number => (date as any)[_() + "Day"](); |
|
const m = (): number => (date as any)[_() + "Month"](); |
|
const y = (): number => (date as any)[_() + "FullYear"](); |
|
const H = (): number => (date as any)[_() + "Hours"](); |
|
const M = (): number => (date as any)[_() + "Minutes"](); |
|
const s = (): number => (date as any)[_() + "Seconds"](); |
|
const L = (): number => (date as any)[_() + "Milliseconds"](); |
|
const o = (): number => (utc ? 0 : (date as Date).getTimezoneOffset()); |
|
const W = (): number => getWeek(date as Date); |
|
const N = (): number => getDayOfWeek(date as Date); |
|
|
|
const flags = { |
|
d: () => d(), |
|
dd: () => pad(d()), |
|
ddd: () => dateFormat.i18n.dayNames[D()], |
|
DDD: () => getDayName({ |
|
y: y(), |
|
m: m(), |
|
d: d(), |
|
_: _(), |
|
dayName: dateFormat.i18n.dayNames[D()], |
|
short: true |
|
}), |
|
dddd: () => dateFormat.i18n.dayNames[D() + 7], |
|
DDDD: () => getDayName({ |
|
y: y(), |
|
m: m(), |
|
d: d(), |
|
_: _(), |
|
dayName: dateFormat.i18n.dayNames[D() + 7] |
|
}), |
|
m: () => m() + 1, |
|
mm: () => pad(m() + 1), |
|
mmm: () => dateFormat.i18n.monthNames[m()], |
|
mmmm: () => dateFormat.i18n.monthNames[m() + 12], |
|
yy: () => String(y()).slice(2), |
|
yyyy: () => pad(y(), 4), |
|
h: () => H() % 12 || 12, |
|
hh: () => pad(H() % 12 || 12), |
|
H: () => H(), |
|
HH: () => pad(H()), |
|
M: () => M(), |
|
MM: () => pad(M()), |
|
s: () => s(), |
|
ss: () => pad(s()), |
|
l: () => pad(L(), 3), |
|
L: () => pad(Math.floor(L() / 10)), |
|
t: () => |
|
H() < 12 ? |
|
dateFormat.i18n.timeNames[0] : dateFormat.i18n.timeNames[1], |
|
tt: () => |
|
H() < 12 ? |
|
dateFormat.i18n.timeNames[2] : dateFormat.i18n.timeNames[3], |
|
T: () => |
|
H() < 12 ? |
|
dateFormat.i18n.timeNames[4] : dateFormat.i18n.timeNames[5], |
|
TT: () => |
|
H() < 12 ? |
|
dateFormat.i18n.timeNames[6] : dateFormat.i18n.timeNames[7], |
|
Z: () => |
|
gmt ? |
|
"GMT" : utc ? |
|
"UTC" : (String(date).match(timezone) || [""]) |
|
.pop() |
|
.replace(timezoneClip, "") |
|
.replace(/GMT\+0000/g, "UTC"), |
|
o: () => |
|
(o() > 0 ? "-" : "+") + |
|
pad(Math.floor(Math.abs(o()) / 60) * 100 + (Math.abs(o()) % 60), 4), |
|
p: () => |
|
(o() > 0 ? "-" : "+") + |
|
pad(Math.floor(Math.abs(o()) / 60), 2) + |
|
":" + |
|
pad(Math.floor(Math.abs(o()) % 60), 2), |
|
S: () => ["th", "st", "nd", "rd"][ |
|
// @ts-ignore |
|
d() % 10 > 3 ? 0 : (((d() % 100) - (d() % 10) != 10) * d()) % 10 |
|
], |
|
W: () => W(), |
|
WW: () => pad(W()), |
|
N: () => N(), |
|
}; |
|
|
|
return mask.replace(token, (match) => { |
|
if(match in flags) { |
|
// @ts-ignore |
|
return flags[match](); |
|
} |
|
return match.slice(1, match.length - 1); |
|
}); |
|
}; |
|
|
|
// Internationalization strings |
|
f.i18n = { |
|
dayNames: [ |
|
"Sun", |
|
"Mon", |
|
"Tue", |
|
"Wed", |
|
"Thu", |
|
"Fri", |
|
"Sat", |
|
"Sunday", |
|
"Monday", |
|
"Tuesday", |
|
"Wednesday", |
|
"Thursday", |
|
"Friday", |
|
"Saturday", |
|
], |
|
monthNames: [ |
|
"Jan", |
|
"Feb", |
|
"Mar", |
|
"Apr", |
|
"May", |
|
"Jun", |
|
"Jul", |
|
"Aug", |
|
"Sep", |
|
"Oct", |
|
"Nov", |
|
"Dec", |
|
"January", |
|
"February", |
|
"March", |
|
"April", |
|
"May", |
|
"June", |
|
"July", |
|
"August", |
|
"September", |
|
"October", |
|
"November", |
|
"December", |
|
], |
|
timeNames: ["a", "p", "am", "pm", "A", "P", "AM", "PM"], |
|
}; |
|
|
|
f.setLocale = function(code: string) { |
|
const date = new Date(); |
|
|
|
{ |
|
const dateTimeFormat = new Intl.DateTimeFormat(code, {month: 'long'}); |
|
const dateTimeFormatShort = new Intl.DateTimeFormat(code, {month: 'short'}); |
|
for(let i = 0; i < 12; ++i) { |
|
date.setMonth(i); |
|
f.i18n.monthNames[i] = dateTimeFormatShort.format(date); |
|
f.i18n.monthNames[i + 12] = dateTimeFormat.format(date); |
|
} |
|
} |
|
|
|
{ |
|
const day = date.getDay(); |
|
if(day !== 0) { |
|
date.setDate(date.getDate() - day); |
|
} |
|
|
|
const dateTimeFormat = new Intl.DateTimeFormat(code, {weekday: 'long'}); |
|
const dateTimeFormatShort = new Intl.DateTimeFormat(code, {weekday: 'short'}); |
|
for(let i = 0; i < 7; ++i) { |
|
date.setDate(date.getDate() + 1); |
|
f.i18n.dayNames[i] = dateTimeFormatShort.format(date); |
|
f.i18n.dayNames[i + 7] = dateTimeFormat.format(date); |
|
} |
|
} |
|
}; |
|
|
|
return f; |
|
})(); |
|
|
|
export default dateFormat; |
|
|
|
(window as any).dateFormat = dateFormat; |
|
|
|
/* dateFormat.masks = { |
|
default: "ddd mmm dd yyyy HH:MM:ss", |
|
shortDate: "m/d/yy", |
|
paddedShortDate: "mm/dd/yyyy", |
|
mediumDate: "mmm d, yyyy", |
|
longDate: "mmmm d, yyyy", |
|
fullDate: "dddd, mmmm d, yyyy", |
|
shortTime: "h:MM TT", |
|
mediumTime: "h:MM:ss TT", |
|
longTime: "h:MM:ss TT Z", |
|
isoDate: "yyyy-mm-dd", |
|
isoTime: "HH:MM:ss", |
|
isoDateTime: "yyyy-mm-dd'T'HH:MM:sso", |
|
isoUtcDateTime: "UTC:yyyy-mm-dd'T'HH:MM:ss'Z'", |
|
expiresHeaderFormat: "ddd, dd mmm yyyy HH:MM:ss Z", |
|
}; */ |
|
|
|
const pad = (val: number | string, len = 2) => { |
|
val = String(val); |
|
while(val.length < len) { |
|
val = "0" + val; |
|
} |
|
return val; |
|
}; |
|
|
|
/** |
|
* Get day name |
|
* Yesterday, Today, Tomorrow if the date lies within, else fallback to Monday - Sunday |
|
* @param {Object} |
|
* @return {String} |
|
*/ |
|
const getDayName = ({ |
|
y, |
|
m, |
|
d, |
|
_, |
|
dayName, |
|
short = false |
|
}: { |
|
y: number, |
|
m: number, |
|
d: number, |
|
_: any, |
|
dayName: any, |
|
short?: boolean |
|
}) => { |
|
const today = new Date(); |
|
const yesterday = new Date(); |
|
yesterday.setDate((yesterday as any)[_ + 'Date']() - 1); |
|
const tomorrow = new Date(); |
|
tomorrow.setDate((tomorrow as any)[_ + 'Date']() + 1); |
|
const today_d = (): number => (today as any)[_ + 'Date'](); |
|
const today_m = (): number => (today as any)[_ + 'Month'](); |
|
const today_y = (): number => (today as any)[_ + 'FullYear'](); |
|
const yesterday_d = (): number => (yesterday as any)[_ + 'Date'](); |
|
const yesterday_m = (): number => (yesterday as any)[_ + 'Month'](); |
|
const yesterday_y = (): number => (yesterday as any)[_ + 'FullYear'](); |
|
const tomorrow_d = (): number => (tomorrow as any)[_ + 'Date'](); |
|
const tomorrow_m = (): number => (tomorrow as any)[_ + 'Month'](); |
|
const tomorrow_y = (): number => (tomorrow as any)[_ + 'FullYear'](); |
|
|
|
if(today_y() === y && today_m() === m && today_d() === d) { |
|
return short ? 'Tdy' : 'Today'; |
|
} else if(yesterday_y() === y && yesterday_m() === m && yesterday_d() === d) { |
|
return short ? 'Ysd' : 'Yesterday'; |
|
} else if(tomorrow_y() === y && tomorrow_m() === m && tomorrow_d() === d) { |
|
return short ? 'Tmw' : 'Tomorrow'; |
|
} |
|
return dayName; |
|
}; |
|
|
|
/** |
|
* Get the ISO 8601 week number |
|
* Based on comments from |
|
* http://techblog.procurios.nl/k/n618/news/view/33796/14863/Calculate-ISO-8601-week-and-year-in-javascript.html |
|
* |
|
* @param {Object} `date` |
|
* @return {Number} |
|
*/ |
|
const getWeek = (date: Date) => { |
|
// Remove time components of date |
|
const targetThursday = new Date( |
|
date.getFullYear(), |
|
date.getMonth(), |
|
date.getDate() |
|
); |
|
|
|
// Change date to Thursday same week |
|
targetThursday.setDate( |
|
targetThursday.getDate() - ((targetThursday.getDay() + 6) % 7) + 3 |
|
); |
|
|
|
// Take January 4th as it is always in week 1 (see ISO 8601) |
|
const firstThursday = new Date(targetThursday.getFullYear(), 0, 4); |
|
|
|
// Change date to Thursday same week |
|
firstThursday.setDate( |
|
firstThursday.getDate() - ((firstThursday.getDay() + 6) % 7) + 3 |
|
); |
|
|
|
// Check if daylight-saving-time-switch occurred and correct for it |
|
const ds = |
|
targetThursday.getTimezoneOffset() - firstThursday.getTimezoneOffset(); |
|
targetThursday.setHours(targetThursday.getHours() - ds); |
|
|
|
// Number of weeks between target Thursday and first Thursday |
|
const weekDiff = (targetThursday.getTime() - firstThursday.getTime()) / (86400000 * 7); |
|
return 1 + Math.floor(weekDiff); |
|
}; |
|
|
|
/** |
|
* Get ISO-8601 numeric representation of the day of the week |
|
* 1 (for Monday) through 7 (for Sunday) |
|
* |
|
* @param {Object} `date` |
|
* @return {Number} |
|
*/ |
|
const getDayOfWeek = (date: Date) => { |
|
let dow = date.getDay(); |
|
if(dow === 0) { |
|
dow = 7; |
|
} |
|
return dow; |
|
}; |
|
|
|
/** |
|
* kind-of shortcut |
|
* @param {*} val |
|
* @return {String} |
|
*/ |
|
/* const kindOf = (val: any) => { |
|
if(val === null) { |
|
return "null"; |
|
} |
|
|
|
if(val === undefined) { |
|
return "undefined"; |
|
} |
|
|
|
if(typeof val !== "object") { |
|
return typeof val; |
|
} |
|
|
|
if(Array.isArray(val)) { |
|
return "array"; |
|
} |
|
|
|
return {}.toString.call(val).slice(8, -1).toLowerCase(); |
|
}; */
|
|
|