191 lines
5.5 KiB
TypeScript
191 lines
5.5 KiB
TypeScript
import { Task, ViewMode } from "../types/public-types";
|
|
import DateTimeFormatOptions = Intl.DateTimeFormatOptions;
|
|
import DateTimeFormat = Intl.DateTimeFormat;
|
|
|
|
type DateHelperScales =
|
|
| "year"
|
|
| "month"
|
|
| "day"
|
|
| "hour"
|
|
| "minute"
|
|
| "second"
|
|
| "millisecond";
|
|
|
|
const intlDTCache = {};
|
|
const getCachedDateTimeFormat = (locString: string | string[], opts: DateTimeFormatOptions = {}): DateTimeFormat => {
|
|
const key = JSON.stringify([locString, opts]);
|
|
let dtf = intlDTCache[key];
|
|
if (!dtf) {
|
|
dtf = new Intl.DateTimeFormat(locString, opts);
|
|
intlDTCache[key] = dtf;
|
|
}
|
|
return dtf;
|
|
};
|
|
|
|
|
|
export const addToDate = (
|
|
date: Date,
|
|
quantity: number,
|
|
scale: DateHelperScales
|
|
) => {
|
|
const newDate = new Date(
|
|
date.getFullYear() + (scale === "year" ? quantity : 0),
|
|
date.getMonth() + (scale === "month" ? quantity : 0),
|
|
date.getDate() + (scale === "day" ? quantity : 0),
|
|
date.getHours() + (scale === "hour" ? quantity : 0),
|
|
date.getMinutes() + (scale === "minute" ? quantity : 0),
|
|
date.getSeconds() + (scale === "second" ? quantity : 0),
|
|
date.getMilliseconds() + (scale === "millisecond" ? quantity : 0)
|
|
);
|
|
return newDate;
|
|
};
|
|
|
|
export const startOfDate = (date: Date, scale: DateHelperScales) => {
|
|
const scores = [
|
|
"millisecond",
|
|
"second",
|
|
"minute",
|
|
"hour",
|
|
"day",
|
|
"month",
|
|
"year",
|
|
];
|
|
|
|
const shouldReset = (_scale: DateHelperScales) => {
|
|
const maxScore = scores.indexOf(scale);
|
|
return scores.indexOf(_scale) <= maxScore;
|
|
};
|
|
const newDate = new Date(
|
|
date.getFullYear(),
|
|
shouldReset("year") ? 0 : date.getMonth(),
|
|
shouldReset("month") ? 1 : date.getDate(),
|
|
shouldReset("day") ? 0 : date.getHours(),
|
|
shouldReset("hour") ? 0 : date.getMinutes(),
|
|
shouldReset("minute") ? 0 : date.getSeconds(),
|
|
shouldReset("second") ? 0 : date.getMilliseconds()
|
|
);
|
|
return newDate;
|
|
};
|
|
|
|
export const ganttDateRange = (tasks: Task[], viewMode: ViewMode) => {
|
|
let newStartDate: Date = tasks[0].start;
|
|
let newEndDate: Date = tasks[0].start;
|
|
for (const task of tasks) {
|
|
if (task.start < newStartDate) {
|
|
newStartDate = task.start;
|
|
}
|
|
if (task.end > newEndDate) {
|
|
newEndDate = task.end;
|
|
}
|
|
}
|
|
switch (viewMode) {
|
|
case ViewMode.Month:
|
|
newStartDate = addToDate(newStartDate, -1, "month");
|
|
newStartDate = startOfDate(newStartDate, "month");
|
|
newEndDate = addToDate(newEndDate, 1, "year");
|
|
newEndDate = startOfDate(newEndDate, "year");
|
|
break;
|
|
case ViewMode.Week:
|
|
newStartDate = startOfDate(newStartDate, "day");
|
|
newEndDate = startOfDate(newEndDate, "day");
|
|
newStartDate = addToDate(getMonday(newStartDate), -7, "day");
|
|
newEndDate = addToDate(newEndDate, 1.5, "month");
|
|
break;
|
|
case ViewMode.Day:
|
|
newStartDate = startOfDate(newStartDate, "day");
|
|
newEndDate = startOfDate(newEndDate, "day");
|
|
newStartDate = addToDate(newStartDate, -1, "day");
|
|
newEndDate = addToDate(newEndDate, 19, "day");
|
|
break;
|
|
case ViewMode.QuarterDay:
|
|
newStartDate = startOfDate(newStartDate, "day");
|
|
newEndDate = startOfDate(newEndDate, "day");
|
|
newStartDate = addToDate(newStartDate, -1, "day");
|
|
newEndDate = addToDate(newEndDate, 66, "hour"); // 24(1 day)*3 - 6
|
|
break;
|
|
case ViewMode.HalfDay:
|
|
newStartDate = startOfDate(newStartDate, "day");
|
|
newEndDate = startOfDate(newEndDate, "day");
|
|
newStartDate = addToDate(newStartDate, -1, "day");
|
|
newEndDate = addToDate(newEndDate, 108, "hour"); // 24(1 day)*5 - 12
|
|
break;
|
|
}
|
|
return [newStartDate, newEndDate];
|
|
};
|
|
|
|
export const seedDates = (
|
|
startDate: Date,
|
|
endDate: Date,
|
|
viewMode: ViewMode
|
|
) => {
|
|
let currentDate: Date = new Date(startDate);
|
|
const dates: Date[] = [currentDate];
|
|
while (currentDate < endDate) {
|
|
switch (viewMode) {
|
|
case ViewMode.Month:
|
|
currentDate = addToDate(currentDate, 1, "month");
|
|
break;
|
|
case ViewMode.Week:
|
|
currentDate = addToDate(currentDate, 7, "day");
|
|
break;
|
|
case ViewMode.Day:
|
|
currentDate = addToDate(currentDate, 1, "day");
|
|
break;
|
|
case ViewMode.HalfDay:
|
|
currentDate = addToDate(currentDate, 12, "hour");
|
|
break;
|
|
case ViewMode.QuarterDay:
|
|
currentDate = addToDate(currentDate, 6, "hour");
|
|
break;
|
|
}
|
|
dates.push(currentDate);
|
|
}
|
|
return dates;
|
|
};
|
|
|
|
export const getLocaleMonth = (date: Date, locale: string) => {
|
|
let bottomValue = getCachedDateTimeFormat(locale, {
|
|
month: "long",
|
|
}).format(date);
|
|
bottomValue = bottomValue.replace(
|
|
bottomValue[0],
|
|
bottomValue[0].toLocaleUpperCase()
|
|
);
|
|
return bottomValue;
|
|
};
|
|
|
|
/**
|
|
* Returns monday of current week
|
|
* @param date date for modify
|
|
*/
|
|
const getMonday = (date: Date) => {
|
|
const day = date.getDay();
|
|
const diff = date.getDate() - day + (day === 0 ? -6 : 1); // adjust when day is sunday
|
|
return new Date(date.setDate(diff));
|
|
};
|
|
|
|
export const getWeekNumberISO8601 = (date: Date) => {
|
|
const tmpDate = new Date(date.valueOf());
|
|
const dayNumber = (tmpDate.getDay() + 6) % 7;
|
|
tmpDate.setDate(tmpDate.getDate() - dayNumber + 3);
|
|
const firstThursday = tmpDate.valueOf();
|
|
tmpDate.setMonth(0, 1);
|
|
if (tmpDate.getDay() !== 4) {
|
|
tmpDate.setMonth(0, 1 + ((4 - tmpDate.getDay() + 7) % 7));
|
|
}
|
|
const weekNumber = (
|
|
1 + Math.ceil((firstThursday - tmpDate.valueOf()) / 604800000)
|
|
).toString();
|
|
|
|
if (weekNumber.length === 1) {
|
|
return `0${weekNumber}`;
|
|
} else {
|
|
return weekNumber;
|
|
}
|
|
};
|
|
|
|
export const getDaysInMonth = (month: number, year: number) => {
|
|
return new Date(year, month + 1, 0).getDate();
|
|
};
|
|
|