ts-time-utils 4.0.1 → 4.4.0
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/README.md +175 -30
- package/dist/{age.js → age.cjs} +14 -6
- package/dist/{calculate.js → calculate.cjs} +30 -18
- package/dist/{calendar.js → calendar.cjs} +80 -39
- package/dist/{calendars.js → calendars.cjs} +48 -23
- package/dist/{chain.js → chain.cjs} +41 -40
- package/dist/{compare.js → compare.cjs} +58 -28
- package/dist/constants.cjs +19 -0
- package/dist/{countdown.js → countdown.cjs} +16 -7
- package/dist/{cron.js → cron.cjs} +20 -9
- package/dist/{dateRange.js → dateRange.cjs} +42 -26
- package/dist/{duration.js → duration.cjs} +56 -44
- package/dist/esm/chain.js +0 -5
- package/dist/esm/finance.d.ts +236 -0
- package/dist/esm/finance.d.ts.map +1 -0
- package/dist/esm/finance.js +495 -0
- package/dist/esm/healthcare.d.ts +260 -0
- package/dist/esm/healthcare.d.ts.map +1 -0
- package/dist/esm/healthcare.js +447 -0
- package/dist/esm/index.d.ts +6 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +6 -0
- package/dist/esm/naturalLanguage.d.ts +1 -3
- package/dist/esm/naturalLanguage.d.ts.map +1 -1
- package/dist/esm/naturalLanguage.js +9 -2
- package/dist/esm/plugins.d.ts +0 -6
- package/dist/esm/plugins.d.ts.map +1 -1
- package/dist/esm/plugins.js +36 -42
- package/dist/esm/recurrence.d.ts.map +1 -1
- package/dist/esm/recurrence.js +3 -5
- package/dist/esm/scheduling.d.ts +206 -0
- package/dist/esm/scheduling.d.ts.map +1 -0
- package/dist/esm/scheduling.js +329 -0
- package/dist/esm/timezone.d.ts +6 -1
- package/dist/esm/timezone.d.ts.map +1 -1
- package/dist/esm/timezone.js +106 -66
- package/dist/esm/types.d.ts +0 -4
- package/dist/esm/types.d.ts.map +1 -1
- package/dist/finance.cjs +512 -0
- package/dist/finance.d.ts +236 -0
- package/dist/finance.d.ts.map +1 -0
- package/dist/{fiscal.js → fiscal.cjs} +36 -17
- package/dist/{format.js → format.cjs} +83 -70
- package/dist/healthcare.cjs +462 -0
- package/dist/healthcare.d.ts +260 -0
- package/dist/healthcare.d.ts.map +1 -0
- package/dist/{holidays.js → holidays.cjs} +52 -25
- package/dist/index.cjs +595 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/{interval.js → interval.cjs} +24 -11
- package/dist/{iterate.js → iterate.cjs} +84 -41
- package/dist/{locale.js → locale.cjs} +54 -26
- package/dist/{naturalLanguage.js → naturalLanguage.cjs} +36 -23
- package/dist/naturalLanguage.d.ts +1 -3
- package/dist/naturalLanguage.d.ts.map +1 -1
- package/dist/{parse.js → parse.cjs} +24 -11
- package/dist/{performance.js → performance.cjs} +23 -10
- package/dist/{plugins.js → plugins.cjs} +48 -47
- package/dist/plugins.d.ts +0 -6
- package/dist/plugins.d.ts.map +1 -1
- package/dist/{precision.js → precision.cjs} +74 -37
- package/dist/{rangePresets.js → rangePresets.cjs} +40 -19
- package/dist/{recurrence.js → recurrence.cjs} +27 -21
- package/dist/recurrence.d.ts.map +1 -1
- package/dist/scheduling.cjs +344 -0
- package/dist/scheduling.d.ts +206 -0
- package/dist/scheduling.d.ts.map +1 -0
- package/dist/{serialize.js → serialize.cjs} +36 -17
- package/dist/{temporal.js → temporal.cjs} +28 -13
- package/dist/{timezone.js → timezone.cjs} +140 -82
- package/dist/timezone.d.ts +6 -1
- package/dist/timezone.d.ts.map +1 -1
- package/dist/{types.js → types.cjs} +9 -3
- package/dist/types.d.ts +0 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/{validate.js → validate.cjs} +54 -26
- package/dist/{workingHours.js → workingHours.cjs} +36 -17
- package/package.json +52 -34
- package/dist/constants.js +0 -16
- package/dist/index.js +0 -66
|
@@ -1,3 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerLocale = registerLocale;
|
|
4
|
+
exports.getLocaleConfig = getLocaleConfig;
|
|
5
|
+
exports.getSupportedLocales = getSupportedLocales;
|
|
6
|
+
exports.formatRelativeTime = formatRelativeTime;
|
|
7
|
+
exports.formatDateLocale = formatDateLocale;
|
|
8
|
+
exports.formatTimeLocale = formatTimeLocale;
|
|
9
|
+
exports.formatDateTimeLocale = formatDateTimeLocale;
|
|
10
|
+
exports.getMonthNames = getMonthNames;
|
|
11
|
+
exports.getDayNames = getDayNames;
|
|
12
|
+
exports.getFirstDayOfWeek = getFirstDayOfWeek;
|
|
13
|
+
exports.isLocaleSupported = isLocaleSupported;
|
|
14
|
+
exports.getBestMatchingLocale = getBestMatchingLocale;
|
|
15
|
+
exports.detectLocale = detectLocale;
|
|
16
|
+
exports.convertRelativeTime = convertRelativeTime;
|
|
17
|
+
exports.detectLocaleFromRelativeTime = detectLocaleFromRelativeTime;
|
|
18
|
+
exports.convertFormatPattern = convertFormatPattern;
|
|
19
|
+
exports.convertFormattedDate = convertFormattedDate;
|
|
20
|
+
exports.convertRelativeTimeArray = convertRelativeTimeArray;
|
|
21
|
+
exports.compareLocaleFormats = compareLocaleFormats;
|
|
22
|
+
exports.getWeekInfo = getWeekInfo;
|
|
23
|
+
exports.getLocaleWeekStartsOn = getLocaleWeekStartsOn;
|
|
24
|
+
exports.getLocaleWeekendDays = getLocaleWeekendDays;
|
|
25
|
+
exports.intlFormat = intlFormat;
|
|
26
|
+
exports.formatISODate = formatISODate;
|
|
27
|
+
exports.formatISOTime = formatISOTime;
|
|
28
|
+
exports.formatDistanceStrict = formatDistanceStrict;
|
|
1
29
|
/**
|
|
2
30
|
* Internationalization and localization utilities for time formatting
|
|
3
31
|
*/
|
|
@@ -423,7 +451,7 @@ const localeRegistry = new Map(Object.entries(DEFAULT_LOCALES));
|
|
|
423
451
|
/**
|
|
424
452
|
* Register a custom locale configuration
|
|
425
453
|
*/
|
|
426
|
-
|
|
454
|
+
function registerLocale(config) {
|
|
427
455
|
localeRegistry.set(config.locale, config);
|
|
428
456
|
// Also register base language if this is a region-specific locale
|
|
429
457
|
const baseLang = config.locale.split('-')[0];
|
|
@@ -434,7 +462,7 @@ export function registerLocale(config) {
|
|
|
434
462
|
/**
|
|
435
463
|
* Get locale configuration, with fallback to base language or English
|
|
436
464
|
*/
|
|
437
|
-
|
|
465
|
+
function getLocaleConfig(locale) {
|
|
438
466
|
// Try exact match first
|
|
439
467
|
if (localeRegistry.has(locale)) {
|
|
440
468
|
return localeRegistry.get(locale);
|
|
@@ -450,13 +478,13 @@ export function getLocaleConfig(locale) {
|
|
|
450
478
|
/**
|
|
451
479
|
* Get list of all registered locales
|
|
452
480
|
*/
|
|
453
|
-
|
|
481
|
+
function getSupportedLocales() {
|
|
454
482
|
return Array.from(localeRegistry.keys());
|
|
455
483
|
}
|
|
456
484
|
/**
|
|
457
485
|
* Format relative time in the specified locale
|
|
458
486
|
*/
|
|
459
|
-
|
|
487
|
+
function formatRelativeTime(date, options = {}) {
|
|
460
488
|
const { locale = 'en', maxUnit = 'years', minUnit = 'seconds', precision = 0, short = false, numeric = 'always', style = 'long' } = options;
|
|
461
489
|
const targetDate = normalizeDate(date);
|
|
462
490
|
if (!targetDate) {
|
|
@@ -530,7 +558,7 @@ export function formatRelativeTime(date, options = {}) {
|
|
|
530
558
|
/**
|
|
531
559
|
* Format date in locale-specific format
|
|
532
560
|
*/
|
|
533
|
-
|
|
561
|
+
function formatDateLocale(date, locale = 'en', style = 'medium') {
|
|
534
562
|
const targetDate = normalizeDate(date);
|
|
535
563
|
if (!targetDate) {
|
|
536
564
|
throw new Error('Invalid date provided for locale formatting');
|
|
@@ -542,7 +570,7 @@ export function formatDateLocale(date, locale = 'en', style = 'medium') {
|
|
|
542
570
|
/**
|
|
543
571
|
* Format time in locale-specific format
|
|
544
572
|
*/
|
|
545
|
-
|
|
573
|
+
function formatTimeLocale(date, locale = 'en', style = 'medium') {
|
|
546
574
|
const targetDate = normalizeDate(date);
|
|
547
575
|
if (!targetDate) {
|
|
548
576
|
throw new Error('Invalid date provided for time locale formatting');
|
|
@@ -554,7 +582,7 @@ export function formatTimeLocale(date, locale = 'en', style = 'medium') {
|
|
|
554
582
|
/**
|
|
555
583
|
* Format both date and time in locale-specific format
|
|
556
584
|
*/
|
|
557
|
-
|
|
585
|
+
function formatDateTimeLocale(date, locale = 'en', dateStyle = 'medium', timeStyle = 'medium') {
|
|
558
586
|
const dateStr = formatDateLocale(date, locale, dateStyle);
|
|
559
587
|
const timeStr = formatTimeLocale(date, locale, timeStyle);
|
|
560
588
|
// Simple concatenation - could be made more sophisticated per locale
|
|
@@ -563,7 +591,7 @@ export function formatDateTimeLocale(date, locale = 'en', dateStyle = 'medium',
|
|
|
563
591
|
/**
|
|
564
592
|
* Get localized month names
|
|
565
593
|
*/
|
|
566
|
-
|
|
594
|
+
function getMonthNames(locale = 'en', short = false) {
|
|
567
595
|
const config = getLocaleConfig(locale);
|
|
568
596
|
return short ?
|
|
569
597
|
(config.calendar?.monthNamesShort || config.calendar?.monthNames || []) :
|
|
@@ -572,7 +600,7 @@ export function getMonthNames(locale = 'en', short = false) {
|
|
|
572
600
|
/**
|
|
573
601
|
* Get localized day names
|
|
574
602
|
*/
|
|
575
|
-
|
|
603
|
+
function getDayNames(locale = 'en', short = false) {
|
|
576
604
|
const config = getLocaleConfig(locale);
|
|
577
605
|
return short ?
|
|
578
606
|
(config.calendar?.dayNamesShort || config.calendar?.dayNames || []) :
|
|
@@ -581,20 +609,20 @@ export function getDayNames(locale = 'en', short = false) {
|
|
|
581
609
|
/**
|
|
582
610
|
* Get the first day of week for a locale (0 = Sunday, 1 = Monday, etc.)
|
|
583
611
|
*/
|
|
584
|
-
|
|
612
|
+
function getFirstDayOfWeek(locale = 'en') {
|
|
585
613
|
const config = getLocaleConfig(locale);
|
|
586
614
|
return config.calendar?.weekStartsOn ?? 0;
|
|
587
615
|
}
|
|
588
616
|
/**
|
|
589
617
|
* Check if a locale is supported
|
|
590
618
|
*/
|
|
591
|
-
|
|
619
|
+
function isLocaleSupported(locale) {
|
|
592
620
|
return localeRegistry.has(locale) || localeRegistry.has(locale.split('-')[0]);
|
|
593
621
|
}
|
|
594
622
|
/**
|
|
595
623
|
* Get the best matching locale from a list of preferences
|
|
596
624
|
*/
|
|
597
|
-
|
|
625
|
+
function getBestMatchingLocale(preferences, fallback = 'en') {
|
|
598
626
|
for (const pref of preferences) {
|
|
599
627
|
// Try exact match first
|
|
600
628
|
if (isLocaleSupported(pref)) {
|
|
@@ -615,7 +643,7 @@ export function getBestMatchingLocale(preferences, fallback = 'en') {
|
|
|
615
643
|
/**
|
|
616
644
|
* Auto-detect locale from browser or system (if available)
|
|
617
645
|
*/
|
|
618
|
-
|
|
646
|
+
function detectLocale(fallback = 'en') {
|
|
619
647
|
// In browser environment
|
|
620
648
|
if (typeof navigator !== 'undefined' && navigator.languages) {
|
|
621
649
|
return getBestMatchingLocale(Array.from(navigator.languages), fallback);
|
|
@@ -770,7 +798,7 @@ function formatWithPattern(date, pattern, config) {
|
|
|
770
798
|
* Convert a relative time string from one locale to another
|
|
771
799
|
* Attempts to parse the relative time and reformat in target locale
|
|
772
800
|
*/
|
|
773
|
-
|
|
801
|
+
function convertRelativeTime(relativeTimeString, fromLocale, toLocale) {
|
|
774
802
|
if (fromLocale === toLocale) {
|
|
775
803
|
return relativeTimeString;
|
|
776
804
|
}
|
|
@@ -790,7 +818,7 @@ export function convertRelativeTime(relativeTimeString, fromLocale, toLocale) {
|
|
|
790
818
|
* Detect the locale of a formatted relative time string
|
|
791
819
|
* Returns the most likely locale or null if detection fails
|
|
792
820
|
*/
|
|
793
|
-
|
|
821
|
+
function detectLocaleFromRelativeTime(relativeTimeString) {
|
|
794
822
|
const supportedLocales = getSupportedLocales();
|
|
795
823
|
for (const locale of supportedLocales) {
|
|
796
824
|
if (parseRelativeTime(relativeTimeString, locale)) {
|
|
@@ -802,7 +830,7 @@ export function detectLocaleFromRelativeTime(relativeTimeString) {
|
|
|
802
830
|
/**
|
|
803
831
|
* Convert a date format pattern from one locale's convention to another
|
|
804
832
|
*/
|
|
805
|
-
|
|
833
|
+
function convertFormatPattern(pattern, fromLocale, toLocale, style) {
|
|
806
834
|
if (fromLocale === toLocale) {
|
|
807
835
|
return pattern;
|
|
808
836
|
}
|
|
@@ -853,7 +881,7 @@ export function convertFormatPattern(pattern, fromLocale, toLocale, style) {
|
|
|
853
881
|
* Convert a formatted date string from one locale to another
|
|
854
882
|
* Attempts to parse the date and reformat in target locale
|
|
855
883
|
*/
|
|
856
|
-
|
|
884
|
+
function convertFormattedDate(formattedDate, fromLocale, toLocale, targetStyle) {
|
|
857
885
|
if (fromLocale === toLocale) {
|
|
858
886
|
return formattedDate;
|
|
859
887
|
}
|
|
@@ -866,13 +894,13 @@ export function convertFormattedDate(formattedDate, fromLocale, toLocale, target
|
|
|
866
894
|
/**
|
|
867
895
|
* Bulk convert an array of relative time strings to a different locale
|
|
868
896
|
*/
|
|
869
|
-
|
|
897
|
+
function convertRelativeTimeArray(relativeTimeStrings, fromLocale, toLocale) {
|
|
870
898
|
return relativeTimeStrings.map(str => convertRelativeTime(str, fromLocale, toLocale));
|
|
871
899
|
}
|
|
872
900
|
/**
|
|
873
901
|
* Get format pattern differences between two locales
|
|
874
902
|
*/
|
|
875
|
-
|
|
903
|
+
function compareLocaleFormats(locale1, locale2) {
|
|
876
904
|
const config1 = getLocaleConfig(locale1);
|
|
877
905
|
const config2 = getLocaleConfig(locale2);
|
|
878
906
|
const result = {
|
|
@@ -1093,7 +1121,7 @@ function tryParseWithPattern(dateString, pattern, config) {
|
|
|
1093
1121
|
* @param locale - locale code
|
|
1094
1122
|
* @returns Object with firstDay, weekend days, and minimalDays
|
|
1095
1123
|
*/
|
|
1096
|
-
|
|
1124
|
+
function getWeekInfo(locale) {
|
|
1097
1125
|
const config = getLocaleConfig(locale);
|
|
1098
1126
|
const firstDay = config.calendar?.weekStartsOn ?? 0;
|
|
1099
1127
|
// Most locales use Saturday-Sunday weekend
|
|
@@ -1110,7 +1138,7 @@ export function getWeekInfo(locale) {
|
|
|
1110
1138
|
* @param locale - locale code
|
|
1111
1139
|
* @returns 0-6 (0 = Sunday, 1 = Monday, etc.)
|
|
1112
1140
|
*/
|
|
1113
|
-
|
|
1141
|
+
function getLocaleWeekStartsOn(locale) {
|
|
1114
1142
|
const config = getLocaleConfig(locale);
|
|
1115
1143
|
return config.calendar?.weekStartsOn ?? 0;
|
|
1116
1144
|
}
|
|
@@ -1119,7 +1147,7 @@ export function getLocaleWeekStartsOn(locale) {
|
|
|
1119
1147
|
* @param locale - locale code
|
|
1120
1148
|
* @returns Array of day numbers (0 = Sunday, 6 = Saturday)
|
|
1121
1149
|
*/
|
|
1122
|
-
|
|
1150
|
+
function getLocaleWeekendDays(locale) {
|
|
1123
1151
|
const middleEasternLocales = ['ar', 'fa', 'he', 'ur'];
|
|
1124
1152
|
const baseLang = locale.split('-')[0];
|
|
1125
1153
|
return middleEasternLocales.includes(baseLang) ? [5, 6] : [6, 0];
|
|
@@ -1130,14 +1158,14 @@ export function getLocaleWeekendDays(locale) {
|
|
|
1130
1158
|
* @param options - Intl.DateTimeFormatOptions
|
|
1131
1159
|
* @param locale - locale string (defaults to system locale)
|
|
1132
1160
|
*/
|
|
1133
|
-
|
|
1161
|
+
function intlFormat(date, options, locale) {
|
|
1134
1162
|
return new Intl.DateTimeFormat(locale, options).format(date);
|
|
1135
1163
|
}
|
|
1136
1164
|
/**
|
|
1137
1165
|
* Format only the date part in ISO format (YYYY-MM-DD)
|
|
1138
1166
|
* @param date - date to format
|
|
1139
1167
|
*/
|
|
1140
|
-
|
|
1168
|
+
function formatISODate(date) {
|
|
1141
1169
|
const year = date.getFullYear();
|
|
1142
1170
|
const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
1143
1171
|
const day = String(date.getDate()).padStart(2, '0');
|
|
@@ -1148,7 +1176,7 @@ export function formatISODate(date) {
|
|
|
1148
1176
|
* @param date - date to format
|
|
1149
1177
|
* @param includeMs - include milliseconds
|
|
1150
1178
|
*/
|
|
1151
|
-
|
|
1179
|
+
function formatISOTime(date, includeMs = false) {
|
|
1152
1180
|
const hours = String(date.getHours()).padStart(2, '0');
|
|
1153
1181
|
const minutes = String(date.getMinutes()).padStart(2, '0');
|
|
1154
1182
|
const seconds = String(date.getSeconds()).padStart(2, '0');
|
|
@@ -1165,7 +1193,7 @@ export function formatISOTime(date, includeMs = false) {
|
|
|
1165
1193
|
* @param baseDate - the base date to compare against (defaults to now)
|
|
1166
1194
|
* @param options - formatting options
|
|
1167
1195
|
*/
|
|
1168
|
-
|
|
1196
|
+
function formatDistanceStrict(date, baseDate = new Date(), options = {}) {
|
|
1169
1197
|
const { locale = 'en', unit, roundingMethod = 'round', addSuffix = false } = options;
|
|
1170
1198
|
const config = getLocaleConfig(locale);
|
|
1171
1199
|
const diffMs = date.getTime() - baseDate.getTime();
|
|
@@ -1,9 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* @fileoverview Natural language date parsing utilities
|
|
3
4
|
* Provides intelligent parsing of human-readable date strings
|
|
4
5
|
*/
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.parseNaturalDate = parseNaturalDate;
|
|
8
|
+
exports.parseRelativePhrase = parseRelativePhrase;
|
|
9
|
+
exports.extractDatesFromText = extractDatesFromText;
|
|
10
|
+
exports.suggestDateFromContext = suggestDateFromContext;
|
|
11
|
+
const calculate_js_1 = require("./calculate.cjs");
|
|
12
|
+
const parse_js_1 = require("./parse.cjs");
|
|
7
13
|
/**
|
|
8
14
|
* Parses natural language date strings into Date objects
|
|
9
15
|
* @param input - Natural language date string
|
|
@@ -25,15 +31,15 @@ import { parseRelativeDate } from './parse.js';
|
|
|
25
31
|
* // Date for Dec 25 this year (or next if passed)
|
|
26
32
|
* ```
|
|
27
33
|
*/
|
|
28
|
-
|
|
29
|
-
const { referenceDate = new Date(), defaultTime } = options;
|
|
34
|
+
function parseNaturalDate(input, options = {}) {
|
|
35
|
+
const { referenceDate = new Date(), defaultTime, strict = false } = options;
|
|
30
36
|
const normalized = input.toLowerCase().trim();
|
|
31
37
|
// Try relative phrase parser first (handles "next week", "last month", etc.)
|
|
32
38
|
const relativePhraseResult = parseRelativePhrase(input, referenceDate);
|
|
33
39
|
if (relativePhraseResult)
|
|
34
40
|
return relativePhraseResult;
|
|
35
41
|
// Try existing relative date parser
|
|
36
|
-
const relativeResult = parseRelativeDate(input);
|
|
42
|
+
const relativeResult = (0, parse_js_1.parseRelativeDate)(input);
|
|
37
43
|
if (relativeResult)
|
|
38
44
|
return relativeResult;
|
|
39
45
|
// Common absolute patterns
|
|
@@ -61,6 +67,9 @@ export function parseNaturalDate(input, options = {}) {
|
|
|
61
67
|
return parseMatchedPattern(match, referenceDate, defaultTime);
|
|
62
68
|
}
|
|
63
69
|
}
|
|
70
|
+
if (strict) {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
64
73
|
// Try standard Date parsing as fallback
|
|
65
74
|
const standardDate = new Date(input);
|
|
66
75
|
if (!isNaN(standardDate.getTime())) {
|
|
@@ -81,7 +90,7 @@ export function parseNaturalDate(input, options = {}) {
|
|
|
81
90
|
* parseRelativePhrase('next week'); // 7 days from now
|
|
82
91
|
* ```
|
|
83
92
|
*/
|
|
84
|
-
|
|
93
|
+
function parseRelativePhrase(input, referenceDate = new Date()) {
|
|
85
94
|
const normalized = input.toLowerCase().trim();
|
|
86
95
|
// "in X units"
|
|
87
96
|
const inPattern = /^in\s+(\d+)\s+(millisecond|milliseconds|second|seconds|minute|minutes|hour|hours|day|days|week|weeks|month|months|year|years)$/;
|
|
@@ -89,7 +98,7 @@ export function parseRelativePhrase(input, referenceDate = new Date()) {
|
|
|
89
98
|
if (match) {
|
|
90
99
|
const amount = parseInt(match[1], 10);
|
|
91
100
|
const unit = normalizeUnit(match[2]);
|
|
92
|
-
return addTime(referenceDate, amount, unit);
|
|
101
|
+
return (0, calculate_js_1.addTime)(referenceDate, amount, unit);
|
|
93
102
|
}
|
|
94
103
|
// "X units ago"
|
|
95
104
|
const agoPattern = /^(\d+)\s+(millisecond|milliseconds|second|seconds|minute|minutes|hour|hours|day|days|week|weeks|month|months|year|years)\s+ago$/;
|
|
@@ -97,7 +106,7 @@ export function parseRelativePhrase(input, referenceDate = new Date()) {
|
|
|
97
106
|
if (match) {
|
|
98
107
|
const amount = parseInt(match[1], 10);
|
|
99
108
|
const unit = normalizeUnit(match[2]);
|
|
100
|
-
return addTime(referenceDate, -amount, unit);
|
|
109
|
+
return (0, calculate_js_1.addTime)(referenceDate, -amount, unit);
|
|
101
110
|
}
|
|
102
111
|
// "X units from now"
|
|
103
112
|
const fromNowPattern = /^(\d+)\s+(millisecond|milliseconds|second|seconds|minute|minutes|hour|hours|day|days|week|weeks|month|months|year|years)\s+from\s+now$/;
|
|
@@ -105,7 +114,7 @@ export function parseRelativePhrase(input, referenceDate = new Date()) {
|
|
|
105
114
|
if (match) {
|
|
106
115
|
const amount = parseInt(match[1], 10);
|
|
107
116
|
const unit = normalizeUnit(match[2]);
|
|
108
|
-
return addTime(referenceDate, amount, unit);
|
|
117
|
+
return (0, calculate_js_1.addTime)(referenceDate, amount, unit);
|
|
109
118
|
}
|
|
110
119
|
// Common shortcuts - use switch/case to properly use the referenceDate parameter
|
|
111
120
|
switch (normalized) {
|
|
@@ -117,21 +126,21 @@ export function parseRelativePhrase(input, referenceDate = new Date()) {
|
|
|
117
126
|
return d;
|
|
118
127
|
}
|
|
119
128
|
case 'tomorrow':
|
|
120
|
-
return addTime(referenceDate, 1, 'day');
|
|
129
|
+
return (0, calculate_js_1.addTime)(referenceDate, 1, 'day');
|
|
121
130
|
case 'yesterday':
|
|
122
|
-
return addTime(referenceDate, -1, 'day');
|
|
131
|
+
return (0, calculate_js_1.addTime)(referenceDate, -1, 'day');
|
|
123
132
|
case 'next week':
|
|
124
|
-
return addTime(referenceDate, 1, 'week');
|
|
133
|
+
return (0, calculate_js_1.addTime)(referenceDate, 1, 'week');
|
|
125
134
|
case 'last week':
|
|
126
|
-
return addTime(referenceDate, -1, 'week');
|
|
135
|
+
return (0, calculate_js_1.addTime)(referenceDate, -1, 'week');
|
|
127
136
|
case 'next month':
|
|
128
|
-
return addTime(referenceDate, 1, 'month');
|
|
137
|
+
return (0, calculate_js_1.addTime)(referenceDate, 1, 'month');
|
|
129
138
|
case 'last month':
|
|
130
|
-
return addTime(referenceDate, -1, 'month');
|
|
139
|
+
return (0, calculate_js_1.addTime)(referenceDate, -1, 'month');
|
|
131
140
|
case 'next year':
|
|
132
|
-
return addTime(referenceDate, 1, 'year');
|
|
141
|
+
return (0, calculate_js_1.addTime)(referenceDate, 1, 'year');
|
|
133
142
|
case 'last year':
|
|
134
|
-
return addTime(referenceDate, -1, 'year');
|
|
143
|
+
return (0, calculate_js_1.addTime)(referenceDate, -1, 'year');
|
|
135
144
|
default:
|
|
136
145
|
return null;
|
|
137
146
|
}
|
|
@@ -152,7 +161,7 @@ export function parseRelativePhrase(input, referenceDate = new Date()) {
|
|
|
152
161
|
* // ]
|
|
153
162
|
* ```
|
|
154
163
|
*/
|
|
155
|
-
|
|
164
|
+
function extractDatesFromText(text, options = {}) {
|
|
156
165
|
const { referenceDate = new Date() } = options;
|
|
157
166
|
const results = [];
|
|
158
167
|
// Patterns to match
|
|
@@ -182,7 +191,11 @@ export function extractDatesFromText(text, options = {}) {
|
|
|
182
191
|
continue;
|
|
183
192
|
processed.add(`${index}-${matchedText}`);
|
|
184
193
|
// Try to parse the matched text
|
|
185
|
-
const parsed = parseNaturalDate(matchedText, {
|
|
194
|
+
const parsed = parseNaturalDate(matchedText, {
|
|
195
|
+
referenceDate,
|
|
196
|
+
defaultTime: options.defaultTime,
|
|
197
|
+
strict: options.strict
|
|
198
|
+
});
|
|
186
199
|
if (parsed) {
|
|
187
200
|
results.push({
|
|
188
201
|
date: parsed,
|
|
@@ -209,7 +222,7 @@ export function extractDatesFromText(text, options = {}) {
|
|
|
209
222
|
* // [{ date: Date(last day of current month), confidence: 0.8, ... }]
|
|
210
223
|
* ```
|
|
211
224
|
*/
|
|
212
|
-
|
|
225
|
+
function suggestDateFromContext(context, options = {}) {
|
|
213
226
|
const { referenceDate = new Date() } = options;
|
|
214
227
|
const suggestions = [];
|
|
215
228
|
const normalized = context.toLowerCase();
|
|
@@ -284,16 +297,16 @@ function parseMatchedPattern(match, referenceDate, defaultTime) {
|
|
|
284
297
|
if (daysToAdd <= 0)
|
|
285
298
|
daysToAdd += 7;
|
|
286
299
|
}
|
|
287
|
-
return addTime(referenceDate, daysToAdd, 'day');
|
|
300
|
+
return (0, calculate_js_1.addTime)(referenceDate, daysToAdd, 'day');
|
|
288
301
|
}
|
|
289
302
|
// "in X units" pattern
|
|
290
303
|
if (match[1] && match[2]) {
|
|
291
304
|
const amount = parseInt(match[1], 10);
|
|
292
305
|
const unit = normalizeUnit(match[2]);
|
|
293
306
|
if (match[3] === 'ago') {
|
|
294
|
-
return addTime(referenceDate, -amount, unit);
|
|
307
|
+
return (0, calculate_js_1.addTime)(referenceDate, -amount, unit);
|
|
295
308
|
}
|
|
296
|
-
return addTime(referenceDate, amount, unit);
|
|
309
|
+
return (0, calculate_js_1.addTime)(referenceDate, amount, unit);
|
|
297
310
|
}
|
|
298
311
|
return null;
|
|
299
312
|
}
|
|
@@ -14,9 +14,7 @@ export interface NaturalParseOptions {
|
|
|
14
14
|
minute: number;
|
|
15
15
|
second?: number;
|
|
16
16
|
};
|
|
17
|
-
/**
|
|
18
|
-
locale?: string;
|
|
19
|
-
/** Whether to use strict parsing */
|
|
17
|
+
/** Whether to skip permissive fallback parsing */
|
|
20
18
|
strict?: boolean;
|
|
21
19
|
}
|
|
22
20
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"naturalLanguage.d.ts","sourceRoot":"","sources":["../src/naturalLanguage.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,4DAA4D;IAC5D,aAAa,CAAC,EAAE,IAAI,CAAC;IACrB,sDAAsD;IACtD,WAAW,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAChE,
|
|
1
|
+
{"version":3,"file":"naturalLanguage.d.ts","sourceRoot":"","sources":["../src/naturalLanguage.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,4DAA4D;IAC5D,aAAa,CAAC,EAAE,IAAI,CAAC;IACrB,sDAAsD;IACtD,WAAW,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAChE,kDAAkD;IAClD,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,sBAAsB;IACtB,IAAI,EAAE,IAAI,CAAC;IACX,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,6CAA6C;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,mCAAmC;IACnC,IAAI,EAAE,UAAU,GAAG,UAAU,GAAG,OAAO,GAAG,MAAM,CAAC;IACjD,6BAA6B;IAC7B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,mBAAwB,GAAG,IAAI,GAAG,IAAI,CAkD9F;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,aAAa,GAAE,IAAiB,GAAG,IAAI,GAAG,IAAI,CA6DhG;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,mBAAwB,GAChC,aAAa,EAAE,CAsDjB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,mBAAwB,GAChC,KAAK,CAAC;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,CAkDzD"}
|
|
@@ -1,11 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* Advanced date parsing utilities
|
|
3
4
|
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.parseDate = parseDate;
|
|
7
|
+
exports.parseRelativeDate = parseRelativeDate;
|
|
8
|
+
exports.parseTimeAgo = parseTimeAgo;
|
|
9
|
+
exports.parseCustomFormat = parseCustomFormat;
|
|
10
|
+
exports.parseManyFormats = parseManyFormats;
|
|
11
|
+
exports.parseISO8601Duration = parseISO8601Duration;
|
|
12
|
+
exports.parseISO8601DurationToMs = parseISO8601DurationToMs;
|
|
13
|
+
exports.parseTime = parseTime;
|
|
14
|
+
exports.guessDateFormat = guessDateFormat;
|
|
15
|
+
exports.parseAutoFormat = parseAutoFormat;
|
|
16
|
+
exports.parseRangeEndpoint = parseRangeEndpoint;
|
|
4
17
|
/**
|
|
5
18
|
* Parse various date formats intelligently
|
|
6
19
|
* @param input - date string, number, or Date object
|
|
7
20
|
*/
|
|
8
|
-
|
|
21
|
+
function parseDate(input) {
|
|
9
22
|
if (input instanceof Date) {
|
|
10
23
|
return isNaN(input.getTime()) ? null : input;
|
|
11
24
|
}
|
|
@@ -61,7 +74,7 @@ export function parseDate(input) {
|
|
|
61
74
|
* Parse relative date strings like "tomorrow", "next monday", "2 weeks ago"
|
|
62
75
|
* @param input - relative date string
|
|
63
76
|
*/
|
|
64
|
-
|
|
77
|
+
function parseRelativeDate(input) {
|
|
65
78
|
const now = new Date();
|
|
66
79
|
const lowercaseInput = input.toLowerCase().trim();
|
|
67
80
|
// Handle simple cases
|
|
@@ -105,7 +118,7 @@ export function parseRelativeDate(input) {
|
|
|
105
118
|
* Parse "time ago" strings like "5 minutes ago", "2 hours ago"
|
|
106
119
|
* @param input - time ago string
|
|
107
120
|
*/
|
|
108
|
-
|
|
121
|
+
function parseTimeAgo(input) {
|
|
109
122
|
const now = new Date();
|
|
110
123
|
const lowercaseInput = input.toLowerCase().trim();
|
|
111
124
|
// Handle simple cases
|
|
@@ -125,7 +138,7 @@ export function parseTimeAgo(input) {
|
|
|
125
138
|
* @param dateString - date string to parse
|
|
126
139
|
* @param format - format pattern (e.g., "YYYY-MM-DD", "DD/MM/YYYY")
|
|
127
140
|
*/
|
|
128
|
-
|
|
141
|
+
function parseCustomFormat(dateString, format) {
|
|
129
142
|
// Simple implementation for common patterns
|
|
130
143
|
const formatMap = {
|
|
131
144
|
'YYYY-MM-DD': /^(\d{4})-(\d{2})-(\d{2})$/,
|
|
@@ -176,7 +189,7 @@ export function parseCustomFormat(dateString, format) {
|
|
|
176
189
|
* @param dateString - date string to parse
|
|
177
190
|
* @param formats - array of format patterns to try
|
|
178
191
|
*/
|
|
179
|
-
|
|
192
|
+
function parseManyFormats(dateString, formats) {
|
|
180
193
|
for (const format of formats) {
|
|
181
194
|
const result = parseCustomFormat(dateString, format);
|
|
182
195
|
if (result)
|
|
@@ -220,7 +233,7 @@ function subtractTimeUnits(date, amount, unit) {
|
|
|
220
233
|
* @param duration - ISO 8601 duration string
|
|
221
234
|
* @returns object with parsed components
|
|
222
235
|
*/
|
|
223
|
-
|
|
236
|
+
function parseISO8601Duration(duration) {
|
|
224
237
|
// ISO 8601 duration format: P[n]Y[n]M[n]DT[n]H[n]M[n]S or P[n]W
|
|
225
238
|
const result = {
|
|
226
239
|
years: 0,
|
|
@@ -265,7 +278,7 @@ export function parseISO8601Duration(duration) {
|
|
|
265
278
|
* Convert ISO 8601 duration to milliseconds (approximate for months/years)
|
|
266
279
|
* @param duration - ISO 8601 duration string
|
|
267
280
|
*/
|
|
268
|
-
|
|
281
|
+
function parseISO8601DurationToMs(duration) {
|
|
269
282
|
const parsed = parseISO8601Duration(duration);
|
|
270
283
|
if (!parsed)
|
|
271
284
|
return null;
|
|
@@ -289,7 +302,7 @@ export function parseISO8601DurationToMs(duration) {
|
|
|
289
302
|
* @param timeString - time string to parse
|
|
290
303
|
* @returns object with hours, minutes, seconds, or null if invalid
|
|
291
304
|
*/
|
|
292
|
-
|
|
305
|
+
function parseTime(timeString) {
|
|
293
306
|
const normalized = timeString.trim();
|
|
294
307
|
// 24-hour format: HH:MM or HH:MM:SS
|
|
295
308
|
const match24 = normalized.match(/^(\d{1,2}):(\d{2})(?::(\d{2}))?$/);
|
|
@@ -328,7 +341,7 @@ export function parseTime(timeString) {
|
|
|
328
341
|
* @param dateString - date string to analyze
|
|
329
342
|
* @returns detected format pattern or null
|
|
330
343
|
*/
|
|
331
|
-
|
|
344
|
+
function guessDateFormat(dateString) {
|
|
332
345
|
const normalized = dateString.trim();
|
|
333
346
|
// YYYY-MM-DD
|
|
334
347
|
if (/^\d{4}-\d{2}-\d{2}$/.test(normalized)) {
|
|
@@ -367,7 +380,7 @@ export function guessDateFormat(dateString) {
|
|
|
367
380
|
* Parse a date string using auto-detected format
|
|
368
381
|
* @param dateString - date string to parse
|
|
369
382
|
*/
|
|
370
|
-
|
|
383
|
+
function parseAutoFormat(dateString) {
|
|
371
384
|
const format = guessDateFormat(dateString);
|
|
372
385
|
if (!format) {
|
|
373
386
|
return parseDate(dateString);
|
|
@@ -387,7 +400,7 @@ export function parseAutoFormat(dateString) {
|
|
|
387
400
|
* Parse a date from a natural language date range endpoint
|
|
388
401
|
* @param input - string like "end of month", "start of year", "beginning of week"
|
|
389
402
|
*/
|
|
390
|
-
|
|
403
|
+
function parseRangeEndpoint(input) {
|
|
391
404
|
const now = new Date();
|
|
392
405
|
const lowercaseInput = input.toLowerCase().trim();
|
|
393
406
|
// Start/beginning of period
|
|
@@ -1,11 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* Async time utilities for delays, timeouts, and performance
|
|
3
4
|
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.Stopwatch = void 0;
|
|
7
|
+
exports.sleep = sleep;
|
|
8
|
+
exports.timeout = timeout;
|
|
9
|
+
exports.debounce = debounce;
|
|
10
|
+
exports.throttle = throttle;
|
|
11
|
+
exports.retry = retry;
|
|
12
|
+
exports.createStopwatch = createStopwatch;
|
|
13
|
+
exports.measureTime = measureTime;
|
|
14
|
+
exports.measureAsync = measureAsync;
|
|
15
|
+
exports.benchmark = benchmark;
|
|
4
16
|
/**
|
|
5
17
|
* Sleep for a specified number of milliseconds
|
|
6
18
|
* @param ms - milliseconds to sleep
|
|
7
19
|
*/
|
|
8
|
-
|
|
20
|
+
function sleep(ms) {
|
|
9
21
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
10
22
|
}
|
|
11
23
|
/**
|
|
@@ -14,7 +26,7 @@ export function sleep(ms) {
|
|
|
14
26
|
* @param ms - timeout in milliseconds
|
|
15
27
|
* @param timeoutMessage - optional timeout error message
|
|
16
28
|
*/
|
|
17
|
-
|
|
29
|
+
function timeout(promise, ms, timeoutMessage = 'Operation timed out') {
|
|
18
30
|
return Promise.race([
|
|
19
31
|
promise,
|
|
20
32
|
new Promise((_, reject) => setTimeout(() => reject(new Error(timeoutMessage)), ms))
|
|
@@ -25,7 +37,7 @@ export function timeout(promise, ms, timeoutMessage = 'Operation timed out') {
|
|
|
25
37
|
* @param fn - function to debounce
|
|
26
38
|
* @param delay - delay in milliseconds
|
|
27
39
|
*/
|
|
28
|
-
|
|
40
|
+
function debounce(fn, delay) {
|
|
29
41
|
let timeoutId;
|
|
30
42
|
return (...args) => {
|
|
31
43
|
clearTimeout(timeoutId);
|
|
@@ -37,7 +49,7 @@ export function debounce(fn, delay) {
|
|
|
37
49
|
* @param fn - function to throttle
|
|
38
50
|
* @param delay - delay in milliseconds
|
|
39
51
|
*/
|
|
40
|
-
|
|
52
|
+
function throttle(fn, delay) {
|
|
41
53
|
let lastCall = 0;
|
|
42
54
|
return (...args) => {
|
|
43
55
|
const now = Date.now();
|
|
@@ -54,7 +66,7 @@ export function throttle(fn, delay) {
|
|
|
54
66
|
* @param baseDelay - base delay in milliseconds
|
|
55
67
|
* @param maxDelay - maximum delay in milliseconds
|
|
56
68
|
*/
|
|
57
|
-
|
|
69
|
+
async function retry(fn, maxAttempts = 3, baseDelay = 1000, maxDelay = 10000) {
|
|
58
70
|
let lastError;
|
|
59
71
|
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
60
72
|
try {
|
|
@@ -75,7 +87,7 @@ export async function retry(fn, maxAttempts = 3, baseDelay = 1000, maxDelay = 10
|
|
|
75
87
|
/**
|
|
76
88
|
* Stopwatch for measuring elapsed time
|
|
77
89
|
*/
|
|
78
|
-
|
|
90
|
+
class Stopwatch {
|
|
79
91
|
constructor() {
|
|
80
92
|
this.startTime = null;
|
|
81
93
|
this.endTime = null;
|
|
@@ -167,10 +179,11 @@ export class Stopwatch {
|
|
|
167
179
|
return this.pauseStart !== null;
|
|
168
180
|
}
|
|
169
181
|
}
|
|
182
|
+
exports.Stopwatch = Stopwatch;
|
|
170
183
|
/**
|
|
171
184
|
* Create a new stopwatch instance
|
|
172
185
|
*/
|
|
173
|
-
|
|
186
|
+
function createStopwatch() {
|
|
174
187
|
return new Stopwatch();
|
|
175
188
|
}
|
|
176
189
|
/**
|
|
@@ -178,7 +191,7 @@ export function createStopwatch() {
|
|
|
178
191
|
* @param fn - function to measure
|
|
179
192
|
* @returns tuple of [result, elapsed time in ms]
|
|
180
193
|
*/
|
|
181
|
-
|
|
194
|
+
function measureTime(fn) {
|
|
182
195
|
const start = performance.now();
|
|
183
196
|
const result = fn();
|
|
184
197
|
const elapsed = performance.now() - start;
|
|
@@ -189,7 +202,7 @@ export function measureTime(fn) {
|
|
|
189
202
|
* @param fn - async function to measure
|
|
190
203
|
* @returns promise that resolves to tuple of [result, elapsed time in ms]
|
|
191
204
|
*/
|
|
192
|
-
|
|
205
|
+
async function measureAsync(fn) {
|
|
193
206
|
const start = performance.now();
|
|
194
207
|
const result = await fn();
|
|
195
208
|
const elapsed = performance.now() - start;
|
|
@@ -200,7 +213,7 @@ export async function measureAsync(fn) {
|
|
|
200
213
|
* @param fn - function to benchmark
|
|
201
214
|
* @param iterations - number of iterations to run
|
|
202
215
|
*/
|
|
203
|
-
|
|
216
|
+
function benchmark(fn, iterations = 1000) {
|
|
204
217
|
const times = [];
|
|
205
218
|
for (let i = 0; i < iterations; i++) {
|
|
206
219
|
const [, elapsed] = measureTime(fn);
|