routie dev init since i didn't adhere to any proper guidance up until now
This commit is contained in:
+1
@@ -0,0 +1 @@
|
||||
export declare function isLeapYear(year: number): boolean;
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
export function isLeapYear(year) {
|
||||
return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;
|
||||
}
|
||||
//# sourceMappingURL=dateTimeUtils.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"dateTimeUtils.js","names":["isLeapYear","year"],"sources":["../../../../src/components/VCalendar/util/dateTimeUtils.ts"],"sourcesContent":["export function isLeapYear (year: number): boolean {\n return ((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0)\n}\n"],"mappings":"AAAA,OAAO,SAASA,UAAUA,CAAEC,IAAY,EAAW;EACjD,OAASA,IAAI,GAAG,CAAC,KAAK,CAAC,IAAMA,IAAI,GAAG,GAAG,KAAK,CAAE,IAAMA,IAAI,GAAG,GAAG,KAAK,CAAE;AACvE","ignoreList":[]}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
import type { CalendarEvent, CalendarEventParsed, CalendarTimestamp } from '../types.js';
|
||||
export declare function parseEvent(input: CalendarEvent, index: number, startProperty: string, endProperty: string, timed?: boolean, category?: string | false): CalendarEventParsed;
|
||||
export declare function isEventOn(event: CalendarEventParsed, dayIdentifier: number): boolean;
|
||||
export declare function isEventOnDay(event: CalendarEventParsed, day: CalendarTimestamp, inRange?: [number, number]): boolean;
|
||||
export declare function isEventHiddenOn(event: CalendarEventParsed, day: CalendarTimestamp): boolean;
|
||||
export declare function isEventStart(event: CalendarEventParsed, day: CalendarTimestamp, dayIdentifier: number, firstWeekday: number): boolean;
|
||||
export declare function isEventOverlapping(event: CalendarEventParsed, startIdentifier: number, endIdentifier: number): boolean;
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
import { copyTimestamp, getDayIdentifier, getTimestampIdentifier, isTimedless, nextMinutes, parseTimestamp, updateHasTime } from "./timestamp.js"; // Types
|
||||
export function parseEvent(input, index, startProperty, endProperty, timed = false, category = false) {
|
||||
const startInput = input[startProperty];
|
||||
const endInput = input[endProperty];
|
||||
const startParsed = parseTimestamp(startInput, true);
|
||||
const endParsed = endInput ? parseTimestamp(endInput, true) : startParsed;
|
||||
const start = isTimedless(startInput) ? updateHasTime(startParsed, timed) : startParsed;
|
||||
const end = isTimedless(endInput) ? updateHasTime(endParsed, timed) : endParsed;
|
||||
const startIdentifier = getDayIdentifier(start);
|
||||
const startTimestampIdentifier = getTimestampIdentifier(start);
|
||||
const endIdentifier = getDayIdentifier(end);
|
||||
const endOffset = start.hasTime ? 0 : 2359;
|
||||
const endTimestampIdentifier = getTimestampIdentifier(end) + endOffset;
|
||||
const allDay = !start.hasTime;
|
||||
return {
|
||||
input,
|
||||
start,
|
||||
startIdentifier,
|
||||
startTimestampIdentifier,
|
||||
end,
|
||||
endIdentifier,
|
||||
endTimestampIdentifier,
|
||||
allDay,
|
||||
index,
|
||||
category
|
||||
};
|
||||
}
|
||||
export function isEventOn(event, dayIdentifier) {
|
||||
return dayIdentifier >= event.startIdentifier && dayIdentifier <= event.endIdentifier;
|
||||
}
|
||||
export function isEventOnDay(event, day, inRange) {
|
||||
if (inRange) {
|
||||
const dayStart = nextMinutes(copyTimestamp(day), inRange[0]);
|
||||
const dayEnd = nextMinutes(copyTimestamp(day), inRange[1]);
|
||||
const starts = event.startTimestampIdentifier < getTimestampIdentifier(dayEnd);
|
||||
const ends = event.endTimestampIdentifier > getTimestampIdentifier(dayStart);
|
||||
return starts && ends;
|
||||
}
|
||||
return isEventOn(event, getDayIdentifier(day));
|
||||
}
|
||||
export function isEventHiddenOn(event, day) {
|
||||
return event.end.time === '00:00' && event.end.date === day.date && event.start.date !== day.date;
|
||||
}
|
||||
export function isEventStart(event, day, dayIdentifier, firstWeekday) {
|
||||
return dayIdentifier === event.startIdentifier || firstWeekday === day.weekday && isEventOn(event, dayIdentifier);
|
||||
}
|
||||
export function isEventOverlapping(event, startIdentifier, endIdentifier) {
|
||||
return startIdentifier <= event.endIdentifier && endIdentifier >= event.startIdentifier;
|
||||
}
|
||||
//# sourceMappingURL=events.js.map
|
||||
+1
File diff suppressed because one or more lines are too long
+3
@@ -0,0 +1,3 @@
|
||||
import type { CalendarCategory, CalendarCategoryTextFunction } from '../types.js';
|
||||
export declare function parsedCategoryText(category: CalendarCategory, categoryText: string | CalendarCategoryTextFunction | undefined): string;
|
||||
export declare function getParsedCategories(categories: CalendarCategory | CalendarCategory[], categoryText: string | CalendarCategoryTextFunction | undefined): CalendarCategory[];
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
// Types
|
||||
|
||||
export function parsedCategoryText(category, categoryText) {
|
||||
return typeof categoryText === 'function' ? categoryText(category) : typeof categoryText === 'string' && typeof category === 'object' && category ? category[categoryText] : typeof category === 'string' ? category : '';
|
||||
}
|
||||
export function getParsedCategories(categories, categoryText) {
|
||||
if (typeof categories === 'string') return categories.split(/\s*,\s/);
|
||||
if (Array.isArray(categories)) {
|
||||
return categories.map(category => {
|
||||
if (typeof category === 'string') return category;
|
||||
const categoryName = typeof category.categoryName === 'string' ? category.categoryName : parsedCategoryText(category, categoryText);
|
||||
return {
|
||||
...category,
|
||||
categoryName
|
||||
};
|
||||
});
|
||||
}
|
||||
return [];
|
||||
}
|
||||
//# sourceMappingURL=parser.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"parser.js","names":["parsedCategoryText","category","categoryText","getParsedCategories","categories","split","Array","isArray","map","categoryName"],"sources":["../../../../src/components/VCalendar/util/parser.ts"],"sourcesContent":["// Types\nimport type { CalendarCategory, CalendarCategoryTextFunction } from '../types'\n\nexport function parsedCategoryText (\n category: CalendarCategory,\n categoryText: string | CalendarCategoryTextFunction | undefined\n): string {\n return typeof categoryText === 'function' ? categoryText(category)\n : typeof categoryText === 'string' && typeof category === 'object' && category ? category[categoryText]\n : typeof category === 'string' ? category\n : ''\n}\n\nexport function getParsedCategories (\n categories: CalendarCategory | CalendarCategory[],\n categoryText: string | CalendarCategoryTextFunction | undefined\n): CalendarCategory[] {\n if (typeof categories === 'string') return categories.split(/\\s*,\\s/)\n if (Array.isArray(categories)) {\n return categories.map((category: CalendarCategory) => {\n if (typeof category === 'string') return category\n\n const categoryName = typeof category.categoryName === 'string'\n ? category.categoryName\n : parsedCategoryText(category, categoryText)\n return { ...category, categoryName }\n })\n }\n return []\n}\n"],"mappings":"AAAA;;AAGA,OAAO,SAASA,kBAAkBA,CAChCC,QAA0B,EAC1BC,YAA+D,EACvD;EACR,OAAO,OAAOA,YAAY,KAAK,UAAU,GAAGA,YAAY,CAACD,QAAQ,CAAC,GAC9D,OAAOC,YAAY,KAAK,QAAQ,IAAI,OAAOD,QAAQ,KAAK,QAAQ,IAAIA,QAAQ,GAAGA,QAAQ,CAACC,YAAY,CAAC,GACrG,OAAOD,QAAQ,KAAK,QAAQ,GAAGA,QAAQ,GACvC,EAAE;AACR;AAEA,OAAO,SAASE,mBAAmBA,CACjCC,UAAiD,EACjDF,YAA+D,EAC3C;EACpB,IAAI,OAAOE,UAAU,KAAK,QAAQ,EAAE,OAAOA,UAAU,CAACC,KAAK,CAAC,QAAQ,CAAC;EACrE,IAAIC,KAAK,CAACC,OAAO,CAACH,UAAU,CAAC,EAAE;IAC7B,OAAOA,UAAU,CAACI,GAAG,CAAEP,QAA0B,IAAK;MACpD,IAAI,OAAOA,QAAQ,KAAK,QAAQ,EAAE,OAAOA,QAAQ;MAEjD,MAAMQ,YAAY,GAAG,OAAOR,QAAQ,CAACQ,YAAY,KAAK,QAAQ,GAC1DR,QAAQ,CAACQ,YAAY,GACrBT,kBAAkB,CAACC,QAAQ,EAAEC,YAAY,CAAC;MAC9C,OAAO;QAAE,GAAGD,QAAQ;QAAEQ;MAAa,CAAC;IACtC,CAAC,CAAC;EACJ;EACA,OAAO,EAAE;AACX","ignoreList":[]}
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
import type { CalendarFormatter, CalendarTimestamp } from '../types.js';
|
||||
export declare const PARSE_REGEX: RegExp;
|
||||
export declare const PARSE_TIME: RegExp;
|
||||
export declare const DAYS_IN_MONTH: number[];
|
||||
export declare const DAYS_IN_MONTH_LEAP: number[];
|
||||
export declare const DAYS_IN_MONTH_MIN = 28;
|
||||
export declare const DAYS_IN_MONTH_MAX = 31;
|
||||
export declare const MONTH_MAX = 12;
|
||||
export declare const MONTH_MIN = 1;
|
||||
export declare const DAY_MIN = 1;
|
||||
export declare const DAYS_IN_WEEK = 7;
|
||||
export declare const MINUTES_IN_HOUR = 60;
|
||||
export declare const MINUTE_MAX = 59;
|
||||
export declare const MINUTES_IN_DAY: number;
|
||||
export declare const HOURS_IN_DAY = 24;
|
||||
export declare const HOUR_MAX = 23;
|
||||
export declare const FIRST_HOUR = 0;
|
||||
export declare const OFFSET_YEAR = 10000;
|
||||
export declare const OFFSET_MONTH = 100;
|
||||
export declare const OFFSET_HOUR = 100;
|
||||
export declare const OFFSET_TIME = 10000;
|
||||
type CalendarTimestampFormatOptions = (timestamp: CalendarTimestamp, short: boolean) => Intl.DateTimeFormatOptions;
|
||||
type CalendarTimestampOperation = (timestamp: CalendarTimestamp) => CalendarTimestamp;
|
||||
export type VTime = number | string | {
|
||||
hour: number;
|
||||
minute: number;
|
||||
};
|
||||
export type VTimestampInput = number | string | Date;
|
||||
export declare function getStartOfWeek(timestamp: CalendarTimestamp, weekdays: number[], today?: CalendarTimestamp): CalendarTimestamp;
|
||||
export declare function getEndOfWeek(timestamp: CalendarTimestamp, weekdays: number[], today?: CalendarTimestamp): CalendarTimestamp;
|
||||
export declare function getStartOfMonth(timestamp: CalendarTimestamp): CalendarTimestamp;
|
||||
export declare function getEndOfMonth(timestamp: CalendarTimestamp): CalendarTimestamp;
|
||||
export declare function validateNumber(input: any): boolean;
|
||||
export declare function validateTime(input: any): input is VTime;
|
||||
export declare function parseTime(input: any): number | false;
|
||||
export declare function validateTimestamp(input: any): input is VTimestampInput;
|
||||
export declare function parseTimestamp(input: VTimestampInput | null, required?: false, now?: CalendarTimestamp | null): CalendarTimestamp | null;
|
||||
export declare function parseTimestamp(input: VTimestampInput, required: true, now?: CalendarTimestamp): CalendarTimestamp;
|
||||
export declare function parseDate(date: Date): CalendarTimestamp;
|
||||
export declare function getDayIdentifier(timestamp: {
|
||||
year: number;
|
||||
month: number;
|
||||
day: number;
|
||||
}): number;
|
||||
export declare function getTimeIdentifier(timestamp: {
|
||||
hour: number;
|
||||
minute: number;
|
||||
}): number;
|
||||
export declare function getTimestampIdentifier(timestamp: CalendarTimestamp): number;
|
||||
export declare function updateRelative(timestamp: CalendarTimestamp, now: CalendarTimestamp, time?: boolean): CalendarTimestamp;
|
||||
export declare function isTimedless(input: VTimestampInput): input is (Date | number);
|
||||
export declare function updateHasTime(timestamp: CalendarTimestamp, hasTime: boolean, now?: CalendarTimestamp): CalendarTimestamp;
|
||||
export declare function updateMinutes(timestamp: CalendarTimestamp, minutes: number, now?: CalendarTimestamp): CalendarTimestamp;
|
||||
export declare function updateWeekday(timestamp: CalendarTimestamp): CalendarTimestamp;
|
||||
export declare function updateFormatted(timestamp: CalendarTimestamp): CalendarTimestamp;
|
||||
export declare function getWeekday(timestamp: CalendarTimestamp): number;
|
||||
export declare function daysInMonth(year: number, month: number): number;
|
||||
export declare function copyTimestamp(timestamp: null): null;
|
||||
export declare function copyTimestamp(timestamp: CalendarTimestamp): CalendarTimestamp;
|
||||
export declare function padNumber(x: number, length: number): string;
|
||||
export declare function getDate(timestamp: CalendarTimestamp): string;
|
||||
export declare function getTime(timestamp: CalendarTimestamp): string;
|
||||
export declare function nextMinutes(timestamp: CalendarTimestamp, minutes: number): CalendarTimestamp;
|
||||
export declare function nextDay(timestamp: CalendarTimestamp): CalendarTimestamp;
|
||||
export declare function prevDay(timestamp: CalendarTimestamp): CalendarTimestamp;
|
||||
export declare function relativeDays(timestamp: CalendarTimestamp, mover?: CalendarTimestampOperation, days?: number): CalendarTimestamp;
|
||||
export declare function diffMinutes(min: CalendarTimestamp, max: CalendarTimestamp): number;
|
||||
export declare function findWeekday(timestamp: CalendarTimestamp, weekday: number, mover?: CalendarTimestampOperation, maxDays?: number): CalendarTimestamp;
|
||||
export declare function getWeekdaySkips(weekdays: number[]): number[];
|
||||
export declare function timestampToDate(timestamp: CalendarTimestamp): Date;
|
||||
export declare function createDayList(start: CalendarTimestamp, end: CalendarTimestamp, now: CalendarTimestamp, weekdaySkips: number[], max?: number, min?: number): CalendarTimestamp[];
|
||||
export declare function createIntervalList(timestamp: CalendarTimestamp, first: number, minutes: number, count: number, now?: CalendarTimestamp): CalendarTimestamp[];
|
||||
export declare function createNativeLocaleFormatter(locale: string, getOptions: CalendarTimestampFormatOptions): CalendarFormatter;
|
||||
export declare function validateWeekdays(input: string | (number | string)[]): boolean;
|
||||
|
||||
+437
@@ -0,0 +1,437 @@
|
||||
import { isLeapYear } from "./dateTimeUtils.js"; // Types
|
||||
export const PARSE_REGEX = /^(\d{4})-(\d{1,2})(-(\d{1,2}))?([^\d]+(\d{1,2}))?(:(\d{1,2}))?(:(\d{1,2}))?$/;
|
||||
export const PARSE_TIME = /(\d\d?)(:(\d\d?)|)(:(\d\d?)|)/;
|
||||
export const DAYS_IN_MONTH = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
||||
export const DAYS_IN_MONTH_LEAP = [0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
||||
export const DAYS_IN_MONTH_MIN = 28;
|
||||
export const DAYS_IN_MONTH_MAX = 31;
|
||||
export const MONTH_MAX = 12;
|
||||
export const MONTH_MIN = 1;
|
||||
export const DAY_MIN = 1;
|
||||
export const DAYS_IN_WEEK = 7;
|
||||
export const MINUTES_IN_HOUR = 60;
|
||||
export const MINUTE_MAX = 59;
|
||||
export const MINUTES_IN_DAY = 24 * 60;
|
||||
export const HOURS_IN_DAY = 24;
|
||||
export const HOUR_MAX = 23;
|
||||
export const FIRST_HOUR = 0;
|
||||
export const OFFSET_YEAR = 10000;
|
||||
export const OFFSET_MONTH = 100;
|
||||
export const OFFSET_HOUR = 100;
|
||||
export const OFFSET_TIME = 10000;
|
||||
export function getStartOfWeek(timestamp, weekdays, today) {
|
||||
const start = copyTimestamp(timestamp);
|
||||
findWeekday(start, weekdays[0], prevDay);
|
||||
updateFormatted(start);
|
||||
if (today) {
|
||||
updateRelative(start, today, start.hasTime);
|
||||
}
|
||||
return start;
|
||||
}
|
||||
export function getEndOfWeek(timestamp, weekdays, today) {
|
||||
const end = copyTimestamp(timestamp);
|
||||
findWeekday(end, weekdays[weekdays.length - 1]);
|
||||
updateFormatted(end);
|
||||
if (today) {
|
||||
updateRelative(end, today, end.hasTime);
|
||||
}
|
||||
return end;
|
||||
}
|
||||
export function getStartOfMonth(timestamp) {
|
||||
const start = copyTimestamp(timestamp);
|
||||
start.day = DAY_MIN;
|
||||
updateWeekday(start);
|
||||
updateFormatted(start);
|
||||
return start;
|
||||
}
|
||||
export function getEndOfMonth(timestamp) {
|
||||
const end = copyTimestamp(timestamp);
|
||||
end.day = daysInMonth(end.year, end.month);
|
||||
updateWeekday(end);
|
||||
updateFormatted(end);
|
||||
return end;
|
||||
}
|
||||
export function validateNumber(input) {
|
||||
return isFinite(parseInt(input));
|
||||
}
|
||||
export function validateTime(input) {
|
||||
return typeof input === 'number' && isFinite(input) || !!PARSE_TIME.exec(input) || typeof input === 'object' && isFinite(input.hour) && isFinite(input.minute);
|
||||
}
|
||||
export function parseTime(input) {
|
||||
if (typeof input === 'number') {
|
||||
// when a number is given, it's minutes since 12:00am
|
||||
return input;
|
||||
} else if (typeof input === 'string') {
|
||||
// when a string is given, it's a hh:mm:ss format where seconds are optional
|
||||
const parts = PARSE_TIME.exec(input);
|
||||
if (!parts) {
|
||||
return false;
|
||||
}
|
||||
return parseInt(parts[1]) * 60 + parseInt(parts[3] || 0);
|
||||
} else if (typeof input === 'object') {
|
||||
// when an object is given, it must have hour and minute
|
||||
if (typeof input.hour !== 'number' || typeof input.minute !== 'number') {
|
||||
return false;
|
||||
}
|
||||
return input.hour * 60 + input.minute;
|
||||
} else {
|
||||
// unsupported type
|
||||
return false;
|
||||
}
|
||||
}
|
||||
export function validateTimestamp(input) {
|
||||
return typeof input === 'number' && isFinite(input) || typeof input === 'string' && !!PARSE_REGEX.exec(input) || input instanceof Date;
|
||||
}
|
||||
export function parseTimestamp(input, required = false, now) {
|
||||
if (typeof input === 'number' && isFinite(input)) {
|
||||
input = new Date(input);
|
||||
}
|
||||
if (input instanceof Date) {
|
||||
const date = parseDate(input);
|
||||
if (now) {
|
||||
updateRelative(date, now, date.hasTime);
|
||||
}
|
||||
return date;
|
||||
}
|
||||
if (typeof input !== 'string') {
|
||||
if (required) {
|
||||
throw new Error(`${input} is not a valid timestamp. It must be a Date, number of milliseconds since Epoch, or a string in the format of YYYY-MM-DD or YYYY-MM-DD hh:mm. Zero-padding is optional and seconds are ignored.`);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// YYYY-MM-DD hh:mm:ss
|
||||
const parts = PARSE_REGEX.exec(input);
|
||||
if (!parts) {
|
||||
if (required) {
|
||||
throw new Error(`${input} is not a valid timestamp. It must be a Date, number of milliseconds since Epoch, or a string in the format of YYYY-MM-DD or YYYY-MM-DD hh:mm. Zero-padding is optional and seconds are ignored.`);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
const timestamp = {
|
||||
date: input,
|
||||
time: '',
|
||||
year: parseInt(parts[1]),
|
||||
month: parseInt(parts[2]),
|
||||
day: parseInt(parts[4]) || 1,
|
||||
hour: parseInt(parts[6]) || 0,
|
||||
minute: parseInt(parts[8]) || 0,
|
||||
weekday: 0,
|
||||
hasDay: !!parts[4],
|
||||
hasTime: !!(parts[6] && parts[8]),
|
||||
past: false,
|
||||
present: false,
|
||||
future: false
|
||||
};
|
||||
updateWeekday(timestamp);
|
||||
updateFormatted(timestamp);
|
||||
if (now) {
|
||||
updateRelative(timestamp, now, timestamp.hasTime);
|
||||
}
|
||||
return timestamp;
|
||||
}
|
||||
export function parseDate(date) {
|
||||
return updateFormatted({
|
||||
date: '',
|
||||
time: '',
|
||||
year: date.getFullYear(),
|
||||
month: date.getMonth() + 1,
|
||||
day: date.getDate(),
|
||||
weekday: date.getDay(),
|
||||
hour: date.getHours(),
|
||||
minute: date.getMinutes(),
|
||||
hasDay: true,
|
||||
hasTime: true,
|
||||
past: false,
|
||||
present: true,
|
||||
future: false
|
||||
});
|
||||
}
|
||||
export function getDayIdentifier(timestamp) {
|
||||
return timestamp.year * OFFSET_YEAR + timestamp.month * OFFSET_MONTH + timestamp.day;
|
||||
}
|
||||
export function getTimeIdentifier(timestamp) {
|
||||
return timestamp.hour * OFFSET_HOUR + timestamp.minute;
|
||||
}
|
||||
export function getTimestampIdentifier(timestamp) {
|
||||
return getDayIdentifier(timestamp) * OFFSET_TIME + getTimeIdentifier(timestamp);
|
||||
}
|
||||
export function updateRelative(timestamp, now, time = false) {
|
||||
let a = getDayIdentifier(now);
|
||||
let b = getDayIdentifier(timestamp);
|
||||
let present = a === b;
|
||||
if (timestamp.hasTime && time && present) {
|
||||
a = getTimeIdentifier(now);
|
||||
b = getTimeIdentifier(timestamp);
|
||||
present = a === b;
|
||||
}
|
||||
timestamp.past = b < a;
|
||||
timestamp.present = present;
|
||||
timestamp.future = b > a;
|
||||
return timestamp;
|
||||
}
|
||||
export function isTimedless(input) {
|
||||
return input instanceof Date || typeof input === 'number' && isFinite(input);
|
||||
}
|
||||
export function updateHasTime(timestamp, hasTime, now) {
|
||||
if (timestamp.hasTime !== hasTime) {
|
||||
timestamp.hasTime = hasTime;
|
||||
if (!hasTime) {
|
||||
timestamp.hour = HOUR_MAX;
|
||||
timestamp.minute = MINUTE_MAX;
|
||||
timestamp.time = getTime(timestamp);
|
||||
}
|
||||
if (now) {
|
||||
updateRelative(timestamp, now, timestamp.hasTime);
|
||||
}
|
||||
}
|
||||
return timestamp;
|
||||
}
|
||||
export function updateMinutes(timestamp, minutes, now) {
|
||||
timestamp.hasTime = true;
|
||||
timestamp.hour = 0;
|
||||
timestamp.minute = 0;
|
||||
nextMinutes(timestamp, minutes);
|
||||
updateFormatted(timestamp);
|
||||
if (now) {
|
||||
updateRelative(timestamp, now, true);
|
||||
}
|
||||
return timestamp;
|
||||
}
|
||||
export function updateWeekday(timestamp) {
|
||||
timestamp.weekday = getWeekday(timestamp);
|
||||
return timestamp;
|
||||
}
|
||||
export function updateFormatted(timestamp) {
|
||||
timestamp.time = getTime(timestamp);
|
||||
timestamp.date = getDate(timestamp);
|
||||
return timestamp;
|
||||
}
|
||||
export function getWeekday(timestamp) {
|
||||
if (timestamp.hasDay) {
|
||||
const _ = Math.floor;
|
||||
const k = timestamp.day;
|
||||
const m = (timestamp.month + 9) % MONTH_MAX + 1;
|
||||
const C = _(timestamp.year / 100);
|
||||
const Y = timestamp.year % 100 - (timestamp.month <= 2 ? 1 : 0);
|
||||
return ((k + _(2.6 * m - 0.2) - 2 * C + Y + _(Y / 4) + _(C / 4)) % 7 + 7) % 7;
|
||||
}
|
||||
return timestamp.weekday;
|
||||
}
|
||||
export function daysInMonth(year, month) {
|
||||
return isLeapYear(year) ? DAYS_IN_MONTH_LEAP[month] : DAYS_IN_MONTH[month];
|
||||
}
|
||||
export function copyTimestamp(timestamp) {
|
||||
if (timestamp == null) return null;
|
||||
const {
|
||||
date,
|
||||
time,
|
||||
year,
|
||||
month,
|
||||
day,
|
||||
weekday,
|
||||
hour,
|
||||
minute,
|
||||
hasDay,
|
||||
hasTime,
|
||||
past,
|
||||
present,
|
||||
future
|
||||
} = timestamp;
|
||||
return {
|
||||
date,
|
||||
time,
|
||||
year,
|
||||
month,
|
||||
day,
|
||||
weekday,
|
||||
hour,
|
||||
minute,
|
||||
hasDay,
|
||||
hasTime,
|
||||
past,
|
||||
present,
|
||||
future
|
||||
};
|
||||
}
|
||||
export function padNumber(x, length) {
|
||||
let padded = String(x);
|
||||
while (padded.length < length) {
|
||||
padded = '0' + padded;
|
||||
}
|
||||
return padded;
|
||||
}
|
||||
export function getDate(timestamp) {
|
||||
let str = `${padNumber(timestamp.year, 4)}-${padNumber(timestamp.month, 2)}`;
|
||||
if (timestamp.hasDay) str += `-${padNumber(timestamp.day, 2)}`;
|
||||
return str;
|
||||
}
|
||||
export function getTime(timestamp) {
|
||||
if (!timestamp.hasTime) {
|
||||
return '';
|
||||
}
|
||||
return `${padNumber(timestamp.hour, 2)}:${padNumber(timestamp.minute, 2)}`;
|
||||
}
|
||||
export function nextMinutes(timestamp, minutes) {
|
||||
timestamp.minute += minutes;
|
||||
while (timestamp.minute >= MINUTES_IN_HOUR) {
|
||||
timestamp.minute -= MINUTES_IN_HOUR;
|
||||
timestamp.hour++;
|
||||
if (timestamp.hour >= HOURS_IN_DAY) {
|
||||
nextDay(timestamp);
|
||||
timestamp.hour = FIRST_HOUR;
|
||||
}
|
||||
}
|
||||
return timestamp;
|
||||
}
|
||||
export function nextDay(timestamp) {
|
||||
timestamp.day++;
|
||||
timestamp.weekday = (timestamp.weekday + 1) % DAYS_IN_WEEK;
|
||||
if (timestamp.day > DAYS_IN_MONTH_MIN && timestamp.day > daysInMonth(timestamp.year, timestamp.month)) {
|
||||
timestamp.day = DAY_MIN;
|
||||
timestamp.month++;
|
||||
if (timestamp.month > MONTH_MAX) {
|
||||
timestamp.month = MONTH_MIN;
|
||||
timestamp.year++;
|
||||
}
|
||||
}
|
||||
return timestamp;
|
||||
}
|
||||
export function prevDay(timestamp) {
|
||||
timestamp.day--;
|
||||
timestamp.weekday = (timestamp.weekday + 6) % DAYS_IN_WEEK;
|
||||
if (timestamp.day < DAY_MIN) {
|
||||
timestamp.month--;
|
||||
if (timestamp.month < MONTH_MIN) {
|
||||
timestamp.year--;
|
||||
timestamp.month = MONTH_MAX;
|
||||
}
|
||||
timestamp.day = daysInMonth(timestamp.year, timestamp.month);
|
||||
}
|
||||
return timestamp;
|
||||
}
|
||||
export function relativeDays(timestamp, mover = nextDay, days = 1) {
|
||||
while (--days >= 0) mover(timestamp);
|
||||
return timestamp;
|
||||
}
|
||||
export function diffMinutes(min, max) {
|
||||
const Y = (max.year - min.year) * 525600;
|
||||
const M = (max.month - min.month) * 43800;
|
||||
const D = (max.day - min.day) * 1440;
|
||||
const h = (max.hour - min.hour) * 60;
|
||||
const m = max.minute - min.minute;
|
||||
return Y + M + D + h + m;
|
||||
}
|
||||
export function findWeekday(timestamp, weekday, mover = nextDay, maxDays = 6) {
|
||||
while (timestamp.weekday !== weekday && --maxDays >= 0) mover(timestamp);
|
||||
return timestamp;
|
||||
}
|
||||
export function getWeekdaySkips(weekdays) {
|
||||
const skips = [1, 1, 1, 1, 1, 1, 1];
|
||||
const filled = [0, 0, 0, 0, 0, 0, 0];
|
||||
for (let i = 0; i < weekdays.length; i++) {
|
||||
filled[weekdays[i]] = 1;
|
||||
}
|
||||
for (let k = 0; k < DAYS_IN_WEEK; k++) {
|
||||
let skip = 1;
|
||||
for (let j = 1; j < DAYS_IN_WEEK; j++) {
|
||||
const next = (k + j) % DAYS_IN_WEEK;
|
||||
if (filled[next]) {
|
||||
break;
|
||||
}
|
||||
skip++;
|
||||
}
|
||||
skips[k] = filled[k] * skip;
|
||||
}
|
||||
return skips;
|
||||
}
|
||||
export function timestampToDate(timestamp) {
|
||||
const time = `${padNumber(timestamp.hour, 2)}:${padNumber(timestamp.minute, 2)}`;
|
||||
const date = timestamp.date;
|
||||
return new Date(`${date}T${time}:00+00:00`);
|
||||
}
|
||||
export function createDayList(start, end, now, weekdaySkips, max = 42, min = 0) {
|
||||
const stop = getDayIdentifier(end);
|
||||
const days = [];
|
||||
let current = copyTimestamp(start);
|
||||
let currentIdentifier = 0;
|
||||
let stopped = currentIdentifier === stop;
|
||||
if (stop < getDayIdentifier(start)) {
|
||||
throw new Error('End date is earlier than start date.');
|
||||
}
|
||||
while ((!stopped || days.length < min) && days.length < max) {
|
||||
currentIdentifier = getDayIdentifier(current);
|
||||
stopped = stopped || currentIdentifier === stop;
|
||||
if (weekdaySkips[current.weekday] === 0) {
|
||||
current = nextDay(current);
|
||||
continue;
|
||||
}
|
||||
const day = copyTimestamp(current);
|
||||
updateFormatted(day);
|
||||
updateRelative(day, now);
|
||||
days.push(day);
|
||||
current = relativeDays(current, nextDay, weekdaySkips[current.weekday]);
|
||||
}
|
||||
if (!days.length) throw new Error('No dates found using specified start date, end date, and weekdays.');
|
||||
return days;
|
||||
}
|
||||
export function createIntervalList(timestamp, first, minutes, count, now) {
|
||||
const intervals = [];
|
||||
for (let i = 0; i < count; i++) {
|
||||
const mins = first + i * minutes;
|
||||
const int = copyTimestamp(timestamp);
|
||||
intervals.push(updateMinutes(int, mins, now));
|
||||
}
|
||||
return intervals;
|
||||
}
|
||||
export function createNativeLocaleFormatter(locale, getOptions) {
|
||||
const emptyFormatter = (_t, _s) => '';
|
||||
if (typeof Intl === 'undefined' || typeof Intl.DateTimeFormat === 'undefined') {
|
||||
return emptyFormatter;
|
||||
}
|
||||
return (timestamp, short) => {
|
||||
try {
|
||||
const intlFormatter = new Intl.DateTimeFormat(locale || undefined, getOptions(timestamp, short));
|
||||
return intlFormatter.format(timestampToDate(timestamp));
|
||||
} catch (e) {
|
||||
return '';
|
||||
}
|
||||
};
|
||||
}
|
||||
export function validateWeekdays(input) {
|
||||
if (typeof input === 'string') {
|
||||
input = input.split(',');
|
||||
}
|
||||
if (Array.isArray(input)) {
|
||||
const ints = input.map(x => parseInt(x));
|
||||
if (ints.length > DAYS_IN_WEEK || ints.length === 0) {
|
||||
return false;
|
||||
}
|
||||
const visited = {};
|
||||
let wrapped = false;
|
||||
for (let i = 0; i < ints.length; i++) {
|
||||
const x = ints[i];
|
||||
if (!isFinite(x) || x < 0 || x >= DAYS_IN_WEEK) {
|
||||
return false;
|
||||
}
|
||||
if (i > 0) {
|
||||
const d = x - ints[i - 1];
|
||||
if (d < 0) {
|
||||
if (wrapped) {
|
||||
return false;
|
||||
}
|
||||
wrapped = true;
|
||||
} else if (d === 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (visited[x]) {
|
||||
return false;
|
||||
}
|
||||
visited[x] = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//# sourceMappingURL=timestamp.js.map
|
||||
+1
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user