scdate 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Eric Vera
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,5 @@
1
+ # scdate
2
+
3
+ Time zone free readable dates and times
4
+
5
+ _This package is in active pre-release development so there may be breaking changed until v1.0 is released._
@@ -0,0 +1,9 @@
1
+ export declare enum Weekday {
2
+ Sun = 1,
3
+ Mon = 2,
4
+ Tue = 4,
5
+ Wed = 8,
6
+ Thu = 16,
7
+ Fri = 32,
8
+ Sat = 64
9
+ }
@@ -0,0 +1,10 @@
1
+ export var Weekday;
2
+ (function (Weekday) {
3
+ Weekday[Weekday["Sun"] = 1] = "Sun";
4
+ Weekday[Weekday["Mon"] = 2] = "Mon";
5
+ Weekday[Weekday["Tue"] = 4] = "Tue";
6
+ Weekday[Weekday["Wed"] = 8] = "Wed";
7
+ Weekday[Weekday["Thu"] = 16] = "Thu";
8
+ Weekday[Weekday["Fri"] = 32] = "Fri";
9
+ Weekday[Weekday["Sat"] = 64] = "Sat";
10
+ })(Weekday || (Weekday = {}));
@@ -0,0 +1,5 @@
1
+ export * from './constants';
2
+ export * from './sDate';
3
+ export * from './sTime';
4
+ export * from './sTimestamp';
5
+ export * from './sWeekdays';
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export * from './constants';
2
+ export * from './sDate';
3
+ export * from './sTime';
4
+ export * from './sTimestamp';
5
+ export * from './sWeekdays';
@@ -0,0 +1,5 @@
1
+ export declare class SDate {
2
+ readonly date: string;
3
+ constructor(isoValue: string);
4
+ toJSON(): string;
5
+ }
@@ -0,0 +1,11 @@
1
+ import { validateISODate } from './date';
2
+ export class SDate {
3
+ date;
4
+ constructor(isoValue) {
5
+ validateISODate(isoValue);
6
+ this.date = isoValue;
7
+ }
8
+ toJSON() {
9
+ return this.date;
10
+ }
11
+ }
@@ -0,0 +1,5 @@
1
+ export declare class STime {
2
+ readonly time: string;
3
+ constructor(isoValue: string);
4
+ toJSON(): string;
5
+ }
@@ -0,0 +1,11 @@
1
+ import { validateISOTime } from './time';
2
+ export class STime {
3
+ time;
4
+ constructor(isoValue) {
5
+ validateISOTime(isoValue);
6
+ this.time = isoValue;
7
+ }
8
+ toJSON() {
9
+ return this.time;
10
+ }
11
+ }
@@ -0,0 +1,5 @@
1
+ export declare class STimestamp {
2
+ readonly timestamp: string;
3
+ constructor(timestamp: string);
4
+ toJSON(): string;
5
+ }
@@ -0,0 +1,11 @@
1
+ import { validateISOTimestamp } from './timestamp';
2
+ export class STimestamp {
3
+ timestamp;
4
+ constructor(timestamp) {
5
+ validateISOTimestamp(timestamp);
6
+ this.timestamp = timestamp;
7
+ }
8
+ toJSON() {
9
+ return this.timestamp;
10
+ }
11
+ }
@@ -0,0 +1,5 @@
1
+ export declare class SWeekdays {
2
+ readonly weekdays: string;
3
+ constructor(weekdays: string);
4
+ toJSON(): string;
5
+ }
@@ -0,0 +1,11 @@
1
+ import { validateWeekdays } from './weekdays';
2
+ export class SWeekdays {
3
+ weekdays;
4
+ constructor(weekdays) {
5
+ validateWeekdays(weekdays);
6
+ this.weekdays = weekdays;
7
+ }
8
+ toJSON() {
9
+ return this.weekdays;
10
+ }
11
+ }
@@ -0,0 +1,2 @@
1
+ import { Weekday } from '../constants';
2
+ export declare const DayToWeekday: Weekday[];
@@ -0,0 +1,10 @@
1
+ import { Weekday } from '../constants';
2
+ export const DayToWeekday = [
3
+ Weekday.Sun,
4
+ Weekday.Mon,
5
+ Weekday.Tue,
6
+ Weekday.Wed,
7
+ Weekday.Thu,
8
+ Weekday.Fri,
9
+ Weekday.Sat,
10
+ ];
@@ -0,0 +1,8 @@
1
+ import { UTCDateMini } from '@date-fns/utc';
2
+ import { SDate } from './SDate';
3
+ export declare const getISOYearFromISODate: (isoDate: string) => string;
4
+ export declare const getISOMonthFromISODate: (isoDate: string) => string;
5
+ export declare const getISODateFromISODate: (isoDate: string) => string;
6
+ export declare const getISODateFromZonedDate: (date: Date) => string;
7
+ export declare const validateISODate: (isoDate: string) => void;
8
+ export declare const getDateAsUTCDateMini: (date: SDate) => UTCDateMini;
@@ -0,0 +1,35 @@
1
+ import { UTCDateMini } from '@date-fns/utc';
2
+ import { formatISO } from 'date-fns';
3
+ export const getISOYearFromISODate = (isoDate) => {
4
+ const EndOfYearIndex = 4;
5
+ return isoDate.slice(0, EndOfYearIndex);
6
+ };
7
+ export const getISOMonthFromISODate = (isoDate) => {
8
+ const StartOfMonthIndex = 5;
9
+ const EndOfMonthIndex = 7;
10
+ return isoDate.slice(StartOfMonthIndex, EndOfMonthIndex);
11
+ };
12
+ export const getISODateFromISODate = (isoDate) => {
13
+ const StartOfDateIndex = 8;
14
+ return isoDate.slice(StartOfDateIndex);
15
+ };
16
+ export const getISODateFromZonedDate = (date) => {
17
+ const EndOfISODateIndex = 10;
18
+ return formatISO(date).slice(0, EndOfISODateIndex);
19
+ };
20
+ export const validateISODate = (isoDate) => {
21
+ const ValidISODate = /^\d{4}-\d{2}-\d{2}$/;
22
+ if (!ValidISODate.test(isoDate)) {
23
+ throw new Error(`Invalid date format. Expected format: YYYY-MM-DD. Current value: '${isoDate}'.`);
24
+ }
25
+ const year = Number(getISOYearFromISODate(isoDate));
26
+ const month = Number(getISOMonthFromISODate(isoDate)) - 1;
27
+ const date = Number(getISODateFromISODate(isoDate));
28
+ const nativeDate = new Date(year, month, date);
29
+ if (nativeDate.getFullYear() !== year ||
30
+ nativeDate.getMonth() !== month ||
31
+ nativeDate.getDate() !== date) {
32
+ throw new Error(`Invalid ISO date value. Current value: '${isoDate}'.`);
33
+ }
34
+ };
35
+ export const getDateAsUTCDateMini = (date) => new UTCDateMini(`${date.date}T00:00z`);
@@ -0,0 +1,4 @@
1
+ export declare const getISOHoursFromISOTime: (isoTime: string) => string;
2
+ export declare const getISOMinutesFromISOTime: (isoTime: string) => string;
3
+ export declare const getISOTimeFromDate: (date: Date) => string;
4
+ export declare const validateISOTime: (isoTime: string) => void;
@@ -0,0 +1,28 @@
1
+ import { formatISO } from 'date-fns';
2
+ export const getISOHoursFromISOTime = (isoTime) => {
3
+ const EndOfHoursIndex = 2;
4
+ return isoTime.slice(0, EndOfHoursIndex);
5
+ };
6
+ export const getISOMinutesFromISOTime = (isoTime) => {
7
+ const StartOfMinutesIndex = 3;
8
+ return isoTime.slice(StartOfMinutesIndex);
9
+ };
10
+ export const getISOTimeFromDate = (date) => {
11
+ const StartOfISOTimeIndex = 11;
12
+ const EndOfISOTimeIndex = 16;
13
+ return formatISO(date).slice(StartOfISOTimeIndex, EndOfISOTimeIndex);
14
+ };
15
+ export const validateISOTime = (isoTime) => {
16
+ const ValidISOTime = /^\d{2}:\d{2}$/;
17
+ if (!ValidISOTime.test(isoTime)) {
18
+ throw new Error(`Invalid time format. Expected format: HH:MM. Current value: '${isoTime}'.`);
19
+ }
20
+ const hours = Number(getISOHoursFromISOTime(isoTime));
21
+ const minutes = Number(getISOMinutesFromISOTime(isoTime));
22
+ const nativeDate = new Date();
23
+ nativeDate.setHours(hours);
24
+ nativeDate.setMinutes(minutes);
25
+ if (nativeDate.getMinutes() !== minutes || nativeDate.getHours() !== hours) {
26
+ throw new Error(`Invalid ISO time value. Expected from 00:00 to 23:59. Current value: '${isoTime}'.`);
27
+ }
28
+ };
@@ -0,0 +1,7 @@
1
+ import { UTCDateMini } from '@date-fns/utc';
2
+ import { STimestamp } from './STimestamp';
3
+ export declare const getISODateFromISOTimestamp: (isoTimestamp: string) => string;
4
+ export declare const getISOTimeFromISOTimestamp: (isoTimestamp: string) => string;
5
+ export declare const getISOTimestampFromZonedDate: (date: Date) => string;
6
+ export declare const validateISOTimestamp: (isoTimestamp: string) => void;
7
+ export declare const getTimestampAsUTCDateMini: (timestamp: STimestamp) => UTCDateMini;
@@ -0,0 +1,27 @@
1
+ import { UTCDateMini } from '@date-fns/utc';
2
+ import { formatISO } from 'date-fns';
3
+ import { validateISODate } from './date';
4
+ import { validateISOTime } from './time';
5
+ export const getISODateFromISOTimestamp = (isoTimestamp) => {
6
+ const EndOfDateIndex = 10;
7
+ return isoTimestamp.slice(0, EndOfDateIndex);
8
+ };
9
+ export const getISOTimeFromISOTimestamp = (isoTimestamp) => {
10
+ const StartOfTimeIndex = 11;
11
+ return isoTimestamp.slice(StartOfTimeIndex);
12
+ };
13
+ export const getISOTimestampFromZonedDate = (date) => {
14
+ const ISOTimestampLength = 16;
15
+ return formatISO(date).slice(0, ISOTimestampLength);
16
+ };
17
+ export const validateISOTimestamp = (isoTimestamp) => {
18
+ const ValidISOTimestamp = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}$/;
19
+ if (!ValidISOTimestamp.test(isoTimestamp)) {
20
+ throw new Error(`Invalid date and time format. Expected format: YYYY-MM-DDTHH:MM. Current value: '${isoTimestamp}'.`);
21
+ }
22
+ const isoDate = getISODateFromISOTimestamp(isoTimestamp);
23
+ validateISODate(isoDate);
24
+ const isoTime = getISOTimeFromISOTimestamp(isoTimestamp);
25
+ validateISOTime(isoTime);
26
+ };
27
+ export const getTimestampAsUTCDateMini = (timestamp) => new UTCDateMini(`${timestamp.timestamp}z`);
@@ -0,0 +1,2 @@
1
+ export declare const hasFlag: (flags: number, checkFlag: number) => boolean;
2
+ export declare const getAtIndex: <T extends string | unknown[]>(arrayOrString: T, index: number) => T[number];
@@ -0,0 +1,8 @@
1
+ export const hasFlag = (flags, checkFlag) => (flags & checkFlag) === checkFlag;
2
+ export const getAtIndex = (arrayOrString, index) => {
3
+ const value = arrayOrString[index];
4
+ if (value === undefined) {
5
+ throw new Error(`Value at index ${String(index)} is undefined.`);
6
+ }
7
+ return value;
8
+ };
@@ -0,0 +1,3 @@
1
+ import { Weekday } from '../constants';
2
+ export declare const validateWeekdays: (weekdays: string) => void;
3
+ export declare const getIndexForWeekday: (weekday: Weekday) => number;
@@ -0,0 +1,15 @@
1
+ import { DayToWeekday } from './constants';
2
+ export const validateWeekdays = (weekdays) => {
3
+ const ValidWeekdays = /^[S-][M-][T-][W-][T-][F-][S-]$/;
4
+ if (!ValidWeekdays.test(weekdays)) {
5
+ throw new Error(`Invalid weekdays format. Expected format: SMTWTFS. Any of the values can be replaced with a '-'. Current value: '${weekdays}'.`);
6
+ }
7
+ return;
8
+ };
9
+ export const getIndexForWeekday = (weekday) => {
10
+ const weekdayIndex = DayToWeekday.indexOf(weekday);
11
+ if (weekdayIndex < 0) {
12
+ throw new Error(`Invalid weekday '${String(weekday)}'. Expected a single weekday.`);
13
+ }
14
+ return weekdayIndex;
15
+ };
@@ -0,0 +1,5 @@
1
+ import { SDate } from './SDate';
2
+ import { STimestamp } from './STimestamp';
3
+ export declare const getMillisecondsInUTCFromTimestamp: (timestamp: STimestamp, timeZone: string) => number;
4
+ export declare const getMillisecondsInUTCFromDate: (date: SDate, timeZone: string) => number;
5
+ export declare const getTimeZonedDate: (millisecondsInUTC: number, timeZone: string) => Date;
@@ -0,0 +1,30 @@
1
+ import { getTimezoneOffset, toZonedTime } from 'date-fns-tz';
2
+ import { getDateAsUTCDateMini } from './date';
3
+ import { getTimestampAsUTCDateMini } from './timestamp';
4
+ const getValidatedTimeZoneOffset = (timeZone, utcDate) => {
5
+ const timeZoneOffset = getTimezoneOffset(timeZone, utcDate);
6
+ if (isNaN(timeZoneOffset)) {
7
+ throw new Error(`Invalid time zone. Time zone: '${timeZone}'`);
8
+ }
9
+ return timeZoneOffset;
10
+ };
11
+ export const getMillisecondsInUTCFromTimestamp = (timestamp, timeZone) => {
12
+ const utcDate = getTimestampAsUTCDateMini(timestamp);
13
+ const timeZoneOffset = getValidatedTimeZoneOffset(timeZone, utcDate);
14
+ return utcDate.getTime() - timeZoneOffset;
15
+ };
16
+ export const getMillisecondsInUTCFromDate = (date, timeZone) => {
17
+ const utcDate = getDateAsUTCDateMini(date);
18
+ const timeZoneOffset = getValidatedTimeZoneOffset(timeZone, utcDate);
19
+ return utcDate.getTime() - timeZoneOffset;
20
+ };
21
+ export const getTimeZonedDate = (millisecondsInUTC, timeZone) => {
22
+ if (isNaN(millisecondsInUTC.valueOf())) {
23
+ throw new Error(`Invalid date. Date: '${String(millisecondsInUTC.valueOf())}'`);
24
+ }
25
+ const zonedDate = toZonedTime(millisecondsInUTC, timeZone);
26
+ if (isNaN(zonedDate.valueOf())) {
27
+ throw new Error(`Invalid time zone. Time zone: '${timeZone}'`);
28
+ }
29
+ return zonedDate;
30
+ };
@@ -0,0 +1,33 @@
1
+ import { Weekday } from './constants';
2
+ import { SDate } from './internal/SDate';
3
+ export interface SDateShortStringOptions {
4
+ includeWeekday: boolean;
5
+ onTodayText: () => string;
6
+ }
7
+ export declare const sDate: (date: string | SDate) => SDate;
8
+ export declare const getDateToday: (timeZone: string) => SDate;
9
+ export declare const getNextDateByWeekday: (date: string | SDate, weekday: Weekday) => SDate;
10
+ export declare const getPreviousDateByWeekday: (date: string | SDate, weekday: Weekday) => SDate;
11
+ export declare const getDateForFirstDayOfMonth: (date: string | SDate) => SDate;
12
+ export declare const getDateForLastDayOfMonth: (date: string | SDate) => SDate;
13
+ export declare const getYearFromDate: (date: string | SDate) => number;
14
+ export declare const getMonthFromDate: (date: string | SDate) => number;
15
+ export declare const getDateFromDate: (date: string | SDate) => number;
16
+ export declare const getWeekdayFromDate: (date: string | SDate) => number;
17
+ export declare const getTimeZonedDateFromDate: (date: string | SDate, timeZone: string) => Date;
18
+ export declare const getDaysBetweenDates: (date1: string | SDate, date2: string | SDate) => number;
19
+ export declare const getFullDateString: (date: string | SDate, locale: Intl.LocalesArgument) => string;
20
+ export declare const getShortDateString: (date: string | SDate, timeZone: string, locale: Intl.LocalesArgument, options: SDateShortStringOptions) => string;
21
+ export declare const addDaysToDate: (date: string | SDate, days: number) => SDate;
22
+ export declare const addMonthsToDate: (date: string | SDate, months: number) => SDate;
23
+ export declare const addYearsToDate: (date: string | SDate, years: number) => SDate;
24
+ export declare const isSameDate: (date1: string | SDate, date2: string | SDate) => boolean;
25
+ export declare const isBeforeDate: (date1: string | SDate, date2: string | SDate) => boolean;
26
+ export declare const isSameDateOrBefore: (date1: string | SDate, date2: string | SDate) => boolean;
27
+ export declare const isAfterDate: (date1: string | SDate, date2: string | SDate) => boolean;
28
+ export declare const isSameDateOrAfter: (date1: string | SDate, date2: string | SDate) => boolean;
29
+ export declare const isDateToday: (date: string | SDate, timeZone: string) => boolean;
30
+ export declare const areDatesInSameMonth: (date1: string | SDate, date2: string | SDate) => boolean;
31
+ export declare const isDateInCurrentMonth: (date: string | SDate, timeZone: string) => boolean;
32
+ export declare const areDatesInSameYear: (date1: string | SDate, date2: string | SDate) => boolean;
33
+ export declare const isDateInCurrentYear: (date: string | SDate, timeZone: string) => boolean;
package/dist/sDate.js ADDED
@@ -0,0 +1,166 @@
1
+ import { differenceInDays, lastDayOfMonth } from 'date-fns';
2
+ import { daysInWeek } from 'date-fns/constants';
3
+ import { SDate } from './internal/SDate';
4
+ import { DayToWeekday } from './internal/constants';
5
+ import { getDateAsUTCDateMini, getISODateFromISODate, getISODateFromZonedDate, getISOMonthFromISODate, getISOYearFromISODate, } from './internal/date';
6
+ import { getAtIndex } from './internal/utils';
7
+ import { getIndexForWeekday } from './internal/weekdays';
8
+ import { getMillisecondsInUTCFromDate, getTimeZonedDate, } from './internal/zoned';
9
+ export const sDate = (date) => {
10
+ if (date instanceof SDate) {
11
+ return date;
12
+ }
13
+ return new SDate(date);
14
+ };
15
+ export const getDateToday = (timeZone) => {
16
+ const date = getTimeZonedDate(Date.now(), timeZone);
17
+ return sDate(getISODateFromZonedDate(date));
18
+ };
19
+ export const getNextDateByWeekday = (date, weekday) => {
20
+ const sDateValue = sDate(date);
21
+ const weekdayIndex = getIndexForWeekday(weekday);
22
+ const todaysWeekdayIndex = DayToWeekday.indexOf(getWeekdayFromDate(sDateValue));
23
+ let adjustment = weekdayIndex - todaysWeekdayIndex;
24
+ if (adjustment <= 0) {
25
+ adjustment += daysInWeek;
26
+ }
27
+ return addDaysToDate(sDateValue, adjustment);
28
+ };
29
+ export const getPreviousDateByWeekday = (date, weekday) => {
30
+ const sDateValue = sDate(date);
31
+ const weekdayIndex = getIndexForWeekday(weekday);
32
+ const todaysWeekdayIndex = DayToWeekday.indexOf(getWeekdayFromDate(sDateValue));
33
+ let adjustment = weekdayIndex - todaysWeekdayIndex;
34
+ if (adjustment >= 0) {
35
+ adjustment -= daysInWeek;
36
+ }
37
+ return addDaysToDate(sDateValue, adjustment);
38
+ };
39
+ export const getDateForFirstDayOfMonth = (date) => {
40
+ const sDateValue = sDate(date);
41
+ const nativeDate = getDateAsUTCDateMini(sDateValue);
42
+ nativeDate.setDate(1);
43
+ return sDate(getISODateFromZonedDate(nativeDate));
44
+ };
45
+ export const getDateForLastDayOfMonth = (date) => {
46
+ const sDateValue = sDate(date);
47
+ const nativeDate = getDateAsUTCDateMini(sDateValue);
48
+ const lastDay = lastDayOfMonth(nativeDate);
49
+ return sDate(getISODateFromZonedDate(lastDay));
50
+ };
51
+ export const getYearFromDate = (date) => {
52
+ const sDateValue = sDate(date);
53
+ return Number(getISOYearFromISODate(sDateValue.date));
54
+ };
55
+ export const getMonthFromDate = (date) => {
56
+ const sDateValue = sDate(date);
57
+ return Number(getISOMonthFromISODate(sDateValue.date)) - 1;
58
+ };
59
+ export const getDateFromDate = (date) => {
60
+ const sDateValue = sDate(date);
61
+ return Number(getISODateFromISODate(sDateValue.date));
62
+ };
63
+ export const getWeekdayFromDate = (date) => {
64
+ const sDateValue = sDate(date);
65
+ const nativeDate = getDateAsUTCDateMini(sDateValue);
66
+ return getAtIndex(DayToWeekday, nativeDate.getDay());
67
+ };
68
+ export const getTimeZonedDateFromDate = (date, timeZone) => {
69
+ const sDateValue = sDate(date);
70
+ const milliseconds = getMillisecondsInUTCFromDate(sDateValue, timeZone);
71
+ const zonedTime = getTimeZonedDate(milliseconds, timeZone);
72
+ return zonedTime;
73
+ };
74
+ export const getDaysBetweenDates = (date1, date2) => {
75
+ const sDate1 = sDate(date1);
76
+ const sDate2 = sDate(date2);
77
+ return differenceInDays(getDateAsUTCDateMini(sDate2), getDateAsUTCDateMini(sDate1));
78
+ };
79
+ export const getFullDateString = (date, locale) => {
80
+ const sDateValue = sDate(date);
81
+ const utcDate = getDateAsUTCDateMini(sDateValue);
82
+ return utcDate.toLocaleDateString(locale, {
83
+ timeZone: 'UTC',
84
+ dateStyle: 'full',
85
+ });
86
+ };
87
+ export const getShortDateString = (date, timeZone, locale, options) => {
88
+ const sDateValue = sDate(date);
89
+ if (isDateToday(sDateValue, timeZone)) {
90
+ return options.onTodayText();
91
+ }
92
+ const utcDate = getDateAsUTCDateMini(sDateValue);
93
+ return utcDate.toLocaleDateString(locale, {
94
+ timeZone: 'UTC',
95
+ month: 'short',
96
+ day: 'numeric',
97
+ weekday: options.includeWeekday ? 'short' : undefined,
98
+ year: isDateInCurrentYear(sDateValue, timeZone) ? undefined : '2-digit',
99
+ });
100
+ };
101
+ export const addDaysToDate = (date, days) => {
102
+ const sDateValue = sDate(date);
103
+ const nativeDate = getDateAsUTCDateMini(sDateValue);
104
+ nativeDate.setDate(nativeDate.getDate() + days);
105
+ return sDate(getISODateFromZonedDate(nativeDate));
106
+ };
107
+ export const addMonthsToDate = (date, months) => {
108
+ const sDateValue = sDate(date);
109
+ const nativeDate = getDateAsUTCDateMini(sDateValue);
110
+ nativeDate.setMonth(nativeDate.getMonth() + months);
111
+ return sDate(getISODateFromZonedDate(nativeDate));
112
+ };
113
+ export const addYearsToDate = (date, years) => {
114
+ const sDateValue = sDate(date);
115
+ const nativeDate = getDateAsUTCDateMini(sDateValue);
116
+ nativeDate.setFullYear(nativeDate.getFullYear() + years);
117
+ return sDate(getISODateFromZonedDate(nativeDate));
118
+ };
119
+ export const isSameDate = (date1, date2) => {
120
+ const sDate1 = sDate(date1);
121
+ const sDate2 = sDate(date2);
122
+ return sDate1.date === sDate2.date;
123
+ };
124
+ export const isBeforeDate = (date1, date2) => {
125
+ const sDate1 = sDate(date1);
126
+ const sDate2 = sDate(date2);
127
+ return sDate1.date < sDate2.date;
128
+ };
129
+ export const isSameDateOrBefore = (date1, date2) => {
130
+ const sDate1 = sDate(date1);
131
+ const sDate2 = sDate(date2);
132
+ return sDate1.date <= sDate2.date;
133
+ };
134
+ export const isAfterDate = (date1, date2) => {
135
+ const sDate1 = sDate(date1);
136
+ const sDate2 = sDate(date2);
137
+ return sDate1.date > sDate2.date;
138
+ };
139
+ export const isSameDateOrAfter = (date1, date2) => {
140
+ const sDate1 = sDate(date1);
141
+ const sDate2 = sDate(date2);
142
+ return sDate1.date >= sDate2.date;
143
+ };
144
+ export const isDateToday = (date, timeZone) => {
145
+ const sDateValue = sDate(date);
146
+ return isSameDate(sDateValue, getDateToday(timeZone));
147
+ };
148
+ export const areDatesInSameMonth = (date1, date2) => {
149
+ const sDate1 = sDate(date1);
150
+ const sDate2 = sDate(date2);
151
+ return (getISOYearFromISODate(sDate1.date) === getISOYearFromISODate(sDate2.date) &&
152
+ getISOMonthFromISODate(sDate1.date) === getISOMonthFromISODate(sDate2.date));
153
+ };
154
+ export const isDateInCurrentMonth = (date, timeZone) => {
155
+ const sDateValue = sDate(date);
156
+ return areDatesInSameMonth(sDateValue, getDateToday(timeZone));
157
+ };
158
+ export const areDatesInSameYear = (date1, date2) => {
159
+ const sDate1 = sDate(date1);
160
+ const sDate2 = sDate(date2);
161
+ return (getISOYearFromISODate(sDate1.date) === getISOYearFromISODate(sDate2.date));
162
+ };
163
+ export const isDateInCurrentYear = (date, timeZone) => {
164
+ const sDateValue = sDate(date);
165
+ return areDatesInSameYear(sDateValue, getDateToday(timeZone));
166
+ };
@@ -0,0 +1,18 @@
1
+ import { STime } from './internal/STime';
2
+ export declare const sTime: (time: string | STime) => STime;
3
+ export declare const getTimeNow: (timeZone: string) => STime;
4
+ export declare const getTimeAtMidnight: () => STime;
5
+ export declare const getTimeFromMinutes: (timeInMinutes: number) => STime;
6
+ export declare const getHoursFromTime: (time: string | STime) => number;
7
+ export declare const getHoursStringFromTime: (time: string | STime) => string;
8
+ export declare const getMinutesFromTime: (time: string | STime) => number;
9
+ export declare const getMinutesStringFromTime: (time: string | STime) => string;
10
+ export declare const get12HourTimeString: (time: string | STime) => string;
11
+ export declare const getTimeInMinutes: (time: string | STime, midnightIs24?: boolean) => number;
12
+ export declare const addMinutesToTime: (time: string | STime, minutes: number) => STime;
13
+ export declare const isSameTime: (time1: string | STime, time2: string | STime) => boolean;
14
+ export declare const isAfterTime: (time1: string | STime, time2: string | STime) => boolean;
15
+ export declare const isSameTimeOrAfter: (time1: string | STime, time2: string | STime) => boolean;
16
+ export declare const isBeforeTime: (time1: string | STime, time2: string | STime) => boolean;
17
+ export declare const isSameTimeOrBefore: (time1: string | STime, time2: string | STime) => boolean;
18
+ export declare const isTimePM: (time: string | STime) => boolean;
package/dist/sTime.js ADDED
@@ -0,0 +1,90 @@
1
+ import { minutesInDay, minutesInHour } from 'date-fns/constants';
2
+ import { STime } from './internal/STime';
3
+ import { getISOHoursFromISOTime, getISOMinutesFromISOTime, getISOTimeFromDate, } from './internal/time';
4
+ import { getTimeZonedDate } from './internal/zoned';
5
+ export const sTime = (time) => {
6
+ if (time instanceof STime) {
7
+ return time;
8
+ }
9
+ return new STime(time);
10
+ };
11
+ export const getTimeNow = (timeZone) => {
12
+ const date = getTimeZonedDate(Date.now(), timeZone);
13
+ return sTime(getISOTimeFromDate(date));
14
+ };
15
+ export const getTimeAtMidnight = () => sTime('00:00');
16
+ export const getTimeFromMinutes = (timeInMinutes) => {
17
+ const midnight = getTimeAtMidnight();
18
+ return addMinutesToTime(midnight, timeInMinutes);
19
+ };
20
+ export const getHoursFromTime = (time) => {
21
+ const sTimeValue = sTime(time);
22
+ return Number(getISOHoursFromISOTime(sTimeValue.time));
23
+ };
24
+ export const getHoursStringFromTime = (time) => {
25
+ const HoursPMStart = 12;
26
+ const sTimeValue = sTime(time);
27
+ const hours = getHoursFromTime(sTimeValue) % HoursPMStart;
28
+ return hours === 0 ? '12' : hours.toString();
29
+ };
30
+ export const getMinutesFromTime = (time) => {
31
+ const sTimeValue = sTime(time);
32
+ return Number(getISOMinutesFromISOTime(sTimeValue.time));
33
+ };
34
+ export const getMinutesStringFromTime = (time) => {
35
+ const sTimeValue = sTime(time);
36
+ return getISOMinutesFromISOTime(sTimeValue.time);
37
+ };
38
+ export const get12HourTimeString = (time) => {
39
+ const sTimeValue = sTime(time);
40
+ return `${getHoursStringFromTime(sTimeValue)}:${getMinutesStringFromTime(sTimeValue)} ${isTimePM(sTimeValue) ? 'PM' : 'AM'}`;
41
+ };
42
+ export const getTimeInMinutes = (time, midnightIs24 = false) => {
43
+ const sTimeValue = sTime(time);
44
+ const timeInMinutesMidnight0 = getHoursFromTime(sTimeValue) * minutesInHour +
45
+ getMinutesFromTime(sTimeValue);
46
+ if (midnightIs24 && timeInMinutesMidnight0 === 0) {
47
+ return minutesInDay;
48
+ }
49
+ return timeInMinutesMidnight0;
50
+ };
51
+ export const addMinutesToTime = (time, minutes) => {
52
+ const sTimeValue = sTime(time);
53
+ let totalMinutes = (getTimeInMinutes(sTimeValue) + minutes) % minutesInDay;
54
+ if (totalMinutes < 0) {
55
+ totalMinutes += minutesInDay;
56
+ }
57
+ const newHours = Math.floor(totalMinutes / minutesInHour);
58
+ const newMinutes = totalMinutes % minutesInHour;
59
+ return sTime(`${newHours.toString().padStart(2, '0')}:${newMinutes.toString().padStart(2, '0')}`);
60
+ };
61
+ export const isSameTime = (time1, time2) => {
62
+ const sTime1 = sTime(time1);
63
+ const sTime2 = sTime(time2);
64
+ return sTime1.time === sTime2.time;
65
+ };
66
+ export const isAfterTime = (time1, time2) => {
67
+ const sTime1 = sTime(time1);
68
+ const sTime2 = sTime(time2);
69
+ return sTime1.time > sTime2.time;
70
+ };
71
+ export const isSameTimeOrAfter = (time1, time2) => {
72
+ const sTime1 = sTime(time1);
73
+ const sTime2 = sTime(time2);
74
+ return sTime1.time >= sTime2.time;
75
+ };
76
+ export const isBeforeTime = (time1, time2) => {
77
+ const sTime1 = sTime(time1);
78
+ const sTime2 = sTime(time2);
79
+ return sTime1.time < sTime2.time;
80
+ };
81
+ export const isSameTimeOrBefore = (time1, time2) => {
82
+ const sTime1 = sTime(time1);
83
+ const sTime2 = sTime(time2);
84
+ return sTime1.time <= sTime2.time;
85
+ };
86
+ export const isTimePM = (time) => {
87
+ const sTimeValue = sTime(time);
88
+ const NoonValue = '12:00';
89
+ return sTimeValue.time >= NoonValue;
90
+ };
@@ -0,0 +1,23 @@
1
+ import { SDate } from './internal/SDate';
2
+ import { STime } from './internal/STime';
3
+ import { STimestamp } from './internal/STimestamp';
4
+ export interface STimestampShortStringOptions {
5
+ includeWeekday: boolean;
6
+ onTodayAtText: () => string;
7
+ }
8
+ export declare const sTimestamp: (timestamp: string | STimestamp) => STimestamp;
9
+ export declare const getTimestampFromUTCMilliseconds: (utcDateInMilliseconds: number, timeZone: string) => STimestamp;
10
+ export declare const getTimestampNow: (timeZone: string) => STimestamp;
11
+ export declare const getTimestampFromDateAndTime: (date: string | SDate, time: string | STime) => STimestamp;
12
+ export declare const getTimeZonedDateFromTimestamp: (timestamp: string | STimestamp, timeZone: string) => Date;
13
+ export declare const getSecondsToTimestamp: (timestamp: string | STimestamp, timeZone: string) => number;
14
+ export declare const getDateFromTimestamp: (timestamp: string | STimestamp) => SDate;
15
+ export declare const getTimeFromTimestamp: (timestamp: string | STimestamp) => STime;
16
+ export declare const getShortTimestampString: (timestamp: string | STimestamp, timeZone: string, locale: Intl.LocalesArgument, options: STimestampShortStringOptions) => string;
17
+ export declare const addDaysToTimestamp: (timestamp: string | STimestamp, days: number) => STimestamp;
18
+ export declare const addMinutesToTimestamp: (timestamp: string | STimestamp, minutes: number, timeZone: string) => STimestamp;
19
+ export declare const isSameTimestamp: (timestamp1: string | STimestamp, timestamp2: string | STimestamp) => boolean;
20
+ export declare const isBeforeTimestamp: (timestamp1: string | STimestamp, timestamp2: string | STimestamp) => boolean;
21
+ export declare const isSameTimestampOrBefore: (timestamp1: string | STimestamp, timestamp2: string | STimestamp) => boolean;
22
+ export declare const isAfterTimestamp: (timestamp1: string | STimestamp, timestamp2: string | STimestamp) => boolean;
23
+ export declare const isSameTimestampOrAfter: (timestamp1: string | STimestamp, timestamp2: string | STimestamp) => boolean;
@@ -0,0 +1,92 @@
1
+ import { millisecondsInMinute, millisecondsInSecond } from 'date-fns/constants';
2
+ import { STimestamp } from './internal/STimestamp';
3
+ import { getISODateFromISOTimestamp, getISOTimeFromISOTimestamp, getISOTimestampFromZonedDate, getTimestampAsUTCDateMini, } from './internal/timestamp';
4
+ import { getMillisecondsInUTCFromTimestamp, getTimeZonedDate, } from './internal/zoned';
5
+ import { getShortDateString, sDate } from './sDate';
6
+ import { get12HourTimeString, sTime } from './sTime';
7
+ export const sTimestamp = (timestamp) => {
8
+ if (timestamp instanceof STimestamp) {
9
+ return timestamp;
10
+ }
11
+ return new STimestamp(timestamp);
12
+ };
13
+ export const getTimestampFromUTCMilliseconds = (utcDateInMilliseconds, timeZone) => {
14
+ const date = getTimeZonedDate(utcDateInMilliseconds, timeZone);
15
+ return sTimestamp(getISOTimestampFromZonedDate(date));
16
+ };
17
+ export const getTimestampNow = (timeZone) => {
18
+ return getTimestampFromUTCMilliseconds(Date.now(), timeZone);
19
+ };
20
+ export const getTimestampFromDateAndTime = (date, time) => {
21
+ const sDateValue = sDate(date);
22
+ const sDimeValue = sTime(time);
23
+ return sTimestamp(`${sDateValue.date}T${sDimeValue.time}`);
24
+ };
25
+ export const getTimeZonedDateFromTimestamp = (timestamp, timeZone) => {
26
+ const sTimestampValue = sTimestamp(timestamp);
27
+ const dateInUTCMilliseconds = getMillisecondsInUTCFromTimestamp(sTimestampValue, timeZone);
28
+ return getTimeZonedDate(dateInUTCMilliseconds, timeZone);
29
+ };
30
+ export const getSecondsToTimestamp = (timestamp, timeZone) => {
31
+ const sTimestampValue = sTimestamp(timestamp);
32
+ const millisecondsNow = Date.now();
33
+ const millisecondsAtTimestamp = getMillisecondsInUTCFromTimestamp(sTimestampValue, timeZone);
34
+ return Math.floor((millisecondsAtTimestamp - millisecondsNow) / millisecondsInSecond);
35
+ };
36
+ export const getDateFromTimestamp = (timestamp) => {
37
+ const sTimestampValue = sTimestamp(timestamp);
38
+ return sDate(getISODateFromISOTimestamp(sTimestampValue.timestamp));
39
+ };
40
+ export const getTimeFromTimestamp = (timestamp) => {
41
+ const sTimestampValue = sTimestamp(timestamp);
42
+ return sTime(getISOTimeFromISOTimestamp(sTimestampValue.timestamp));
43
+ };
44
+ export const getShortTimestampString = (timestamp, timeZone, locale, options) => {
45
+ const sTimestampValue = sTimestamp(timestamp);
46
+ const date = getDateFromTimestamp(sTimestampValue);
47
+ const time = getTimeFromTimestamp(sTimestampValue);
48
+ const dateText = getShortDateString(date, timeZone, locale, {
49
+ includeWeekday: options.includeWeekday,
50
+ onTodayText: options.onTodayAtText,
51
+ });
52
+ const timeText = get12HourTimeString(time);
53
+ return `${dateText} ${timeText}`;
54
+ };
55
+ export const addDaysToTimestamp = (timestamp, days) => {
56
+ const sTimestampValue = sTimestamp(timestamp);
57
+ const nativeDate = getTimestampAsUTCDateMini(sTimestampValue);
58
+ nativeDate.setDate(nativeDate.getDate() + days);
59
+ return sTimestamp(getISOTimestampFromZonedDate(nativeDate));
60
+ };
61
+ export const addMinutesToTimestamp = (timestamp, minutes, timeZone) => {
62
+ const sTimestampValue = sTimestamp(timestamp);
63
+ const newMillisecondsInUTC = getMillisecondsInUTCFromTimestamp(sTimestampValue, timeZone) +
64
+ minutes * millisecondsInMinute;
65
+ const newTimestamp = getTimestampFromUTCMilliseconds(newMillisecondsInUTC, timeZone);
66
+ return newTimestamp;
67
+ };
68
+ export const isSameTimestamp = (timestamp1, timestamp2) => {
69
+ const sTimestamp1 = sTimestamp(timestamp1);
70
+ const sTimestamp2 = sTimestamp(timestamp2);
71
+ return sTimestamp1.timestamp === sTimestamp2.timestamp;
72
+ };
73
+ export const isBeforeTimestamp = (timestamp1, timestamp2) => {
74
+ const sTimestamp1 = sTimestamp(timestamp1);
75
+ const sTimestamp2 = sTimestamp(timestamp2);
76
+ return sTimestamp1.timestamp < sTimestamp2.timestamp;
77
+ };
78
+ export const isSameTimestampOrBefore = (timestamp1, timestamp2) => {
79
+ const sTimestamp1 = sTimestamp(timestamp1);
80
+ const sTimestamp2 = sTimestamp(timestamp2);
81
+ return sTimestamp1.timestamp <= sTimestamp2.timestamp;
82
+ };
83
+ export const isAfterTimestamp = (timestamp1, timestamp2) => {
84
+ const sTimestamp1 = sTimestamp(timestamp1);
85
+ const sTimestamp2 = sTimestamp(timestamp2);
86
+ return sTimestamp1.timestamp > sTimestamp2.timestamp;
87
+ };
88
+ export const isSameTimestampOrAfter = (timestamp1, timestamp2) => {
89
+ const sTimestamp1 = sTimestamp(timestamp1);
90
+ const sTimestamp2 = sTimestamp(timestamp2);
91
+ return sTimestamp1.timestamp >= sTimestamp2.timestamp;
92
+ };
@@ -0,0 +1,12 @@
1
+ import { Weekday } from './constants';
2
+ import { SDate } from './internal/SDate';
3
+ import { SWeekdays } from './internal/SWeekdays';
4
+ export declare const sWeekdays: (weekdays: string | SWeekdays) => SWeekdays;
5
+ export declare const getWeekdaysFromWeekdayFlags: (weekdays: Weekday) => SWeekdays;
6
+ export declare const getWeekdaysWithAllIncluded: () => SWeekdays;
7
+ export declare const getWeekdaysWithNoneIncluded: () => SWeekdays;
8
+ export declare const shiftWeekdaysForward: (weekdays: string | SWeekdays) => SWeekdays;
9
+ export declare const filterWeekdaysForDates: (weekdays: string | SWeekdays, fromDate: string | SDate, toDate: string | SDate) => SWeekdays;
10
+ export declare const addWeekdayToWeekdays: (weekdays: string | SWeekdays, weekdayToAdd: Weekday) => SWeekdays;
11
+ export declare const doesWeekdaysIncludeWeekday: (weekdays: string | SWeekdays, weekday: Weekday) => boolean;
12
+ export declare const doesWeekdaysHaveOverlapWithWeekdays: (weekdays1: string | SWeekdays, weekdays2: string | SWeekdays) => boolean;
@@ -0,0 +1,89 @@
1
+ import { daysInWeek } from 'date-fns/constants';
2
+ import { SWeekdays } from './internal/SWeekdays';
3
+ import { DayToWeekday } from './internal/constants';
4
+ import { getAtIndex, hasFlag } from './internal/utils';
5
+ import { getIndexForWeekday } from './internal/weekdays';
6
+ import { addDaysToDate, getDaysBetweenDates, getWeekdayFromDate, isAfterDate, isSameDateOrBefore, sDate, } from './sDate';
7
+ const AllWeekdaysIncludedMask = 'SMTWTFS';
8
+ const NotIncludedDay = '-';
9
+ const NoWeekdaysIncluded = NotIncludedDay.repeat(AllWeekdaysIncludedMask.length);
10
+ const WeekdaysCount = AllWeekdaysIncludedMask.length;
11
+ export const sWeekdays = (weekdays) => {
12
+ if (weekdays instanceof SWeekdays) {
13
+ return weekdays;
14
+ }
15
+ return new SWeekdays(weekdays);
16
+ };
17
+ export const getWeekdaysFromWeekdayFlags = (weekdays) => {
18
+ const newWeekdays = [...AllWeekdaysIncludedMask];
19
+ for (let i = 0; i < DayToWeekday.length; i++) {
20
+ const weekday = getAtIndex(DayToWeekday, i);
21
+ if (!hasFlag(weekdays, weekday)) {
22
+ newWeekdays[i] = NotIncludedDay;
23
+ }
24
+ }
25
+ return sWeekdays(newWeekdays.join(''));
26
+ };
27
+ export const getWeekdaysWithAllIncluded = () => {
28
+ return sWeekdays(AllWeekdaysIncludedMask);
29
+ };
30
+ export const getWeekdaysWithNoneIncluded = () => {
31
+ return sWeekdays(NoWeekdaysIncluded);
32
+ };
33
+ export const shiftWeekdaysForward = (weekdays) => {
34
+ const sWeekdaysInstance = sWeekdays(weekdays);
35
+ const after = [...NoWeekdaysIncluded];
36
+ const DayShift = 1;
37
+ for (let i = 0; i < WeekdaysCount; i++) {
38
+ const prevDayIndex = (WeekdaysCount - DayShift + i) % WeekdaysCount;
39
+ after[i] =
40
+ sWeekdaysInstance.weekdays[prevDayIndex] === NotIncludedDay
41
+ ? NotIncludedDay
42
+ : getAtIndex(AllWeekdaysIncludedMask, i);
43
+ }
44
+ return sWeekdays(after.join(''));
45
+ };
46
+ export const filterWeekdaysForDates = (weekdays, fromDate, toDate) => {
47
+ const sWeekdaysInstance = sWeekdays(weekdays);
48
+ const sFromDate = sDate(fromDate);
49
+ const sToDate = sDate(toDate);
50
+ if (isAfterDate(sFromDate, sToDate)) {
51
+ throw new Error('The from date must be before the to date.');
52
+ }
53
+ const diff = getDaysBetweenDates(sFromDate, sToDate);
54
+ if (diff >= daysInWeek) {
55
+ return sWeekdaysInstance;
56
+ }
57
+ let result = getWeekdaysWithNoneIncluded();
58
+ const DayAfterDelta = 1;
59
+ for (let date = fromDate; isSameDateOrBefore(date, toDate); date = addDaysToDate(date, DayAfterDelta)) {
60
+ const weekday = getWeekdayFromDate(date);
61
+ if (doesWeekdaysIncludeWeekday(sWeekdaysInstance, weekday)) {
62
+ result = addWeekdayToWeekdays(result, weekday);
63
+ }
64
+ }
65
+ return result;
66
+ };
67
+ export const addWeekdayToWeekdays = (weekdays, weekdayToAdd) => {
68
+ const sWeekdaysInstance = sWeekdays(weekdays);
69
+ const newWeekdays = [...sWeekdaysInstance.weekdays];
70
+ const weekdayIndex = getIndexForWeekday(weekdayToAdd);
71
+ newWeekdays[weekdayIndex] = getAtIndex(AllWeekdaysIncludedMask, weekdayIndex);
72
+ return sWeekdays(newWeekdays.join(''));
73
+ };
74
+ export const doesWeekdaysIncludeWeekday = (weekdays, weekday) => {
75
+ const sWeekdaysInstance = sWeekdays(weekdays);
76
+ const weekdayIndex = getIndexForWeekday(weekday);
77
+ return getAtIndex(sWeekdaysInstance.weekdays, weekdayIndex) !== NotIncludedDay;
78
+ };
79
+ export const doesWeekdaysHaveOverlapWithWeekdays = (weekdays1, weekdays2) => {
80
+ const sWeekdays1 = sWeekdays(weekdays1);
81
+ const sWeekdays2 = sWeekdays(weekdays2);
82
+ for (let i = 0; i < WeekdaysCount; i++) {
83
+ if (sWeekdays1.weekdays[i] !== NotIncludedDay &&
84
+ sWeekdays1.weekdays[i] === sWeekdays2.weekdays[i]) {
85
+ return true;
86
+ }
87
+ }
88
+ return false;
89
+ };
package/package.json ADDED
@@ -0,0 +1,73 @@
1
+ {
2
+ "name": "scdate",
3
+ "version": "0.1.1",
4
+ "type": "module",
5
+ "exports": {
6
+ ".": "./dist/index.js"
7
+ },
8
+ "files": [
9
+ "dist",
10
+ "!/**/__test__",
11
+ "!*.test.*"
12
+ ],
13
+ "sideEffects": false,
14
+ "engines": {
15
+ "node": ">=20"
16
+ },
17
+ "scripts": {
18
+ "build": "tsc --build",
19
+ "build:clean": "yarn build --clean && rimraf dist && rimraf *.tgz",
20
+ "lint": "eslint .",
21
+ "test": "vitest run",
22
+ "test:utc": "TZ=Etc/Universal vitest run",
23
+ "test:watch": "vitest",
24
+ "smoke": "yarn build && yarn lint && yarn test:utc",
25
+ "-- PRE-COMMIT HOOKS --": "",
26
+ "_postinstall": "husky install",
27
+ "prepublishOnly": "pinst --disable",
28
+ "postpublish": "pinst --enable",
29
+ "prepare": "husky"
30
+ },
31
+ "dependencies": {
32
+ "@date-fns/utc": "^1.2.0",
33
+ "date-fns": "^3.6.0",
34
+ "date-fns-tz": "^3.1.3"
35
+ },
36
+ "devDependencies": {
37
+ "@eslint/js": "^9.1.1",
38
+ "@tsconfig/strictest": "^2.0.5",
39
+ "@types/node": "^20.12.7",
40
+ "eslint": "^9.1.1",
41
+ "husky": "^9.0.11",
42
+ "lint-staged": "^15.2.2",
43
+ "pinst": "^3.0.0",
44
+ "prettier": "^3.2.5",
45
+ "rimraf": "^5.0.5",
46
+ "typescript": "^5.4.5",
47
+ "typescript-eslint": "^7.7.1",
48
+ "vitest": "^1.5.1"
49
+ },
50
+ "prettier": {
51
+ "tabWidth": 2,
52
+ "semi": false,
53
+ "singleQuote": true
54
+ },
55
+ "repository": {
56
+ "type": "git",
57
+ "url": "https://github.com/ericvera/scdate"
58
+ },
59
+ "keywords": [
60
+ "date",
61
+ "time zones",
62
+ "time",
63
+ "datetime",
64
+ "immutable",
65
+ "schedule",
66
+ "timestamp"
67
+ ],
68
+ "lint-staged": {
69
+ "*.{ts,tsx,mjs}": "eslint --cache",
70
+ "*": "prettier --ignore-unknown --write"
71
+ },
72
+ "packageManager": "yarn@4.1.1"
73
+ }