import { MOUNT_CLASS_TO } from "../lib/mtproto/mtproto_config"; export const months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']; export const days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']; export const ONE_DAY = 86400; // https://stackoverflow.com/a/6117889 export const getWeekNumber = (date: Date) => { const d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate())); const dayNum = d.getUTCDay() || 7; d.setUTCDate(d.getUTCDate() + 4 - dayNum); const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1)); return Math.ceil((((d.getTime() - yearStart.getTime()) / ONE_DAY) + 1) / 7); }; export const formatDateAccordingToToday = (time: Date) => { const date = new Date(); const now = date.getTime() / 1000 | 0; const timestamp = time.getTime() / 1000 | 0; let timeStr: string; if((now - timestamp) < ONE_DAY && date.getDate() == time.getDate()) { // if the same day timeStr = ('0' + time.getHours()).slice(-2) + ':' + ('0' + time.getMinutes()).slice(-2); } else if(date.getFullYear() != time.getFullYear()) { // different year timeStr = time.getDate() + '.' + ('0' + (time.getMonth() + 1)).slice(-2) + '.' + ('' + time.getFullYear()).slice(-2); } else if((now - timestamp) < (ONE_DAY * 7) && getWeekNumber(date) == getWeekNumber(time)) { // current week timeStr = days[time.getDay()].slice(0, 3); } else { // same year timeStr = months[time.getMonth()].slice(0, 3) + ' ' + ('0' + time.getDate()).slice(-2); } return timeStr; }; export const getFullDate = (date: Date, options: Partial<{ noTime: true, noSeconds: true, monthAsNumber: true, leadingZero: true }> = {}) => { const joiner = options.monthAsNumber ? '.' : ' '; const time = ('0' + date.getHours()).slice(-2) + ':' + ('0' + date.getMinutes()).slice(-2) + (options.noSeconds ? '' : ':' + ('0' + date.getSeconds()).slice(-2)); return (options.leadingZero ? ('0' + date.getDate()).slice(-2) : date.getDate()) + joiner + (options.monthAsNumber ? ('0' + (date.getMonth() + 1)).slice(-2) : months[date.getMonth()]) + joiner + date.getFullYear() + (options.noTime ? '' : ', ' + time); }; export function tsNow(seconds?: true) { const t = Date.now(); return seconds ? Math.floor(t / 1000) : t; } // https://github.com/DrKLO/Telegram/blob/d52b2c921abd3c1e8d6368858313ad0cb0468c07/TMessagesProj/src/main/java/org/telegram/ui/Adapters/FiltersView.java const minYear = 2013; const yearPattern = new RegExp("20[0-9]{1,2}"); const monthYearOrDayPattern = new RegExp("(\\w{3,}) ([0-9]{0,4})", 'i'); const yearOrDayAndMonthPattern = new RegExp("([0-9]{0,4}) (\\w{2,})", 'i'); const shortDate = new RegExp("^([0-9]{1,4})(\\.| |/|\\-)([0-9]{1,4})$", 'i'); const longDate = new RegExp("^([0-9]{1,2})(\\.| |/|\\-)([0-9]{1,2})(\\.| |/|\\-)([0-9]{1,4})$", 'i'); const numberOfDaysEachMonth = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; export type DateData = { title: string, minDate: number, maxDate: number, }; export function fillTipDates(query: string, dates: DateData[]) { const q = query.trim(); if(q.length < 3) { return; } let matches: any[]; if((matches = shortDate.exec(q)) !== null) { const g1 = matches[1]; const g2 = matches[3]; const k = parseInt(g1); const k1 = parseInt(g2); if(k > 0 && k <= 31) { if(k1 >= minYear && k <= 12) { const selectedYear = k1; const month = k - 1; createForMonthYear(dates, month, selectedYear); return; } else if (k1 <= 12) { const day = k - 1; const month = k1 - 1; createForDayMonth(dates, day, month); } } else if (k >= minYear && k1 <= 12) { const selectedYear = k; const month = k1 - 1; createForMonthYear(dates, month, selectedYear); } return; } if((matches = longDate.exec(q)) !== null) { const g1 = matches[1]; const g2 = matches[3]; const g3 = matches[5]; if(!matches[2] == matches[4]) { return; } const day = parseInt(g1); const month = parseInt(g2) - 1; let year = parseInt(g3); if(year >= 10 && year <= 99) { year += 2000; } const currentYear = new Date().getFullYear(); if(validDateForMonth(day - 1, month) && year >= minYear && year <= currentYear) { const date = new Date(); date.setFullYear(year, month, day); date.setHours(0, 0, 0); const minDate = date.getTime(); date.setFullYear(year, month, day + 1); date.setHours(0, 0, 0); const maxDate = date.getTime() - 1; dates.push({ title: formatterYearMax(minDate), minDate, maxDate }); return; } return; } if((matches = yearPattern.exec(q)) !== null) { let selectedYear = +q; const currentYear = new Date().getFullYear(); if(selectedYear < minYear) { selectedYear = minYear; for(let i = currentYear; i >= selectedYear; i--) { const date = new Date(); date.setFullYear(i, 0, 1); date.setHours(0, 0, 0); const minDate = date.getTime(); date.setFullYear(i + 1, 0, 1); date.setHours(0, 0, 0); const maxDate = date.getTime() - 1; dates.push({ title: '' + i, minDate, maxDate }); } } else if(selectedYear <= currentYear) { const date = new Date(); date.setFullYear(selectedYear, 0, 1); date.setHours(0, 0, 0); const minDate = date.getTime(); date.setFullYear(selectedYear + 1, 0, 1); date.setHours(0, 0, 0); const maxDate = date.getTime() - 1; dates.push({ title: '' + selectedYear, minDate, maxDate }); } return; } if((matches = monthYearOrDayPattern.exec(q)) !== null) { const g1 = matches[1]; const g2 = matches[2]; const month = getMonth(g1); if(month >= 0) { const k = +g2; if(k > 0 && k <= 31) { const day = k - 1; createForDayMonth(dates, day, month); return; } else if(k >= minYear) { const selectedYear = k; createForMonthYear(dates, month, selectedYear); return; } } } if((matches = yearOrDayAndMonthPattern.exec(q)) !== null) { const g1 = matches[1]; const g2 = matches[2]; const month = getMonth(g2); if(month >= 0) { const k = +g1; if(k > 0 && k <= 31) { const day = k - 1; createForDayMonth(dates, day, month); return; } else if (k >= minYear) { const selectedYear = k; createForMonthYear(dates, month, selectedYear); } } } } function createForMonthYear(dates: DateData[], month: number, selectedYear: number) { const currentYear = new Date().getFullYear(); const today = Date.now(); if(selectedYear >= minYear && selectedYear <= currentYear) { const date = new Date(); date.setFullYear(selectedYear, month, 1); date.setHours(0, 0, 0); const minDate = date.getTime(); if(minDate > today) { return; } date.setMonth(date.getMonth() + 1); const maxDate = date.getTime() - 1; dates.push({ title: formatterMonthYear(minDate), minDate, maxDate }); } } function createForDayMonth(dates: DateData[], day: number, month: number) { if(validDateForMonth(day, month)) { const currentYear = new Date().getFullYear(); const today = Date.now(); for(let i = currentYear; i >= minYear; i--) { if(month == 1 && day == 28 && !isLeapYear(i)) { continue; } const date = new Date(); date.setFullYear(i, month, day + 1); date.setHours(0, 0, 0); const minDate = date.getTime(); if(minDate > today) { continue; } date.setFullYear(i, month, day + 2); date.setHours(0, 0, 0); const maxDate = date.getTime() - 1; if(i == currentYear) { dates.push({ title: formatterDayMonth(minDate), minDate, maxDate }); } else { dates.push({ title: formatterYearMax(minDate), minDate, maxDate }); } } } } function formatterMonthYear(timestamp: number) { const date = new Date(timestamp); return months[date.getMonth()].slice(0, 3) + ' ' + date.getFullYear(); } function formatterDayMonth(timestamp: number) { const date = new Date(timestamp); return months[date.getMonth()].slice(0, 3) + ' ' + date.getDate(); } function formatterYearMax(timestamp: number) { const date = new Date(timestamp); return ('0' + date.getDate()).slice(-2) + '.' + ('0' + (date.getMonth() + 1)).slice(-2) + '.' + date.getFullYear(); } function validDateForMonth(day: number, month: number) { if(month >= 0 && month < 12) { if(day >= 0 && day < numberOfDaysEachMonth[month]) { return true; } } return false; } function isLeapYear(year: number) { return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0); } function getMonth(q: string) { /* String[] months = new String[]{ LocaleController.getString("January", R.string.January).toLowerCase(), LocaleController.getString("February", R.string.February).toLowerCase(), LocaleController.getString("March", R.string.March).toLowerCase(), LocaleController.getString("April", R.string.April).toLowerCase(), LocaleController.getString("May", R.string.May).toLowerCase(), LocaleController.getString("June", R.string.June).toLowerCase(), LocaleController.getString("July", R.string.July).toLowerCase(), LocaleController.getString("August", R.string.August).toLowerCase(), LocaleController.getString("September", R.string.September).toLowerCase(), LocaleController.getString("October", R.string.October).toLowerCase(), LocaleController.getString("November", R.string.November).toLowerCase(), LocaleController.getString("December", R.string.December).toLowerCase() }; */ /* String[] monthsEng = new String[12]; Calendar c = Calendar.getInstance(); for (int i = 1; i <= 12; i++) { c.set(0, 0, 0, 0, 0, 0); c.set(Calendar.MONTH, i); monthsEng[i - 1] = c.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.ENGLISH).toLowerCase(); } */ q = q.toLowerCase(); for(let i = 0; i < 12; i++) { const month = months[i].toLowerCase(); if(month.indexOf(q) === 0) { return i; } } return -1; } MOUNT_CLASS_TO && (MOUNT_CLASS_TO.fillTipDates = fillTipDates);