326 lines
8.1 KiB
JavaScript
326 lines
8.1 KiB
JavaScript
const YEAR = 'year';
|
||
const MONTH = 'month';
|
||
const DAY = 'day';
|
||
const HOUR = 'hour';
|
||
const MINUTE = 'minute';
|
||
const SECOND = 'second';
|
||
const MILLISECOND = 'millisecond';
|
||
|
||
const month_names = {
|
||
en: [
|
||
'January',
|
||
'February',
|
||
'March',
|
||
'April',
|
||
'May',
|
||
'June',
|
||
'July',
|
||
'August',
|
||
'September',
|
||
'October',
|
||
'November',
|
||
'December',
|
||
],
|
||
es: [
|
||
'Enero',
|
||
'Febrero',
|
||
'Marzo',
|
||
'Abril',
|
||
'Mayo',
|
||
'Junio',
|
||
'Julio',
|
||
'Agosto',
|
||
'Septiembre',
|
||
'Octubre',
|
||
'Noviembre',
|
||
'Diciembre',
|
||
],
|
||
ru: [
|
||
'Январь',
|
||
'Февраль',
|
||
'Март',
|
||
'Апрель',
|
||
'Май',
|
||
'Июнь',
|
||
'Июль',
|
||
'Август',
|
||
'Сентябрь',
|
||
'Октябрь',
|
||
'Ноябрь',
|
||
'Декабрь',
|
||
],
|
||
ptBr: [
|
||
'Janeiro',
|
||
'Fevereiro',
|
||
'Março',
|
||
'Abril',
|
||
'Maio',
|
||
'Junho',
|
||
'Julho',
|
||
'Agosto',
|
||
'Setembro',
|
||
'Outubro',
|
||
'Novembro',
|
||
'Dezembro',
|
||
],
|
||
fr: [
|
||
'Janvier',
|
||
'Février',
|
||
'Mars',
|
||
'Avril',
|
||
'Mai',
|
||
'Juin',
|
||
'Juillet',
|
||
'Août',
|
||
'Septembre',
|
||
'Octobre',
|
||
'Novembre',
|
||
'Décembre',
|
||
],
|
||
tr: [
|
||
'Ocak',
|
||
'Şubat',
|
||
'Mart',
|
||
'Nisan',
|
||
'Mayıs',
|
||
'Haziran',
|
||
'Temmuz',
|
||
'Ağustos',
|
||
'Eylül',
|
||
'Ekim',
|
||
'Kasım',
|
||
'Aralık',
|
||
],
|
||
zh: [
|
||
'一月',
|
||
'二月',
|
||
'三月',
|
||
'四月',
|
||
'五月',
|
||
'六月',
|
||
'七月',
|
||
'八月',
|
||
'九月',
|
||
'十月',
|
||
'十一月',
|
||
'十二月',
|
||
],
|
||
};
|
||
|
||
export default {
|
||
parse(date, date_separator = '-', time_separator = /[.:]/) {
|
||
if (date instanceof Date) {
|
||
return date;
|
||
}
|
||
if (typeof date === 'string') {
|
||
let date_parts, time_parts;
|
||
const parts = date.split(' ');
|
||
|
||
date_parts = parts[0]
|
||
.split(date_separator)
|
||
.map((val) => parseInt(val, 10));
|
||
time_parts = parts[1] && parts[1].split(time_separator);
|
||
|
||
// month is 0 indexed
|
||
date_parts[1] = date_parts[1] - 1;
|
||
|
||
let vals = date_parts;
|
||
|
||
if (time_parts && time_parts.length) {
|
||
if (time_parts.length == 4) {
|
||
time_parts[3] = '0.' + time_parts[3];
|
||
time_parts[3] = parseFloat(time_parts[3]) * 1000;
|
||
}
|
||
vals = vals.concat(time_parts);
|
||
}
|
||
|
||
return new Date(...vals);
|
||
}
|
||
},
|
||
|
||
to_string(date, with_time = false) {
|
||
if (!(date instanceof Date)) {
|
||
throw new TypeError('Invalid argument type');
|
||
}
|
||
const vals = this.get_date_values(date).map((val, i) => {
|
||
if (i === 1) {
|
||
// add 1 for month
|
||
val = val + 1;
|
||
}
|
||
|
||
if (i === 6) {
|
||
return padStart(val + '', 3, '0');
|
||
}
|
||
|
||
return padStart(val + '', 2, '0');
|
||
});
|
||
const date_string = `${vals[0]}-${vals[1]}-${vals[2]}`;
|
||
const time_string = `${vals[3]}:${vals[4]}:${vals[5]}.${vals[6]}`;
|
||
|
||
return date_string + (with_time ? ' ' + time_string : '');
|
||
},
|
||
|
||
format(date, format_string = 'YYYY-MM-DD HH:mm:ss.SSS', lang = 'en') {
|
||
const values = this.get_date_values(date).map((d) => padStart(d, 2, 0));
|
||
const format_map = {
|
||
YYYY: values[0],
|
||
MM: padStart(+values[1] + 1, 2, 0),
|
||
DD: values[2],
|
||
HH: values[3],
|
||
mm: values[4],
|
||
ss: values[5],
|
||
SSS: values[6],
|
||
D: values[2],
|
||
MMMM: month_names[lang][+values[1]],
|
||
MMM: month_names[lang][+values[1]],
|
||
};
|
||
|
||
let str = format_string;
|
||
const formatted_values = [];
|
||
|
||
Object.keys(format_map)
|
||
.sort((a, b) => b.length - a.length) // big string first
|
||
.forEach((key) => {
|
||
if (str.includes(key)) {
|
||
str = str.replace(key, `$${formatted_values.length}`);
|
||
formatted_values.push(format_map[key]);
|
||
}
|
||
});
|
||
|
||
formatted_values.forEach((value, i) => {
|
||
str = str.replace(`$${i}`, value);
|
||
});
|
||
|
||
return str;
|
||
},
|
||
|
||
diff(date_a, date_b, scale = DAY) {
|
||
let milliseconds, seconds, hours, minutes, days, months, years;
|
||
|
||
milliseconds = date_a - date_b;
|
||
seconds = milliseconds / 1000;
|
||
minutes = seconds / 60;
|
||
hours = minutes / 60;
|
||
days = hours / 24;
|
||
months = days / 30;
|
||
years = months / 12;
|
||
|
||
if (!scale.endsWith('s')) {
|
||
scale += 's';
|
||
}
|
||
|
||
return Math.floor(
|
||
{
|
||
milliseconds,
|
||
seconds,
|
||
minutes,
|
||
hours,
|
||
days,
|
||
months,
|
||
years,
|
||
}[scale]
|
||
);
|
||
},
|
||
|
||
today() {
|
||
const vals = this.get_date_values(new Date()).slice(0, 3);
|
||
return new Date(...vals);
|
||
},
|
||
|
||
now() {
|
||
return new Date();
|
||
},
|
||
|
||
add(date, qty, scale) {
|
||
qty = parseInt(qty, 10);
|
||
const vals = [
|
||
date.getFullYear() + (scale === YEAR ? qty : 0),
|
||
date.getMonth() + (scale === MONTH ? qty : 0),
|
||
date.getDate() + (scale === DAY ? qty : 0),
|
||
date.getHours() + (scale === HOUR ? qty : 0),
|
||
date.getMinutes() + (scale === MINUTE ? qty : 0),
|
||
date.getSeconds() + (scale === SECOND ? qty : 0),
|
||
date.getMilliseconds() + (scale === MILLISECOND ? qty : 0),
|
||
];
|
||
return new Date(...vals);
|
||
},
|
||
|
||
start_of(date, scale) {
|
||
const scores = {
|
||
[YEAR]: 6,
|
||
[MONTH]: 5,
|
||
[DAY]: 4,
|
||
[HOUR]: 3,
|
||
[MINUTE]: 2,
|
||
[SECOND]: 1,
|
||
[MILLISECOND]: 0,
|
||
};
|
||
|
||
function should_reset(_scale) {
|
||
const max_score = scores[scale];
|
||
return scores[_scale] <= max_score;
|
||
}
|
||
|
||
const vals = [
|
||
date.getFullYear(),
|
||
should_reset(YEAR) ? 0 : date.getMonth(),
|
||
should_reset(MONTH) ? 1 : date.getDate(),
|
||
should_reset(DAY) ? 0 : date.getHours(),
|
||
should_reset(HOUR) ? 0 : date.getMinutes(),
|
||
should_reset(MINUTE) ? 0 : date.getSeconds(),
|
||
should_reset(SECOND) ? 0 : date.getMilliseconds(),
|
||
];
|
||
|
||
return new Date(...vals);
|
||
},
|
||
|
||
clone(date) {
|
||
return new Date(...this.get_date_values(date));
|
||
},
|
||
|
||
get_date_values(date) {
|
||
return [
|
||
date.getFullYear(),
|
||
date.getMonth(),
|
||
date.getDate(),
|
||
date.getHours(),
|
||
date.getMinutes(),
|
||
date.getSeconds(),
|
||
date.getMilliseconds(),
|
||
];
|
||
},
|
||
|
||
get_days_in_month(date) {
|
||
const no_of_days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
||
|
||
const month = date.getMonth();
|
||
|
||
if (month !== 1) {
|
||
return no_of_days[month];
|
||
}
|
||
|
||
// Feb
|
||
const year = date.getFullYear();
|
||
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
|
||
return 29;
|
||
}
|
||
return 28;
|
||
},
|
||
};
|
||
|
||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart
|
||
function padStart(str, targetLength, padString) {
|
||
str = str + '';
|
||
targetLength = targetLength >> 0;
|
||
padString = String(typeof padString !== 'undefined' ? padString : ' ');
|
||
if (str.length > targetLength) {
|
||
return String(str);
|
||
} else {
|
||
targetLength = targetLength - str.length;
|
||
if (targetLength > padString.length) {
|
||
padString += padString.repeat(targetLength / padString.length);
|
||
}
|
||
return padString.slice(0, targetLength) + String(str);
|
||
}
|
||
}
|