223 lines
6.8 KiB
TypeScript
223 lines
6.8 KiB
TypeScript
import { MapWorkingTime, WorkingTime } from '../types/schedule';
|
|
|
|
export const WEEK_DAY = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'];
|
|
const MAX_DAY_TIME = 24 * 60; // min
|
|
|
|
const addWeekDay = (weekDay?: string): string => {
|
|
const ind = weekDay ? WEEK_DAY.indexOf(weekDay) + 1 : 0;
|
|
return WEEK_DAY[ind >= WEEK_DAY.length ? 0 : ind];
|
|
}
|
|
|
|
const subWeekDay = (weekDay?: string): string => {
|
|
const ind = weekDay ? WEEK_DAY.indexOf(weekDay) - 1 : 0;
|
|
return WEEK_DAY[ind < 0 ? WEEK_DAY.length - 1 : ind];
|
|
}
|
|
|
|
export const getCurrentTime = (data: WorkingTime, timeZone: string): MapWorkingTime => {
|
|
let startDay = data.startDayOfWeekUtc;
|
|
let endDay = data.endDayOfWeekUtc;
|
|
const startUtc = data.startTimeUtc / (1000 * 1000 * 60);
|
|
const endUtc = data.endTimeUtc / (1000 * 1000 * 60);
|
|
const matches = timeZone.match(/(\+|-)([0-9]{2}):([0-9]{2})/) || [];
|
|
const sign = matches[1];
|
|
const h = matches[2];
|
|
const m = matches[3];
|
|
let startMin;
|
|
let endMin;
|
|
|
|
if (sign === '+') {
|
|
startMin = startUtc + (Number(h) * 60) + Number(m);
|
|
endMin = endUtc + (Number(h) * 60) + Number(m);
|
|
// startMin = startUtc;
|
|
// endMin = endUtc;
|
|
}
|
|
|
|
if (sign === '-') {
|
|
startMin = startUtc - (Number(h) * 60) - Number(m);
|
|
endMin = endUtc - (Number(h) * 60) - Number(m);
|
|
}
|
|
|
|
if (startMin >= MAX_DAY_TIME) {
|
|
startMin = 0;
|
|
// startMin = startMin - MAX_DAY_TIME;
|
|
// const ind = startDay ? WEEK_DAY.indexOf(startDay) + 1 : 0;
|
|
// startDay = WEEK_DAY[ind >= WEEK_DAY.length ? 0 : ind];
|
|
}
|
|
|
|
if (endMin >= MAX_DAY_TIME) {
|
|
endMin = 0;
|
|
// endMin = endMin - MAX_DAY_TIME;
|
|
// const ind = endDay ? WEEK_DAY.indexOf(endDay) + 1 : 0;
|
|
// endDay = WEEK_DAY[ind >= WEEK_DAY.length ? 0 : ind];
|
|
}
|
|
|
|
if (startMin <= 0) {
|
|
startMin = 0;
|
|
// startMin = MAX_DAY_TIME - startMin;
|
|
// const ind = startDay ? WEEK_DAY.indexOf(startDay) - 1 : 0;
|
|
// startDay = WEEK_DAY[ind < 0 ? WEEK_DAY.length - 1 : ind];
|
|
}
|
|
|
|
if (endMin <= 0) {
|
|
endMin = 0;
|
|
// endMin = MAX_DAY_TIME - endMin;
|
|
// const ind = endDay ? WEEK_DAY.indexOf(endDay) - 1 : 0;
|
|
// endDay = WEEK_DAY[ind < 0 ? WEEK_DAY.length - 1 : ind];
|
|
}
|
|
|
|
return {
|
|
startDay,
|
|
startTimeMin: startMin,
|
|
endDay: endDay,
|
|
endTimeMin: endMin
|
|
}
|
|
};
|
|
|
|
export const getTimeString = (min: number) => {
|
|
const timeH = `${(min - min % 60)/60}`;
|
|
|
|
return `${timeH.length === 1 ? `0${timeH}` : timeH}:${min % 60 || '00'}`;
|
|
}
|
|
|
|
export const formattedSchedule = (workingTimes: WorkingTime[], timeZone: string): MapWorkingTime[] => (
|
|
workingTimes.map((time) => getCurrentTime(time, timeZone)) || []
|
|
);
|
|
|
|
export const getNewTime = (time: string): number => {
|
|
const timeArr = time.split(':');
|
|
|
|
return Number(timeArr[0]) * 60 + Number(timeArr[1]);
|
|
};
|
|
|
|
export const getTimeZoneOffset = (oldTime: string, newTime: string): { sign: string, offset: number } => {
|
|
// старая таймзона
|
|
const matches1 = oldTime.match(/(\+|-)([0-9]{2}):([0-9]{2})/) || [];
|
|
const sign1 = matches1[1];
|
|
const min1 = Number(matches1[2]) * 60 + Number(matches1[3]);
|
|
// новая таймзона
|
|
const matches2 = newTime.match(/(\+|-)([0-9]{2}):([0-9]{2})/) || [];
|
|
const sign2 = matches2[1];
|
|
const min2 = Number(matches2[2]) * 60 + Number(matches2[3]);
|
|
|
|
if (sign1 === '+' && sign2 === '+') {
|
|
if (min1 < min2) {
|
|
return {
|
|
sign: '+',
|
|
offset: min2 - min1
|
|
}
|
|
} else {
|
|
return {
|
|
sign: '-',
|
|
offset: min1 - min2
|
|
}
|
|
}
|
|
}
|
|
|
|
if (sign1 === '-' && sign2 === '-') {
|
|
if (min1 < min2) {
|
|
return {
|
|
sign: '-',
|
|
offset: min2 - min1
|
|
}
|
|
} else {
|
|
return {
|
|
sign: '+',
|
|
offset: min1 - min2
|
|
}
|
|
}
|
|
}
|
|
|
|
if (sign1 === '+' && sign2 === '-') {
|
|
return {
|
|
sign: '-',
|
|
offset: min1 + min2
|
|
}
|
|
}
|
|
|
|
if (sign1 === '-' && sign2 === '+') {
|
|
return {
|
|
sign: '+',
|
|
offset: min1 + min2
|
|
}
|
|
}
|
|
}
|
|
|
|
export const formattedTimeByOffset = (workTime: MapWorkingTime, objOffset: { sign: string, offset: number }): MapWorkingTime => {
|
|
if (objOffset.sign === '+') {
|
|
const resStartMin = workTime.startTimeMin + objOffset.offset;
|
|
const resEndMin = workTime.endTimeMin ? workTime.endTimeMin + objOffset.offset : workTime.endTimeMin;
|
|
|
|
return {
|
|
...workTime,
|
|
startTimeMin: resStartMin >= MAX_DAY_TIME ? 0 : resStartMin,
|
|
endTimeMin: resEndMin >= MAX_DAY_TIME ? 0 : resEndMin
|
|
}
|
|
}
|
|
|
|
if (objOffset.sign === '-') {
|
|
const resStartMin = workTime.startTimeMin - objOffset.offset;
|
|
const resEndMin = workTime.endTimeMin ? workTime.endTimeMin - objOffset.offset : workTime.endTimeMin;
|
|
|
|
return {
|
|
...workTime,
|
|
startTimeMin: resStartMin < 0 ? 0 : resStartMin,
|
|
endTimeMin: resEndMin < 0 ? 0 : resEndMin
|
|
}
|
|
}
|
|
|
|
return workTime;
|
|
};
|
|
|
|
const getResultTime = (data: MapWorkingTime, timeZone: string): WorkingTime => {
|
|
let startDayOfWeekUtc = data.startDay;
|
|
let endDayOfWeekUtc = data.startDay;
|
|
const matches = timeZone.match(/(\+|-)([0-9]{2}):([0-9]{2})/) || [];
|
|
const sign = matches[1];
|
|
const offset = (Number(matches[2]) * 60) + Number(matches[3]);
|
|
let startTime = data.startTimeMin;
|
|
let endTime = data.endTimeMin === 0 ? MAX_DAY_TIME : data.endTimeMin;
|
|
|
|
if (sign === '+') {
|
|
startTime = startTime - offset;
|
|
endTime = endTime - offset;
|
|
}
|
|
|
|
if (sign === '-') {
|
|
startTime = startTime + offset;
|
|
endTime = endTime + offset;
|
|
}
|
|
|
|
if (startTime >= MAX_DAY_TIME) {
|
|
startTime = startTime - MAX_DAY_TIME;
|
|
startDayOfWeekUtc = addWeekDay(startDayOfWeekUtc);
|
|
}
|
|
|
|
if (endTime >= MAX_DAY_TIME) {
|
|
endTime = endTime - MAX_DAY_TIME;
|
|
endDayOfWeekUtc = addWeekDay(endDayOfWeekUtc);
|
|
}
|
|
|
|
if (startTime < 0) {
|
|
startTime = MAX_DAY_TIME - Math.abs(startTime || 0);
|
|
startDayOfWeekUtc = subWeekDay(startDayOfWeekUtc);
|
|
}
|
|
|
|
if (endTime < 0) {
|
|
endTime = MAX_DAY_TIME - Math.abs(endTime || 0);
|
|
endDayOfWeekUtc = subWeekDay(endDayOfWeekUtc);
|
|
}
|
|
|
|
return {
|
|
startDayOfWeekUtc,
|
|
startTimeUtc: startTime * 1000 * 1000 * 60,
|
|
endDayOfWeekUtc,
|
|
endTimeUtc: endTime * 1000 * 1000 * 60
|
|
};
|
|
}
|
|
|
|
export const formattedWorkList = (workingList: MapWorkingTime[], timeZone: string): WorkingTime[] => (
|
|
workingList
|
|
.filter(({ startTimeMin, endTimeMin }) => !(!startTimeMin && !endTimeMin))
|
|
.map((time) => getResultTime(time, timeZone)) || []
|
|
);
|