gantt/src/date_utils.js
2022-04-28 10:14:39 +05:30

326 lines
8.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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);
}
}