UNPKG

omniserror

Version:

Abstraction over common javascript date management libraries

354 lines (281 loc) 8.59 kB
import { DateTime, Settings, Info } from "luxon"; import { IUtils, DateIOFormats } from "@date-io/core/IUtils"; const defaultFormats: DateIOFormats = { dayOfMonth: "d", fullDate: "DD", fullDateTime: "ff", fullDateTime12h: "DD, hh:mm a", fullDateTime24h: "DD, T", fullTime: "t", fullTime12h: "hh:mm a", fullTime24h: "HH:mm", hours12h: "hh", hours24h: "HH", keyboardDate: "D", keyboardDateTime: "D t", keyboardDateTime12h: "D hh:mm a", keyboardDateTime24h: "D T", minutes: "mm", seconds: "ss", month: "LLLL", monthAndDate: "MMMM d", monthAndYear: "LLLL yyyy", monthShort: "MMM", normalDate: "d MMMM", normalDateWithWeekday: "EEE, MMM d", shortDate: "MMM d", year: "yyyy" }; export default class LuxonUtils implements IUtils<DateTime> { public locale: string; public formats: DateIOFormats; constructor({ locale, formats }: { formats?: Partial<DateIOFormats>; locale?: string } = {}) { this.locale = locale || "en"; this.formats = Object.assign({}, defaultFormats, formats); } public date(value?: any) { if (typeof value === "undefined") { return DateTime.local(); } if (value === null) { return null; } if (typeof value === "string") { return DateTime.fromJSDate(new Date(value)); } if (value instanceof DateTime) { return value; } return DateTime.fromJSDate(value); } public toJsDate(value: DateTime) { return value.toJSDate(); } public parse(value: string, formatString: string) { if (value === "") { return null; } return DateTime.fromFormat(value, formatString); } /* istanbul ignore next */ public is12HourCycleInCurrentLocale() { if (typeof Intl === "undefined" || typeof Intl.DateTimeFormat === "undefined") { return true; // Luxon defaults to en-US if Intl not found } return Boolean( new Intl.DateTimeFormat(this.locale, { hour: "numeric" })?.resolvedOptions()?.hour12 ); } public getFormatHelperText(format: string) { // Unfortunately there is no way for luxon to retrieve readable formats from localized format return ""; } /* istanbul ignore next */ public getCurrentLocaleCode() { return this.locale || Settings.defaultLocale; } public addDays(date: DateTime, count: number) { return count < 0 ? date.minus({ days: Math.abs(count) }) : date.plus({ days: count }); } public addMonths(date: DateTime, count: number) { return count < 0 ? date.minus({ months: Math.abs(count) }) : date.plus({ months: count }); } public isValid(value: any) { if (value instanceof DateTime) { return value.isValid; } if (value === null) { return false; } return this.date(value).isValid; } public isEqual(value: any, comparing: any) { if (value === null && comparing === null) { return true; } // make sure that null will not be passed to this.date if (value === null || comparing === null) { return false; } return this.date(value).equals(this.date(comparing)); } public isSameDay(date: DateTime, comparing: DateTime) { return date.hasSame(comparing, "day"); } public isSameMonth(date: DateTime, comparing: DateTime) { return date.hasSame(comparing, "month"); } public isSameYear(date: DateTime, comparing: DateTime) { return date.hasSame(comparing, "year"); } public isSameHour(date: DateTime, comparing: DateTime) { return date.hasSame(comparing, "hour"); } public isAfter(value: DateTime, comparing: DateTime) { return value > comparing; } public isBefore(value: DateTime, comparing: DateTime) { return value < comparing; } public isBeforeDay(value: DateTime, comparing: DateTime) { const diff = value.diff(comparing.startOf("day"), "days").toObject(); return diff.days! < 0; } public isAfterDay(value: DateTime, comparing: DateTime) { const diff = value.diff(comparing.endOf("day"), "days").toObject(); return diff.days! > 0; } public isBeforeYear(value: DateTime, comparing: DateTime) { const diff = value.diff(comparing.startOf("year"), "years").toObject(); return diff.years! < 0; } public isAfterYear(value: DateTime, comparing: DateTime) { const diff = value.diff(comparing.endOf("year"), "years").toObject(); return diff.years! > 0; } public getDiff(value: DateTime, comparing: DateTime | string) { if (typeof comparing === "string") { comparing = DateTime.fromJSDate(new Date(comparing)); } return value.diff(comparing).as("millisecond"); } public startOfDay(value: DateTime) { return value.startOf("day"); } public endOfDay(value: DateTime) { return value.endOf("day"); } public format(date: DateTime, formatKey: keyof DateIOFormats) { return this.formatByString(date, this.formats[formatKey]); } public formatByString(date: DateTime, format: string) { return date.setLocale(this.locale).toFormat(format); } public formatNumber(numberToFormat: string) { return numberToFormat; } public getHours(value: DateTime) { return value.get("hour"); } public setHours(value: DateTime, count: number) { return value.set({ hour: count }); } public getMinutes(value: DateTime) { return value.get("minute"); } public setMinutes(value: DateTime, count: number) { return value.set({ minute: count }); } public getSeconds(value: DateTime) { return value.get("second"); } public setSeconds(value: DateTime, count: number) { return value.set({ second: count }); } public getMonth(value: DateTime) { // See https://github.com/moment/luxon/blob/master/docs/moment.md#major-functional-differences return value.get("month") - 1; } public setMonth(value: DateTime, count: number) { return value.set({ month: count + 1 }); } public getYear(value: DateTime) { return value.get("year"); } public setYear(value: DateTime, year: number) { return value.set({ year }); } public mergeDateAndTime(date: DateTime, time: DateTime) { return date.set({ second: time.second, hour: time.hour, minute: time.minute }); } public startOfMonth(value: DateTime) { return value.startOf("month"); } public endOfMonth(value: DateTime) { return value.endOf("month"); } public startOfWeek(value: DateTime) { return value.startOf("week"); } public endOfWeek(value: DateTime) { return value.endOf("week"); } public getNextMonth(value: DateTime) { return value.plus({ months: 1 }); } public getPreviousMonth(value: DateTime) { return value.minus({ months: 1 }); } public getMonthArray(date: DateTime) { const firstMonth = this.date(date).startOf("year"); const monthArray = [firstMonth]; while (monthArray.length < 12) { const prevMonth = monthArray[monthArray.length - 1]; monthArray.push(this.getNextMonth(prevMonth)); } return monthArray; } public getWeekdays() { return Info.weekdaysFormat("narrow", { locale: this.locale }); } public getWeekArray(date: DateTime) { const { days } = date .endOf("month") .endOf("week") .diff(date.startOf("month").startOf("week"), "days") .toObject(); const weeks: DateTime[][] = []; new Array<number>(Math.round(days!)) .fill(0) .map((_, i) => i) .map(day => date .startOf("month") .startOf("week") .plus({ days: day }) ) .forEach((v, i) => { if (i === 0 || (i % 7 === 0 && i > 6)) { weeks.push([v]); return; } weeks[weeks.length - 1].push(v); }); return weeks; } public getYearRange(start: DateTime, end: DateTime) { const startDate = this.date(start).startOf("year"); const endDate = this.date(end).endOf("year"); let current = startDate; const years: DateTime[] = []; while (current < endDate) { years.push(current); current = current.plus({ year: 1 }); } return years; } public getMeridiemText(ampm: "am" | "pm") { return Info.meridiems({ locale: this.locale }).find( v => v.toLowerCase() === ampm.toLowerCase() )!; } public isNull(date: DateTime | null) { return date === null; } public isWithinRange(date: DateTime, [start, end]: [DateTime, DateTime]) { return ( date.equals(start) || date.equals(end) || (this.isAfter(date, start) && this.isBefore(date, end)) ); } }