@intech-software/chronera 0.1.0 → 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/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export { createChronera } from "./create-chronera.js";
2
2
  export { compareInstants, compareLocalDates, sameAbsoluteDate, sameCalendarDate, } from "./operations/compare.js";
3
+ export { getAbsoluteDay, isBefore, isAfter, isEqual, isSameDay, isBetween, isToday, addDays, subtractDays, addMonths, subtractMonths, addYears, subtractYears, diffInDays, startOfMonth, endOfMonth, startOfYear, endOfYear, } from "./operations/convenience.js";
3
4
  export { convertCalendarDate } from "./operations/convert-calendar-date.js";
4
5
  export { daysInMonth, getCalendarCapabilities, isLeapYear, isValidCalendarDate, } from "./operations/validate.js";
5
6
  export { getIsoWeek, formatIsoWeek } from "./operations/iso-week.js";
@@ -16,4 +17,4 @@ export { localTime } from "./core/local-time.js";
16
17
  export { localDateTime } from "./core/local-date-time.js";
17
18
  export { dateRange } from "./core/range.js";
18
19
  export { ChroneraError, ChroneraParseError, ChroneraRangeError, ChroneraUnsupportedError, } from "./errors/index.js";
19
- export type { BuiltInCalendarId, CalendarPlugin, CalendarCapabilities, CalendarConversionMetadata, CalendarConversionResult, CalendarDate, CalendarId, ChroneraErrorCode, ChroneraConfig, ChroneraInstance, ChroneraIssue, Comparison, ConvertCalendarOptions, DateRange, DayOfYearFields, Duration, EraId, FiscalFields, FiscalOptions, FormatDateBaseOptions, FormatDateInput, FormatDateOptions, FormatDateRangeOptions, FormatDateTimeOptions, FormatRelativeOptions, FormatTimeOptions, Instant, IsoWeekFields, LocalDate, LocalDateTime, LocalTime, LocaleId, MonthCode, NumberingSystemId, PatternFormatOptions, ParseInstantOptions, ParseLocalDateOptions, PresetName, QuarterNumber, ResolvedChroneraOptions, Rfc2822Options, RuntimeCapabilities, SafeParseResult, TimeZoneId, ZonedDateTime, } from "./public-types.js";
20
+ export type { BuiltInCalendarId, CalendarPlugin, CalendarCapabilities, CalendarConversionMetadata, CalendarConversionResult, CalendarDate, CalendarId, ChroneraErrorCode, ChroneraConfig, ChroneraInstance, ChroneraIssue, Comparison, ConvertCalendarOptions, DateOrCalendarDate, DateRange, DayOfYearFields, Duration, EraId, FiscalFields, FiscalOptions, FormatDateBaseOptions, FormatDateInput, FormatDateOptions, FormatDateRangeOptions, FormatDateTimeOptions, FormatRelativeOptions, FormatTimeOptions, Instant, IntervalInclusivity, IsoWeekFields, LocalDate, LocalDateTime, LocalTime, LocaleId, MonthCode, NumberingSystemId, PatternFormatOptions, ParseInstantOptions, ParseLocalDateOptions, PresetName, QuarterNumber, ResolvedChroneraOptions, Rfc2822Options, RuntimeCapabilities, SafeParseResult, TimeZoneId, ZonedDateTime, } from "./public-types.js";
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  export { createChronera } from "./create-chronera.js";
2
2
  export { compareInstants, compareLocalDates, sameAbsoluteDate, sameCalendarDate, } from "./operations/compare.js";
3
+ export { getAbsoluteDay, isBefore, isAfter, isEqual, isSameDay, isBetween, isToday, addDays, subtractDays, addMonths, subtractMonths, addYears, subtractYears, diffInDays, startOfMonth, endOfMonth, startOfYear, endOfYear, } from "./operations/convenience.js";
3
4
  export { convertCalendarDate } from "./operations/convert-calendar-date.js";
4
5
  export { daysInMonth, getCalendarCapabilities, isLeapYear, isValidCalendarDate, } from "./operations/validate.js";
5
6
  export { getIsoWeek, formatIsoWeek } from "./operations/iso-week.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AAE5E,OAAO,EACL,WAAW,EACX,uBAAuB,EACvB,UAAU,EACV,mBAAmB,GACpB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAErE,OAAO,EACL,YAAY,EACZ,wBAAwB,EACxB,iBAAiB,GAClB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,4BAA4B,EAC5B,8BAA8B,GAC/B,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEnE,OAAO,EACL,UAAU,EACV,eAAe,EACf,cAAc,EACd,cAAc,EACd,UAAU,EACV,iBAAiB,EACjB,aAAa,EACb,4BAA4B,EAC5B,uCAAuC,EACvC,0BAA0B,EAC1B,wBAAwB,EACxB,2BAA2B,EAC3B,uBAAuB,EACvB,wBAAwB,EACxB,2BAA2B,EAC3B,8BAA8B,EAC9B,sBAAsB,EACtB,0BAA0B,EAC1B,6BAA6B,EAC7B,6BAA6B,EAC7B,sBAAsB,EACtB,6BAA6B,EAC7B,4BAA4B,EAC5B,2BAA2B,EAC3B,uBAAuB,EACvB,2BAA2B,EAC3B,8BAA8B,EAC9B,yBAAyB,EACzB,yBAAyB,EACzB,kBAAkB,EAClB,sBAAsB,EACtB,yBAAyB,EACzB,kBAAkB,EAClB,sBAAsB,EACtB,yBAAyB,GAC1B,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,eAAe,EACf,4BAA4B,EAC5B,uBAAuB,GACxB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAEnE,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjD,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE1D,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,kBAAkB,EAClB,wBAAwB,GACzB,MAAM,mBAAmB,CAAC","sourcesContent":["export { createChronera } from \"./create-chronera.js\";\n\nexport {\n compareInstants,\n compareLocalDates,\n sameAbsoluteDate,\n sameCalendarDate,\n} from \"./operations/compare.js\";\n\nexport { convertCalendarDate } from \"./operations/convert-calendar-date.js\";\n\nexport {\n daysInMonth,\n getCalendarCapabilities,\n isLeapYear,\n isValidCalendarDate,\n} from \"./operations/validate.js\";\n\nexport { getIsoWeek, formatIsoWeek } from \"./operations/iso-week.js\";\n\nexport {\n getDayOfYear,\n getDayOfYearWithRegistry,\n formatOrdinalDate,\n} from \"./operations/day-of-year.js\";\n\nexport {\n toJulianDayNumber,\n toModifiedJulianDay,\n localDateFromJulianDayNumber,\n localDateFromModifiedJulianDay,\n} from \"./operations/julian-day.js\";\n\nexport { getQuarter, getFiscalYear } from \"./operations/fiscal.js\";\n\nexport {\n formatDate,\n formatDateRange,\n formatDateTime,\n formatRelative,\n formatTime,\n formatWithPattern,\n formatRfc2822,\n formatJapaneseOfficialPreset,\n formatJapaneseOfficialWithWeekdayPreset,\n formatTaiwanOfficialPreset,\n formatThaiOfficialPreset,\n formatArabicGregorianPreset,\n formatArabicHijriPreset,\n formatChineseShortPreset,\n formatChineseStandardPreset,\n formatChineseWithWeekdayPreset,\n formatFrenchLongPreset,\n formatFrenchStandardPreset,\n formatFrenchWithWeekdayPreset,\n formatGermanDinStandardPreset,\n formatGermanLongPreset,\n formatGermanWithWeekdayPreset,\n formatJapaneseEraShortPreset,\n formatJapaneseSeirekiPreset,\n formatSpanishLongPreset,\n formatSpanishStandardPreset,\n formatSpanishWithWeekdayPreset,\n formatThaiShortDatePreset,\n formatThaiSlashDatePreset,\n formatUkLongPreset,\n formatUkStandardPreset,\n formatUkWithWeekdayPreset,\n formatUsLongPreset,\n formatUsStandardPreset,\n formatUsWithWeekdayPreset,\n} from \"./format/index.js\";\n\nexport {\n parseInstant,\n parseLocalDate,\n safeParseInstant,\n safeParseLocalDate,\n} from \"./parse/index.js\";\n\nexport {\n instantFromDate,\n instantFromEpochMilliseconds,\n instantFromEpochSeconds,\n} from \"./core/instant.js\";\n\nexport { getRuntimeCapabilities } from \"./runtime/capabilities.js\";\n\nexport { calendarDate } from \"./core/calendar-date.js\";\n\nexport { localDate } from \"./core/local-date.js\";\n\nexport { localTime } from \"./core/local-time.js\";\n\nexport { localDateTime } from \"./core/local-date-time.js\";\n\nexport { dateRange } from \"./core/range.js\";\n\nexport {\n ChroneraError,\n ChroneraParseError,\n ChroneraRangeError,\n ChroneraUnsupportedError,\n} from \"./errors/index.js\";\n\nexport type {\n BuiltInCalendarId,\n CalendarPlugin,\n CalendarCapabilities,\n CalendarConversionMetadata,\n CalendarConversionResult,\n CalendarDate,\n CalendarId,\n ChroneraErrorCode,\n ChroneraConfig,\n ChroneraInstance,\n ChroneraIssue,\n Comparison,\n ConvertCalendarOptions,\n DateRange,\n DayOfYearFields,\n Duration,\n EraId,\n FiscalFields,\n FiscalOptions,\n FormatDateBaseOptions,\n FormatDateInput,\n FormatDateOptions,\n FormatDateRangeOptions,\n FormatDateTimeOptions,\n FormatRelativeOptions,\n FormatTimeOptions,\n Instant,\n IsoWeekFields,\n LocalDate,\n LocalDateTime,\n LocalTime,\n LocaleId,\n MonthCode,\n NumberingSystemId,\n PatternFormatOptions,\n ParseInstantOptions,\n ParseLocalDateOptions,\n PresetName,\n QuarterNumber,\n ResolvedChroneraOptions,\n Rfc2822Options,\n RuntimeCapabilities,\n SafeParseResult,\n TimeZoneId,\n ZonedDateTime,\n} from \"./public-types.js\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,cAAc,EACd,QAAQ,EACR,OAAO,EACP,OAAO,EACP,SAAS,EACT,SAAS,EACT,OAAO,EACP,OAAO,EACP,YAAY,EACZ,SAAS,EACT,cAAc,EACd,QAAQ,EACR,aAAa,EACb,UAAU,EACV,YAAY,EACZ,UAAU,EACV,WAAW,EACX,SAAS,GACV,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AAE5E,OAAO,EACL,WAAW,EACX,uBAAuB,EACvB,UAAU,EACV,mBAAmB,GACpB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAErE,OAAO,EACL,YAAY,EACZ,wBAAwB,EACxB,iBAAiB,GAClB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,4BAA4B,EAC5B,8BAA8B,GAC/B,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEnE,OAAO,EACL,UAAU,EACV,eAAe,EACf,cAAc,EACd,cAAc,EACd,UAAU,EACV,iBAAiB,EACjB,aAAa,EACb,4BAA4B,EAC5B,uCAAuC,EACvC,0BAA0B,EAC1B,wBAAwB,EACxB,2BAA2B,EAC3B,uBAAuB,EACvB,wBAAwB,EACxB,2BAA2B,EAC3B,8BAA8B,EAC9B,sBAAsB,EACtB,0BAA0B,EAC1B,6BAA6B,EAC7B,6BAA6B,EAC7B,sBAAsB,EACtB,6BAA6B,EAC7B,4BAA4B,EAC5B,2BAA2B,EAC3B,uBAAuB,EACvB,2BAA2B,EAC3B,8BAA8B,EAC9B,yBAAyB,EACzB,yBAAyB,EACzB,kBAAkB,EAClB,sBAAsB,EACtB,yBAAyB,EACzB,kBAAkB,EAClB,sBAAsB,EACtB,yBAAyB,GAC1B,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,eAAe,EACf,4BAA4B,EAC5B,uBAAuB,GACxB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAEnE,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjD,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE1D,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,kBAAkB,EAClB,wBAAwB,GACzB,MAAM,mBAAmB,CAAC","sourcesContent":["export { createChronera } from \"./create-chronera.js\";\n\nexport {\n compareInstants,\n compareLocalDates,\n sameAbsoluteDate,\n sameCalendarDate,\n} from \"./operations/compare.js\";\n\nexport {\n getAbsoluteDay,\n isBefore,\n isAfter,\n isEqual,\n isSameDay,\n isBetween,\n isToday,\n addDays,\n subtractDays,\n addMonths,\n subtractMonths,\n addYears,\n subtractYears,\n diffInDays,\n startOfMonth,\n endOfMonth,\n startOfYear,\n endOfYear,\n} from \"./operations/convenience.js\";\n\nexport { convertCalendarDate } from \"./operations/convert-calendar-date.js\";\n\nexport {\n daysInMonth,\n getCalendarCapabilities,\n isLeapYear,\n isValidCalendarDate,\n} from \"./operations/validate.js\";\n\nexport { getIsoWeek, formatIsoWeek } from \"./operations/iso-week.js\";\n\nexport {\n getDayOfYear,\n getDayOfYearWithRegistry,\n formatOrdinalDate,\n} from \"./operations/day-of-year.js\";\n\nexport {\n toJulianDayNumber,\n toModifiedJulianDay,\n localDateFromJulianDayNumber,\n localDateFromModifiedJulianDay,\n} from \"./operations/julian-day.js\";\n\nexport { getQuarter, getFiscalYear } from \"./operations/fiscal.js\";\n\nexport {\n formatDate,\n formatDateRange,\n formatDateTime,\n formatRelative,\n formatTime,\n formatWithPattern,\n formatRfc2822,\n formatJapaneseOfficialPreset,\n formatJapaneseOfficialWithWeekdayPreset,\n formatTaiwanOfficialPreset,\n formatThaiOfficialPreset,\n formatArabicGregorianPreset,\n formatArabicHijriPreset,\n formatChineseShortPreset,\n formatChineseStandardPreset,\n formatChineseWithWeekdayPreset,\n formatFrenchLongPreset,\n formatFrenchStandardPreset,\n formatFrenchWithWeekdayPreset,\n formatGermanDinStandardPreset,\n formatGermanLongPreset,\n formatGermanWithWeekdayPreset,\n formatJapaneseEraShortPreset,\n formatJapaneseSeirekiPreset,\n formatSpanishLongPreset,\n formatSpanishStandardPreset,\n formatSpanishWithWeekdayPreset,\n formatThaiShortDatePreset,\n formatThaiSlashDatePreset,\n formatUkLongPreset,\n formatUkStandardPreset,\n formatUkWithWeekdayPreset,\n formatUsLongPreset,\n formatUsStandardPreset,\n formatUsWithWeekdayPreset,\n} from \"./format/index.js\";\n\nexport {\n parseInstant,\n parseLocalDate,\n safeParseInstant,\n safeParseLocalDate,\n} from \"./parse/index.js\";\n\nexport {\n instantFromDate,\n instantFromEpochMilliseconds,\n instantFromEpochSeconds,\n} from \"./core/instant.js\";\n\nexport { getRuntimeCapabilities } from \"./runtime/capabilities.js\";\n\nexport { calendarDate } from \"./core/calendar-date.js\";\n\nexport { localDate } from \"./core/local-date.js\";\n\nexport { localTime } from \"./core/local-time.js\";\n\nexport { localDateTime } from \"./core/local-date-time.js\";\n\nexport { dateRange } from \"./core/range.js\";\n\nexport {\n ChroneraError,\n ChroneraParseError,\n ChroneraRangeError,\n ChroneraUnsupportedError,\n} from \"./errors/index.js\";\n\nexport type {\n BuiltInCalendarId,\n CalendarPlugin,\n CalendarCapabilities,\n CalendarConversionMetadata,\n CalendarConversionResult,\n CalendarDate,\n CalendarId,\n ChroneraErrorCode,\n ChroneraConfig,\n ChroneraInstance,\n ChroneraIssue,\n Comparison,\n ConvertCalendarOptions,\n DateOrCalendarDate,\n DateRange,\n DayOfYearFields,\n Duration,\n EraId,\n FiscalFields,\n FiscalOptions,\n FormatDateBaseOptions,\n FormatDateInput,\n FormatDateOptions,\n FormatDateRangeOptions,\n FormatDateTimeOptions,\n FormatRelativeOptions,\n FormatTimeOptions,\n Instant,\n IntervalInclusivity,\n IsoWeekFields,\n LocalDate,\n LocalDateTime,\n LocalTime,\n LocaleId,\n MonthCode,\n NumberingSystemId,\n PatternFormatOptions,\n ParseInstantOptions,\n ParseLocalDateOptions,\n PresetName,\n QuarterNumber,\n ResolvedChroneraOptions,\n Rfc2822Options,\n RuntimeCapabilities,\n SafeParseResult,\n TimeZoneId,\n ZonedDateTime,\n} from \"./public-types.js\";\n"]}
@@ -0,0 +1,82 @@
1
+ import type { DateOrCalendarDate, IntervalInclusivity, TimeZoneId } from "../public-types.js";
2
+ /**
3
+ * Returns the astronomical AbsoluteDay integer for any LocalDate or CalendarDate.
4
+ */
5
+ export declare function getAbsoluteDay(date: DateOrCalendarDate): number;
6
+ /**
7
+ * Returns true if date1 is strictly before date2 in the timeline.
8
+ * Works seamlessly across all calendar systems.
9
+ */
10
+ export declare function isBefore(date1: DateOrCalendarDate, date2: DateOrCalendarDate): boolean;
11
+ /**
12
+ * Returns true if date1 is strictly after date2 in the timeline.
13
+ * Works seamlessly across all calendar systems.
14
+ */
15
+ export declare function isAfter(date1: DateOrCalendarDate, date2: DateOrCalendarDate): boolean;
16
+ /**
17
+ * Returns true if date1 and date2 represent the exact same absolute day in the timeline.
18
+ * For example, Thai Buddhist BE 2569-09-04 and Gregorian CE 2026-09-04 are equal.
19
+ */
20
+ export declare function isEqual(date1: DateOrCalendarDate, date2: DateOrCalendarDate): boolean;
21
+ /**
22
+ * Alias for isEqual: returns true if both dates represent the same day in the timeline.
23
+ */
24
+ export declare function isSameDay(date1: DateOrCalendarDate, date2: DateOrCalendarDate): boolean;
25
+ /**
26
+ * Returns true if date falls between start and end.
27
+ * @param inclusivity - '[]' (inclusive), '[)' (half-open), '(]' (half-open), '()' (exclusive). Default is '[]'.
28
+ */
29
+ export declare function isBetween(date: DateOrCalendarDate, start: DateOrCalendarDate, end: DateOrCalendarDate, inclusivity?: IntervalInclusivity): boolean;
30
+ /**
31
+ * Returns true if date represents today in the specified timezone (or the host environment's timezone).
32
+ */
33
+ export declare function isToday(date: DateOrCalendarDate, timeZone?: TimeZoneId): boolean;
34
+ /**
35
+ * Adds days to a LocalDate or CalendarDate.
36
+ * Operates on astronomical timeline days, ensuring 100% precision across all calendars.
37
+ */
38
+ export declare function addDays<T extends DateOrCalendarDate>(date: T, amount: number, overflow?: "constrain" | "reject"): T;
39
+ /**
40
+ * Subtracts days from a LocalDate or CalendarDate.
41
+ */
42
+ export declare function subtractDays<T extends DateOrCalendarDate>(date: T, amount: number, overflow?: "constrain" | "reject"): T;
43
+ /**
44
+ * Adds months to a LocalDate or CalendarDate.
45
+ * Handles month-end clamping according to overflow parameter ("constrain" or "reject").
46
+ */
47
+ export declare function addMonths<T extends DateOrCalendarDate>(date: T, amount: number, overflow?: "constrain" | "reject"): T;
48
+ /**
49
+ * Subtracts months from a LocalDate or CalendarDate.
50
+ */
51
+ export declare function subtractMonths<T extends DateOrCalendarDate>(date: T, amount: number, overflow?: "constrain" | "reject"): T;
52
+ /**
53
+ * Adds years to a LocalDate or CalendarDate.
54
+ * Handles leap year constraints according to overflow parameter ("constrain" or "reject").
55
+ */
56
+ export declare function addYears<T extends DateOrCalendarDate>(date: T, amount: number, overflow?: "constrain" | "reject"): T;
57
+ /**
58
+ * Subtracts years from a LocalDate or CalendarDate.
59
+ */
60
+ export declare function subtractYears<T extends DateOrCalendarDate>(date: T, amount: number, overflow?: "constrain" | "reject"): T;
61
+ /**
62
+ * Returns the signed difference in days between two dates (left - right).
63
+ * Works across different calendars.
64
+ */
65
+ export declare function diffInDays(left: DateOrCalendarDate, right: DateOrCalendarDate): number;
66
+ /**
67
+ * Returns the start of the month (Day 1) for a LocalDate or CalendarDate.
68
+ */
69
+ export declare function startOfMonth<T extends DateOrCalendarDate>(date: T): T;
70
+ /**
71
+ * Returns the end of the month (last day) for a LocalDate or CalendarDate.
72
+ * Properly accounts for leap years in any calendar.
73
+ */
74
+ export declare function endOfMonth<T extends DateOrCalendarDate>(date: T): T;
75
+ /**
76
+ * Returns the start of the year (Month 1, Day 1) for a LocalDate or CalendarDate.
77
+ */
78
+ export declare function startOfYear<T extends DateOrCalendarDate>(date: T): T;
79
+ /**
80
+ * Returns the end of the year (last day of the final month) for a LocalDate or CalendarDate.
81
+ */
82
+ export declare function endOfYear<T extends DateOrCalendarDate>(date: T): T;
@@ -0,0 +1,396 @@
1
+ import { defaultCalendarRegistry } from "../calendar/registry.js";
2
+ import { absoluteDayFromGregorianFields, gregorianFieldsFromAbsoluteDay, } from "../core/absolute-day.js";
3
+ import { daysInGregorianMonth } from "../core/gregorian-math.js";
4
+ import { ChroneraError } from "../errors/errors.js";
5
+ import { projectInstantToZonedFields } from "../runtime/timezone.js";
6
+ /**
7
+ * Returns the astronomical AbsoluteDay integer for any LocalDate or CalendarDate.
8
+ */
9
+ export function getAbsoluteDay(date) {
10
+ if (date.kind === "local-date") {
11
+ return absoluteDayFromGregorianFields(date.year, date.month, date.day);
12
+ }
13
+ const adapter = defaultCalendarRegistry.getAdapter(date.calendar);
14
+ if (!adapter.converter) {
15
+ throw new ChroneraError("CHRONERA_UNSUPPORTED_OPERATION", `Calendar "${date.calendar}" does not support conversion to absolute timeline.`);
16
+ }
17
+ return adapter.converter.toAbsoluteDay(date);
18
+ }
19
+ // ---------------------------------------------------------------------------
20
+ // Comparison Helpers
21
+ // ---------------------------------------------------------------------------
22
+ /**
23
+ * Returns true if date1 is strictly before date2 in the timeline.
24
+ * Works seamlessly across all calendar systems.
25
+ */
26
+ export function isBefore(date1, date2) {
27
+ return getAbsoluteDay(date1) < getAbsoluteDay(date2);
28
+ }
29
+ /**
30
+ * Returns true if date1 is strictly after date2 in the timeline.
31
+ * Works seamlessly across all calendar systems.
32
+ */
33
+ export function isAfter(date1, date2) {
34
+ return getAbsoluteDay(date1) > getAbsoluteDay(date2);
35
+ }
36
+ /**
37
+ * Returns true if date1 and date2 represent the exact same absolute day in the timeline.
38
+ * For example, Thai Buddhist BE 2569-09-04 and Gregorian CE 2026-09-04 are equal.
39
+ */
40
+ export function isEqual(date1, date2) {
41
+ return getAbsoluteDay(date1) === getAbsoluteDay(date2);
42
+ }
43
+ /**
44
+ * Alias for isEqual: returns true if both dates represent the same day in the timeline.
45
+ */
46
+ export function isSameDay(date1, date2) {
47
+ return isEqual(date1, date2);
48
+ }
49
+ /**
50
+ * Returns true if date falls between start and end.
51
+ * @param inclusivity - '[]' (inclusive), '[)' (half-open), '(]' (half-open), '()' (exclusive). Default is '[]'.
52
+ */
53
+ export function isBetween(date, start, end, inclusivity = "[]") {
54
+ const target = getAbsoluteDay(date);
55
+ const s = getAbsoluteDay(start);
56
+ const e = getAbsoluteDay(end);
57
+ if (s > e) {
58
+ throw new ChroneraError("CHRONERA_OUT_OF_RANGE", "Start date must not be after end date.");
59
+ }
60
+ switch (inclusivity) {
61
+ case "[]":
62
+ return target >= s && target <= e;
63
+ case "[)":
64
+ return target >= s && target < e;
65
+ case "(]":
66
+ return target > s && target <= e;
67
+ case "()":
68
+ return target > s && target < e;
69
+ default:
70
+ throw new ChroneraError("CHRONERA_INVALID_DATE", `Invalid inclusivity: "${String(inclusivity)}". Expected "[]", "[)", "(]", or "()".`);
71
+ }
72
+ }
73
+ /**
74
+ * Returns true if date represents today in the specified timezone (or the host environment's timezone).
75
+ */
76
+ export function isToday(date, timeZone) {
77
+ const tz = timeZone ??
78
+ (typeof Intl !== "undefined"
79
+ ? Intl.DateTimeFormat().resolvedOptions().timeZone
80
+ : "UTC") ??
81
+ "UTC";
82
+ const nowInstant = {
83
+ kind: "instant",
84
+ epochMilliseconds: Date.now(),
85
+ };
86
+ const zoned = projectInstantToZonedFields(nowInstant, tz);
87
+ const todayAbsDay = absoluteDayFromGregorianFields(zoned.year, zoned.month, zoned.day);
88
+ return getAbsoluteDay(date) === todayAbsDay;
89
+ }
90
+ // ---------------------------------------------------------------------------
91
+ // Date Arithmetic Shortcuts
92
+ // ---------------------------------------------------------------------------
93
+ /**
94
+ * Adds days to a LocalDate or CalendarDate.
95
+ * Operates on astronomical timeline days, ensuring 100% precision across all calendars.
96
+ */
97
+ export function addDays(date, amount, overflow = "reject") {
98
+ if (date.kind === "local-date") {
99
+ const currentAbs = absoluteDayFromGregorianFields(date.year, date.month, date.day);
100
+ const newAbs = currentAbs + amount;
101
+ const fields = gregorianFieldsFromAbsoluteDay(newAbs);
102
+ return {
103
+ kind: "local-date",
104
+ year: fields.year,
105
+ month: fields.month,
106
+ day: fields.day,
107
+ };
108
+ }
109
+ const adapter = defaultCalendarRegistry.getAdapter(date.calendar);
110
+ if (adapter.arithmetic) {
111
+ return adapter.arithmetic.add(date, { days: amount }, overflow);
112
+ }
113
+ if (adapter.converter) {
114
+ const currentAbs = adapter.converter.toAbsoluteDay(date);
115
+ const newAbs = currentAbs + amount;
116
+ return adapter.converter.fromAbsoluteDay(newAbs);
117
+ }
118
+ throw new ChroneraError("CHRONERA_UNSUPPORTED_OPERATION", `Calendar "${date.calendar}" does not support date arithmetic or conversion.`);
119
+ }
120
+ /**
121
+ * Subtracts days from a LocalDate or CalendarDate.
122
+ */
123
+ export function subtractDays(date, amount, overflow = "reject") {
124
+ return addDays(date, -amount, overflow);
125
+ }
126
+ /**
127
+ * Adds months to a LocalDate or CalendarDate.
128
+ * Handles month-end clamping according to overflow parameter ("constrain" or "reject").
129
+ */
130
+ export function addMonths(date, amount, overflow = "reject") {
131
+ if (date.kind === "local-date") {
132
+ const currentMonth = date.month;
133
+ const totalMonths = date.year * 12 + (currentMonth - 1) + amount;
134
+ const year = Math.floor(totalMonths / 12);
135
+ const month = (((totalMonths % 12) + 12) % 12) + 1;
136
+ const maxDays = daysInGregorianMonth(year, month);
137
+ let day = date.day;
138
+ if (day > maxDays) {
139
+ if (overflow === "reject") {
140
+ throw new ChroneraError("CHRONERA_OUT_OF_RANGE", `Day ${day} exceeds maximum days ${maxDays} for month ${month} in year ${year}.`);
141
+ }
142
+ day = maxDays;
143
+ }
144
+ return {
145
+ kind: "local-date",
146
+ year,
147
+ month,
148
+ day,
149
+ };
150
+ }
151
+ const adapter = defaultCalendarRegistry.getAdapter(date.calendar);
152
+ if (adapter.arithmetic) {
153
+ return adapter.arithmetic.add(date, { months: amount }, overflow);
154
+ }
155
+ const currentMonth = date.month ?? Number.parseInt(date.monthCode.slice(1), 10);
156
+ const totalMonths = date.year * 12 + (currentMonth - 1) + amount;
157
+ const year = Math.floor(totalMonths / 12);
158
+ const month = (((totalMonths % 12) + 12) % 12) + 1;
159
+ const monthCode = `M${String(month).padStart(2, "0")}`;
160
+ const maxDays = adapter.validator.daysInMonth(year, monthCode);
161
+ let day = date.day;
162
+ if (day > maxDays) {
163
+ if (overflow === "reject") {
164
+ throw new ChroneraError("CHRONERA_OUT_OF_RANGE", `Day ${day} exceeds maximum days ${maxDays} for month ${monthCode} in year ${year}.`);
165
+ }
166
+ day = maxDays;
167
+ }
168
+ if (adapter.converter) {
169
+ const candidate = {
170
+ kind: "calendar-date",
171
+ calendar: date.calendar,
172
+ year,
173
+ monthCode,
174
+ month,
175
+ day,
176
+ };
177
+ const absDay = adapter.converter.toAbsoluteDay(candidate);
178
+ return adapter.converter.fromAbsoluteDay(absDay);
179
+ }
180
+ return {
181
+ ...date,
182
+ year,
183
+ monthCode,
184
+ month,
185
+ day,
186
+ };
187
+ }
188
+ /**
189
+ * Subtracts months from a LocalDate or CalendarDate.
190
+ */
191
+ export function subtractMonths(date, amount, overflow = "reject") {
192
+ return addMonths(date, -amount, overflow);
193
+ }
194
+ /**
195
+ * Adds years to a LocalDate or CalendarDate.
196
+ * Handles leap year constraints according to overflow parameter ("constrain" or "reject").
197
+ */
198
+ export function addYears(date, amount, overflow = "reject") {
199
+ if (date.kind === "local-date") {
200
+ const targetYear = date.year + amount;
201
+ const maxDays = daysInGregorianMonth(targetYear, date.month);
202
+ let day = date.day;
203
+ if (day > maxDays) {
204
+ if (overflow === "reject") {
205
+ throw new ChroneraError("CHRONERA_OUT_OF_RANGE", `Day ${day} exceeds maximum days ${maxDays} for month ${date.month} in year ${targetYear}.`);
206
+ }
207
+ day = maxDays;
208
+ }
209
+ return {
210
+ kind: "local-date",
211
+ year: targetYear,
212
+ month: date.month,
213
+ day,
214
+ };
215
+ }
216
+ const adapter = defaultCalendarRegistry.getAdapter(date.calendar);
217
+ if (adapter.arithmetic) {
218
+ return adapter.arithmetic.add(date, { years: amount }, overflow);
219
+ }
220
+ const targetYear = date.year + amount;
221
+ const month = date.month ?? Number.parseInt(date.monthCode.slice(1), 10);
222
+ const maxDays = adapter.validator.daysInMonth(targetYear, date.monthCode);
223
+ let day = date.day;
224
+ if (day > maxDays) {
225
+ if (overflow === "reject") {
226
+ throw new ChroneraError("CHRONERA_OUT_OF_RANGE", `Day ${day} exceeds maximum days ${maxDays} for month ${date.monthCode} in year ${targetYear}.`);
227
+ }
228
+ day = maxDays;
229
+ }
230
+ if (adapter.converter) {
231
+ const candidate = {
232
+ kind: "calendar-date",
233
+ calendar: date.calendar,
234
+ year: targetYear,
235
+ monthCode: date.monthCode,
236
+ month,
237
+ day,
238
+ };
239
+ const absDay = adapter.converter.toAbsoluteDay(candidate);
240
+ return adapter.converter.fromAbsoluteDay(absDay);
241
+ }
242
+ return {
243
+ ...date,
244
+ year: targetYear,
245
+ day,
246
+ eraYear: date.eraYear !== undefined ? date.eraYear + amount : undefined,
247
+ };
248
+ }
249
+ /**
250
+ * Subtracts years from a LocalDate or CalendarDate.
251
+ */
252
+ export function subtractYears(date, amount, overflow = "reject") {
253
+ return addYears(date, -amount, overflow);
254
+ }
255
+ /**
256
+ * Returns the signed difference in days between two dates (left - right).
257
+ * Works across different calendars.
258
+ */
259
+ export function diffInDays(left, right) {
260
+ return getAbsoluteDay(left) - getAbsoluteDay(right);
261
+ }
262
+ // ---------------------------------------------------------------------------
263
+ // Date Boundary Helpers
264
+ // ---------------------------------------------------------------------------
265
+ /**
266
+ * Returns the start of the month (Day 1) for a LocalDate or CalendarDate.
267
+ */
268
+ export function startOfMonth(date) {
269
+ if (date.kind === "local-date") {
270
+ return {
271
+ kind: "local-date",
272
+ year: date.year,
273
+ month: date.month,
274
+ day: 1,
275
+ };
276
+ }
277
+ const adapter = defaultCalendarRegistry.getAdapter(date.calendar);
278
+ if (adapter.converter) {
279
+ const month = date.month ?? Number.parseInt(date.monthCode.slice(1), 10);
280
+ const candidate = {
281
+ kind: "calendar-date",
282
+ calendar: date.calendar,
283
+ year: date.year,
284
+ monthCode: date.monthCode,
285
+ month,
286
+ day: 1,
287
+ };
288
+ const absDay = adapter.converter.toAbsoluteDay(candidate);
289
+ return adapter.converter.fromAbsoluteDay(absDay);
290
+ }
291
+ return {
292
+ ...date,
293
+ day: 1,
294
+ };
295
+ }
296
+ /**
297
+ * Returns the end of the month (last day) for a LocalDate or CalendarDate.
298
+ * Properly accounts for leap years in any calendar.
299
+ */
300
+ export function endOfMonth(date) {
301
+ if (date.kind === "local-date") {
302
+ const maxDay = daysInGregorianMonth(date.year, date.month);
303
+ return {
304
+ kind: "local-date",
305
+ year: date.year,
306
+ month: date.month,
307
+ day: maxDay,
308
+ };
309
+ }
310
+ const adapter = defaultCalendarRegistry.getAdapter(date.calendar);
311
+ const maxDay = adapter.validator.daysInMonth(date.year, date.monthCode);
312
+ if (adapter.converter) {
313
+ const month = date.month ?? Number.parseInt(date.monthCode.slice(1), 10);
314
+ const candidate = {
315
+ kind: "calendar-date",
316
+ calendar: date.calendar,
317
+ year: date.year,
318
+ monthCode: date.monthCode,
319
+ month,
320
+ day: maxDay,
321
+ };
322
+ const absDay = adapter.converter.toAbsoluteDay(candidate);
323
+ return adapter.converter.fromAbsoluteDay(absDay);
324
+ }
325
+ return {
326
+ ...date,
327
+ day: maxDay,
328
+ };
329
+ }
330
+ /**
331
+ * Returns the start of the year (Month 1, Day 1) for a LocalDate or CalendarDate.
332
+ */
333
+ export function startOfYear(date) {
334
+ if (date.kind === "local-date") {
335
+ return {
336
+ kind: "local-date",
337
+ year: date.year,
338
+ month: 1,
339
+ day: 1,
340
+ };
341
+ }
342
+ const adapter = defaultCalendarRegistry.getAdapter(date.calendar);
343
+ if (adapter.converter) {
344
+ const candidate = {
345
+ kind: "calendar-date",
346
+ calendar: date.calendar,
347
+ year: date.year,
348
+ monthCode: "M01",
349
+ month: 1,
350
+ day: 1,
351
+ };
352
+ const absDay = adapter.converter.toAbsoluteDay(candidate);
353
+ return adapter.converter.fromAbsoluteDay(absDay);
354
+ }
355
+ return {
356
+ ...date,
357
+ monthCode: "M01",
358
+ month: 1,
359
+ day: 1,
360
+ };
361
+ }
362
+ /**
363
+ * Returns the end of the year (last day of the final month) for a LocalDate or CalendarDate.
364
+ */
365
+ export function endOfYear(date) {
366
+ if (date.kind === "local-date") {
367
+ return {
368
+ kind: "local-date",
369
+ year: date.year,
370
+ month: 12,
371
+ day: 31,
372
+ };
373
+ }
374
+ const adapter = defaultCalendarRegistry.getAdapter(date.calendar);
375
+ const finalMonthCode = "M12";
376
+ const maxDay = adapter.validator.daysInMonth(date.year, finalMonthCode);
377
+ if (adapter.converter) {
378
+ const candidate = {
379
+ kind: "calendar-date",
380
+ calendar: date.calendar,
381
+ year: date.year,
382
+ monthCode: finalMonthCode,
383
+ month: 12,
384
+ day: maxDay,
385
+ };
386
+ const absDay = adapter.converter.toAbsoluteDay(candidate);
387
+ return adapter.converter.fromAbsoluteDay(absDay);
388
+ }
389
+ return {
390
+ ...date,
391
+ monthCode: finalMonthCode,
392
+ month: 12,
393
+ day: maxDay,
394
+ };
395
+ }
396
+ //# sourceMappingURL=convenience.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"convenience.js","sourceRoot":"","sources":["../../src/operations/convenience.ts"],"names":[],"mappings":"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","sourcesContent":["import { defaultCalendarRegistry } from \"../calendar/registry.js\";\nimport {\n absoluteDayFromGregorianFields,\n gregorianFieldsFromAbsoluteDay,\n} from \"../core/absolute-day.js\";\nimport { daysInGregorianMonth } from \"../core/gregorian-math.js\";\nimport { ChroneraError } from \"../errors/errors.js\";\nimport { projectInstantToZonedFields } from \"../runtime/timezone.js\";\n\nimport type {\n CalendarDate,\n DateOrCalendarDate,\n Instant,\n IntervalInclusivity,\n MonthCode,\n TimeZoneId,\n} from \"../public-types.js\";\n\n/**\n * Returns the astronomical AbsoluteDay integer for any LocalDate or CalendarDate.\n */\nexport function getAbsoluteDay(date: DateOrCalendarDate): number {\n if (date.kind === \"local-date\") {\n return absoluteDayFromGregorianFields(date.year, date.month, date.day);\n }\n const adapter = defaultCalendarRegistry.getAdapter(date.calendar);\n if (!adapter.converter) {\n throw new ChroneraError(\n \"CHRONERA_UNSUPPORTED_OPERATION\",\n `Calendar \"${date.calendar}\" does not support conversion to absolute timeline.`,\n );\n }\n return adapter.converter.toAbsoluteDay(date);\n}\n\n// ---------------------------------------------------------------------------\n// Comparison Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Returns true if date1 is strictly before date2 in the timeline.\n * Works seamlessly across all calendar systems.\n */\nexport function isBefore(\n date1: DateOrCalendarDate,\n date2: DateOrCalendarDate,\n): boolean {\n return getAbsoluteDay(date1) < getAbsoluteDay(date2);\n}\n\n/**\n * Returns true if date1 is strictly after date2 in the timeline.\n * Works seamlessly across all calendar systems.\n */\nexport function isAfter(\n date1: DateOrCalendarDate,\n date2: DateOrCalendarDate,\n): boolean {\n return getAbsoluteDay(date1) > getAbsoluteDay(date2);\n}\n\n/**\n * Returns true if date1 and date2 represent the exact same absolute day in the timeline.\n * For example, Thai Buddhist BE 2569-09-04 and Gregorian CE 2026-09-04 are equal.\n */\nexport function isEqual(\n date1: DateOrCalendarDate,\n date2: DateOrCalendarDate,\n): boolean {\n return getAbsoluteDay(date1) === getAbsoluteDay(date2);\n}\n\n/**\n * Alias for isEqual: returns true if both dates represent the same day in the timeline.\n */\nexport function isSameDay(\n date1: DateOrCalendarDate,\n date2: DateOrCalendarDate,\n): boolean {\n return isEqual(date1, date2);\n}\n\n/**\n * Returns true if date falls between start and end.\n * @param inclusivity - '[]' (inclusive), '[)' (half-open), '(]' (half-open), '()' (exclusive). Default is '[]'.\n */\nexport function isBetween(\n date: DateOrCalendarDate,\n start: DateOrCalendarDate,\n end: DateOrCalendarDate,\n inclusivity: IntervalInclusivity = \"[]\",\n): boolean {\n const target = getAbsoluteDay(date);\n const s = getAbsoluteDay(start);\n const e = getAbsoluteDay(end);\n\n if (s > e) {\n throw new ChroneraError(\n \"CHRONERA_OUT_OF_RANGE\",\n \"Start date must not be after end date.\",\n );\n }\n\n switch (inclusivity) {\n case \"[]\":\n return target >= s && target <= e;\n case \"[)\":\n return target >= s && target < e;\n case \"(]\":\n return target > s && target <= e;\n case \"()\":\n return target > s && target < e;\n default:\n throw new ChroneraError(\n \"CHRONERA_INVALID_DATE\",\n `Invalid inclusivity: \"${String(inclusivity)}\". Expected \"[]\", \"[)\", \"(]\", or \"()\".`,\n );\n }\n}\n\n/**\n * Returns true if date represents today in the specified timezone (or the host environment's timezone).\n */\nexport function isToday(\n date: DateOrCalendarDate,\n timeZone?: TimeZoneId,\n): boolean {\n const tz =\n timeZone ??\n (typeof Intl !== \"undefined\"\n ? Intl.DateTimeFormat().resolvedOptions().timeZone\n : \"UTC\") ??\n \"UTC\";\n\n const nowInstant: Instant = {\n kind: \"instant\",\n epochMilliseconds: Date.now(),\n };\n\n const zoned = projectInstantToZonedFields(nowInstant, tz);\n const todayAbsDay = absoluteDayFromGregorianFields(\n zoned.year,\n zoned.month,\n zoned.day,\n );\n return getAbsoluteDay(date) === todayAbsDay;\n}\n\n// ---------------------------------------------------------------------------\n// Date Arithmetic Shortcuts\n// ---------------------------------------------------------------------------\n\n/**\n * Adds days to a LocalDate or CalendarDate.\n * Operates on astronomical timeline days, ensuring 100% precision across all calendars.\n */\nexport function addDays<T extends DateOrCalendarDate>(\n date: T,\n amount: number,\n overflow: \"constrain\" | \"reject\" = \"reject\",\n): T {\n if (date.kind === \"local-date\") {\n const currentAbs = absoluteDayFromGregorianFields(\n date.year,\n date.month,\n date.day,\n );\n const newAbs = currentAbs + amount;\n const fields = gregorianFieldsFromAbsoluteDay(newAbs);\n return {\n kind: \"local-date\",\n year: fields.year,\n month: fields.month,\n day: fields.day,\n } as T;\n }\n\n const adapter = defaultCalendarRegistry.getAdapter(date.calendar);\n if (adapter.arithmetic) {\n return adapter.arithmetic.add(date, { days: amount }, overflow) as T;\n }\n\n if (adapter.converter) {\n const currentAbs = adapter.converter.toAbsoluteDay(date);\n const newAbs = currentAbs + amount;\n return adapter.converter.fromAbsoluteDay(newAbs) as T;\n }\n\n throw new ChroneraError(\n \"CHRONERA_UNSUPPORTED_OPERATION\",\n `Calendar \"${date.calendar}\" does not support date arithmetic or conversion.`,\n );\n}\n\n/**\n * Subtracts days from a LocalDate or CalendarDate.\n */\nexport function subtractDays<T extends DateOrCalendarDate>(\n date: T,\n amount: number,\n overflow: \"constrain\" | \"reject\" = \"reject\",\n): T {\n return addDays(date, -amount, overflow);\n}\n\n/**\n * Adds months to a LocalDate or CalendarDate.\n * Handles month-end clamping according to overflow parameter (\"constrain\" or \"reject\").\n */\nexport function addMonths<T extends DateOrCalendarDate>(\n date: T,\n amount: number,\n overflow: \"constrain\" | \"reject\" = \"reject\",\n): T {\n if (date.kind === \"local-date\") {\n const currentMonth = date.month;\n const totalMonths = date.year * 12 + (currentMonth - 1) + amount;\n const year = Math.floor(totalMonths / 12);\n const month = (((totalMonths % 12) + 12) % 12) + 1;\n\n const maxDays = daysInGregorianMonth(year, month);\n let day = date.day;\n if (day > maxDays) {\n if (overflow === \"reject\") {\n throw new ChroneraError(\n \"CHRONERA_OUT_OF_RANGE\",\n `Day ${day} exceeds maximum days ${maxDays} for month ${month} in year ${year}.`,\n );\n }\n day = maxDays;\n }\n return {\n kind: \"local-date\",\n year,\n month,\n day,\n } as T;\n }\n\n const adapter = defaultCalendarRegistry.getAdapter(date.calendar);\n if (adapter.arithmetic) {\n return adapter.arithmetic.add(date, { months: amount }, overflow) as T;\n }\n\n const currentMonth =\n date.month ?? Number.parseInt(date.monthCode.slice(1), 10);\n const totalMonths = date.year * 12 + (currentMonth - 1) + amount;\n const year = Math.floor(totalMonths / 12);\n const month = (((totalMonths % 12) + 12) % 12) + 1;\n const monthCode = `M${String(month).padStart(2, \"0\")}` as MonthCode;\n\n const maxDays = adapter.validator.daysInMonth(year, monthCode);\n let day = date.day;\n if (day > maxDays) {\n if (overflow === \"reject\") {\n throw new ChroneraError(\n \"CHRONERA_OUT_OF_RANGE\",\n `Day ${day} exceeds maximum days ${maxDays} for month ${monthCode} in year ${year}.`,\n );\n }\n day = maxDays;\n }\n\n if (adapter.converter) {\n const candidate: CalendarDate = {\n kind: \"calendar-date\",\n calendar: date.calendar,\n year,\n monthCode,\n month,\n day,\n };\n const absDay = adapter.converter.toAbsoluteDay(candidate);\n return adapter.converter.fromAbsoluteDay(absDay) as T;\n }\n\n return {\n ...date,\n year,\n monthCode,\n month,\n day,\n } as T;\n}\n\n/**\n * Subtracts months from a LocalDate or CalendarDate.\n */\nexport function subtractMonths<T extends DateOrCalendarDate>(\n date: T,\n amount: number,\n overflow: \"constrain\" | \"reject\" = \"reject\",\n): T {\n return addMonths(date, -amount, overflow);\n}\n\n/**\n * Adds years to a LocalDate or CalendarDate.\n * Handles leap year constraints according to overflow parameter (\"constrain\" or \"reject\").\n */\nexport function addYears<T extends DateOrCalendarDate>(\n date: T,\n amount: number,\n overflow: \"constrain\" | \"reject\" = \"reject\",\n): T {\n if (date.kind === \"local-date\") {\n const targetYear = date.year + amount;\n const maxDays = daysInGregorianMonth(targetYear, date.month);\n let day = date.day;\n if (day > maxDays) {\n if (overflow === \"reject\") {\n throw new ChroneraError(\n \"CHRONERA_OUT_OF_RANGE\",\n `Day ${day} exceeds maximum days ${maxDays} for month ${date.month} in year ${targetYear}.`,\n );\n }\n day = maxDays;\n }\n return {\n kind: \"local-date\",\n year: targetYear,\n month: date.month,\n day,\n } as T;\n }\n\n const adapter = defaultCalendarRegistry.getAdapter(date.calendar);\n if (adapter.arithmetic) {\n return adapter.arithmetic.add(date, { years: amount }, overflow) as T;\n }\n\n const targetYear = date.year + amount;\n const month = date.month ?? Number.parseInt(date.monthCode.slice(1), 10);\n const maxDays = adapter.validator.daysInMonth(targetYear, date.monthCode);\n\n let day = date.day;\n if (day > maxDays) {\n if (overflow === \"reject\") {\n throw new ChroneraError(\n \"CHRONERA_OUT_OF_RANGE\",\n `Day ${day} exceeds maximum days ${maxDays} for month ${date.monthCode} in year ${targetYear}.`,\n );\n }\n day = maxDays;\n }\n\n if (adapter.converter) {\n const candidate: CalendarDate = {\n kind: \"calendar-date\",\n calendar: date.calendar,\n year: targetYear,\n monthCode: date.monthCode,\n month,\n day,\n };\n const absDay = adapter.converter.toAbsoluteDay(candidate);\n return adapter.converter.fromAbsoluteDay(absDay) as T;\n }\n\n return {\n ...date,\n year: targetYear,\n day,\n eraYear: date.eraYear !== undefined ? date.eraYear + amount : undefined,\n } as T;\n}\n\n/**\n * Subtracts years from a LocalDate or CalendarDate.\n */\nexport function subtractYears<T extends DateOrCalendarDate>(\n date: T,\n amount: number,\n overflow: \"constrain\" | \"reject\" = \"reject\",\n): T {\n return addYears(date, -amount, overflow);\n}\n\n/**\n * Returns the signed difference in days between two dates (left - right).\n * Works across different calendars.\n */\nexport function diffInDays(\n left: DateOrCalendarDate,\n right: DateOrCalendarDate,\n): number {\n return getAbsoluteDay(left) - getAbsoluteDay(right);\n}\n\n// ---------------------------------------------------------------------------\n// Date Boundary Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Returns the start of the month (Day 1) for a LocalDate or CalendarDate.\n */\nexport function startOfMonth<T extends DateOrCalendarDate>(date: T): T {\n if (date.kind === \"local-date\") {\n return {\n kind: \"local-date\",\n year: date.year,\n month: date.month,\n day: 1,\n } as T;\n }\n\n const adapter = defaultCalendarRegistry.getAdapter(date.calendar);\n if (adapter.converter) {\n const month = date.month ?? Number.parseInt(date.monthCode.slice(1), 10);\n const candidate: CalendarDate = {\n kind: \"calendar-date\",\n calendar: date.calendar,\n year: date.year,\n monthCode: date.monthCode,\n month,\n day: 1,\n };\n const absDay = adapter.converter.toAbsoluteDay(candidate);\n return adapter.converter.fromAbsoluteDay(absDay) as T;\n }\n\n return {\n ...date,\n day: 1,\n } as T;\n}\n\n/**\n * Returns the end of the month (last day) for a LocalDate or CalendarDate.\n * Properly accounts for leap years in any calendar.\n */\nexport function endOfMonth<T extends DateOrCalendarDate>(date: T): T {\n if (date.kind === \"local-date\") {\n const maxDay = daysInGregorianMonth(date.year, date.month);\n return {\n kind: \"local-date\",\n year: date.year,\n month: date.month,\n day: maxDay,\n } as T;\n }\n\n const adapter = defaultCalendarRegistry.getAdapter(date.calendar);\n const maxDay = adapter.validator.daysInMonth(date.year, date.monthCode);\n\n if (adapter.converter) {\n const month = date.month ?? Number.parseInt(date.monthCode.slice(1), 10);\n const candidate: CalendarDate = {\n kind: \"calendar-date\",\n calendar: date.calendar,\n year: date.year,\n monthCode: date.monthCode,\n month,\n day: maxDay,\n };\n const absDay = adapter.converter.toAbsoluteDay(candidate);\n return adapter.converter.fromAbsoluteDay(absDay) as T;\n }\n\n return {\n ...date,\n day: maxDay,\n } as T;\n}\n\n/**\n * Returns the start of the year (Month 1, Day 1) for a LocalDate or CalendarDate.\n */\nexport function startOfYear<T extends DateOrCalendarDate>(date: T): T {\n if (date.kind === \"local-date\") {\n return {\n kind: \"local-date\",\n year: date.year,\n month: 1,\n day: 1,\n } as T;\n }\n\n const adapter = defaultCalendarRegistry.getAdapter(date.calendar);\n if (adapter.converter) {\n const candidate: CalendarDate = {\n kind: \"calendar-date\",\n calendar: date.calendar,\n year: date.year,\n monthCode: \"M01\",\n month: 1,\n day: 1,\n };\n const absDay = adapter.converter.toAbsoluteDay(candidate);\n return adapter.converter.fromAbsoluteDay(absDay) as T;\n }\n\n return {\n ...date,\n monthCode: \"M01\" as MonthCode,\n month: 1,\n day: 1,\n } as T;\n}\n\n/**\n * Returns the end of the year (last day of the final month) for a LocalDate or CalendarDate.\n */\nexport function endOfYear<T extends DateOrCalendarDate>(date: T): T {\n if (date.kind === \"local-date\") {\n return {\n kind: \"local-date\",\n year: date.year,\n month: 12,\n day: 31,\n } as T;\n }\n\n const adapter = defaultCalendarRegistry.getAdapter(date.calendar);\n const finalMonthCode: MonthCode = \"M12\";\n const maxDay = adapter.validator.daysInMonth(date.year, finalMonthCode);\n\n if (adapter.converter) {\n const candidate: CalendarDate = {\n kind: \"calendar-date\",\n calendar: date.calendar,\n year: date.year,\n monthCode: finalMonthCode,\n month: 12,\n day: maxDay,\n };\n const absDay = adapter.converter.toAbsoluteDay(candidate);\n return adapter.converter.fromAbsoluteDay(absDay) as T;\n }\n\n return {\n ...date,\n monthCode: finalMonthCode,\n month: 12,\n day: maxDay,\n } as T;\n}\n"]}
@@ -51,6 +51,8 @@ export interface ZonedDateTime {
51
51
  readonly calendar: CalendarId;
52
52
  }
53
53
  export type FormatDateInput = LocalDate | CalendarDate | Instant | Date;
54
+ export type DateOrCalendarDate = LocalDate | CalendarDate;
55
+ export type IntervalInclusivity = "()" | "[]" | "[)" | "(]";
54
56
  export interface Duration {
55
57
  readonly years?: number;
56
58
  readonly months?: number;
@@ -1 +1 @@
1
- {"version":3,"file":"public-types.js","sourceRoot":"","sources":["../src/public-types.ts"],"names":[],"mappings":"","sourcesContent":["import type { DayOfYearFields } from \"./core/day-of-year.js\";\nimport type {\n FiscalFields,\n FiscalOptions,\n QuarterNumber,\n} from \"./core/fiscal.js\";\nimport type { ChroneraErrorCode } from \"./errors/error-codes.js\";\nimport type { PresetName } from \"./format/presets/types.js\";\nimport type { Rfc2822Options } from \"./format/rfc2822.js\";\n\nexport type {\n ChroneraErrorCode,\n DayOfYearFields,\n FiscalFields,\n FiscalOptions,\n PresetName,\n QuarterNumber,\n Rfc2822Options,\n};\n\nexport type BuiltInCalendarId =\n | \"iso8601\"\n | \"gregory\"\n | \"buddhist\"\n | \"islamic\"\n | \"islamic-civil\"\n | \"islamic-tbla\"\n | \"islamic-umalqura\"\n | \"persian\"\n | \"hebrew\"\n | \"japanese\"\n | \"roc\"\n | \"indian\"\n | \"coptic\"\n | \"ethiopic\"\n | \"chinese\"\n | \"dangi\";\n\ntype ExtensibleIdentifier = string & Record<never, never>;\n\nexport type CalendarId = BuiltInCalendarId | ExtensibleIdentifier;\n\nexport type LocaleId = string;\nexport type TimeZoneId = string;\nexport type NumberingSystemId = string;\nexport type EraId = string;\nexport type MonthCode = `M${string}`;\n\nexport interface Instant {\n readonly kind: \"instant\";\n readonly epochMilliseconds: number;\n}\n\nexport interface LocalDate {\n readonly kind: \"local-date\";\n readonly year: number;\n readonly month: number;\n readonly day: number;\n}\n\nexport interface LocalTime {\n readonly kind: \"local-time\";\n readonly hour: number;\n readonly minute: number;\n readonly second: number;\n readonly millisecond: number;\n}\n\nexport interface LocalDateTime {\n readonly kind: \"local-date-time\";\n readonly date: LocalDate;\n readonly time: LocalTime;\n}\n\nexport interface CalendarDate {\n readonly kind: \"calendar-date\";\n readonly calendar: CalendarId;\n readonly era?: EraId;\n readonly eraYear?: number;\n readonly year: number;\n readonly monthCode: MonthCode;\n readonly month?: number;\n readonly day: number;\n}\n\nexport interface ZonedDateTime {\n readonly kind: \"zoned-date-time\";\n readonly instant: Instant;\n readonly timeZone: TimeZoneId;\n readonly calendar: CalendarId;\n}\n\nexport type FormatDateInput = LocalDate | CalendarDate | Instant | Date;\n\nexport interface Duration {\n readonly years?: number;\n readonly months?: number;\n readonly weeks?: number;\n readonly days?: number;\n readonly hours?: number;\n readonly minutes?: number;\n readonly seconds?: number;\n readonly milliseconds?: number;\n}\n\nexport interface DateRange<TDate> {\n readonly start: TDate;\n readonly end: TDate;\n readonly startInclusive: boolean;\n readonly endInclusive: boolean;\n}\n\nexport interface CalendarConversionMetadata {\n readonly requestedCalendar: CalendarId;\n readonly resolvedCalendar: CalendarId;\n readonly engine: \"chronera\" | \"runtime-intl\" | \"custom\";\n readonly algorithm: string;\n readonly deterministic: boolean;\n readonly dataVersion?: string;\n readonly validFrom?: LocalDate;\n readonly validTo?: LocalDate;\n}\n\nexport interface CalendarConversionResult {\n readonly value: CalendarDate;\n readonly metadata: CalendarConversionMetadata;\n}\n\nexport interface ChroneraIssue {\n readonly code: ChroneraErrorCode;\n readonly message: string;\n readonly path?: readonly (string | number)[];\n}\n\nexport type SafeParseResult<T> =\n | {\n readonly success: true;\n readonly value: T;\n }\n | {\n readonly success: false;\n readonly error: ChroneraIssue;\n };\n\nexport type Comparison = -1 | 0 | 1;\n\nexport interface CalendarPlugin {\n readonly id: CalendarId;\n readonly algorithm: string;\n readonly deterministic: boolean;\n readonly validFrom: LocalDate;\n readonly validTo: LocalDate;\n toIsoDate(date: CalendarDate): LocalDate;\n fromIsoDate(date: LocalDate): CalendarDate;\n validate(date: CalendarDate): readonly ChroneraIssue[];\n}\n\nexport interface ChroneraConfig {\n readonly locale?: LocaleId;\n readonly calendar?: CalendarId;\n readonly numberingSystem?: NumberingSystemId;\n readonly timeZone?: TimeZoneId;\n readonly calendars?: readonly CalendarPlugin[];\n readonly formatterCacheSize?: number;\n}\n\nexport interface ResolvedChroneraOptions {\n readonly locale: LocaleId;\n readonly calendar: CalendarId;\n readonly numberingSystem?: NumberingSystemId;\n readonly timeZone: TimeZoneId;\n readonly formatterCacheSize: number;\n}\n\nexport interface FormatDateBaseOptions {\n readonly locale?: LocaleId;\n readonly calendar?: CalendarId;\n readonly numberingSystem?: NumberingSystemId;\n readonly timeZone?: TimeZoneId;\n readonly fallback?: \"error\";\n}\n\nexport type FormatDateOptions = FormatDateBaseOptions &\n (\n | {\n readonly style?: \"numeric\" | \"short\" | \"medium\" | \"long\" | \"full\";\n readonly preset?: never;\n }\n | {\n readonly style?: never;\n readonly preset: PresetName;\n }\n );\n\nexport interface FormatTimeOptions {\n readonly locale?: LocaleId;\n readonly numberingSystem?: NumberingSystemId;\n readonly timeZone?: TimeZoneId;\n readonly style?: \"short\" | \"medium\" | \"long\" | \"full\";\n readonly hourCycle?: \"h11\" | \"h12\" | \"h23\" | \"h24\";\n}\n\nexport interface FormatDateTimeOptions extends FormatDateBaseOptions {\n readonly dateStyle?: \"short\" | \"medium\" | \"long\" | \"full\";\n readonly timeStyle?: \"short\" | \"medium\" | \"long\" | \"full\";\n readonly hourCycle?: \"h11\" | \"h12\" | \"h23\" | \"h24\";\n}\n\nexport type FormatDateRangeOptions = FormatDateOptions & {\n readonly collapse?: \"auto\" | \"none\";\n};\n\nexport interface FormatRelativeOptions {\n readonly relativeTo: Instant | LocalDate;\n readonly locale?: LocaleId;\n readonly numeric?: \"always\" | \"auto\";\n readonly unit?:\n \"second\" | \"minute\" | \"hour\" | \"day\" | \"week\" | \"month\" | \"year\";\n readonly timeZone?: TimeZoneId;\n}\n\nexport interface PatternFormatOptions {\n readonly locale?: LocaleId;\n readonly calendar?: CalendarId;\n readonly numberingSystem?: NumberingSystemId;\n readonly timeZone?: TimeZoneId;\n}\n\nexport interface ParseLocalDateOptions {\n readonly pattern?: string;\n readonly locale?: LocaleId;\n readonly calendar?: \"gregory\" | \"iso8601\";\n readonly numberingSystem?: NumberingSystemId;\n}\n\nexport interface ParseInstantOptions {\n readonly excessFractionalSeconds?: \"reject\" | \"truncate\" | \"round\";\n}\n\nexport interface ConvertCalendarOptions {\n readonly fallback?: \"error\";\n}\n\nexport interface CalendarCapabilities {\n readonly calendar: CalendarId;\n readonly maturity:\n \"stable\" | \"experimental\" | \"runtime-dependent\" | \"planned\" | \"unsupported\";\n readonly canFormat: boolean;\n readonly canParse: boolean;\n readonly canConvertFromAbsoluteDate: boolean;\n readonly canConvertToAbsoluteDate: boolean;\n readonly canValidate: boolean;\n readonly canAddYears: boolean;\n readonly canAddMonths: boolean;\n readonly deterministic: boolean;\n readonly algorithm?: string;\n readonly dataVersion?: string;\n readonly validFrom?: LocalDate;\n readonly validTo?: LocalDate;\n}\n\nexport interface RuntimeCapabilities {\n readonly hasDateTimeFormat: boolean;\n readonly hasFormatToParts: boolean;\n readonly hasFormatRange: boolean;\n readonly hasRelativeTimeFormat: boolean;\n readonly hasLocale: boolean;\n readonly hasSupportedValuesOf: boolean;\n readonly hasTemporal: boolean;\n readonly calendars: Readonly<Record<string, boolean>>;\n readonly timeZones: Readonly<Record<string, boolean>>;\n}\n\nexport interface ChroneraInstance {\n formatDate(\n input: FormatDateInput,\n options?: Readonly<FormatDateOptions>,\n ): string;\n parseLocalDate(\n input: string,\n options?: Readonly<ParseLocalDateOptions>,\n ): LocalDate;\n convertCalendarDate(\n source: CalendarDate,\n targetCalendar: CalendarId,\n options?: Readonly<ConvertCalendarOptions>,\n ): CalendarConversionResult;\n resolvedOptions(): ResolvedChroneraOptions;\n}\n\nexport type { IsoWeekFields } from \"./core/iso-week.js\";\n"]}
1
+ {"version":3,"file":"public-types.js","sourceRoot":"","sources":["../src/public-types.ts"],"names":[],"mappings":"","sourcesContent":["import type { DayOfYearFields } from \"./core/day-of-year.js\";\nimport type {\n FiscalFields,\n FiscalOptions,\n QuarterNumber,\n} from \"./core/fiscal.js\";\nimport type { ChroneraErrorCode } from \"./errors/error-codes.js\";\nimport type { PresetName } from \"./format/presets/types.js\";\nimport type { Rfc2822Options } from \"./format/rfc2822.js\";\n\nexport type {\n ChroneraErrorCode,\n DayOfYearFields,\n FiscalFields,\n FiscalOptions,\n PresetName,\n QuarterNumber,\n Rfc2822Options,\n};\n\nexport type BuiltInCalendarId =\n | \"iso8601\"\n | \"gregory\"\n | \"buddhist\"\n | \"islamic\"\n | \"islamic-civil\"\n | \"islamic-tbla\"\n | \"islamic-umalqura\"\n | \"persian\"\n | \"hebrew\"\n | \"japanese\"\n | \"roc\"\n | \"indian\"\n | \"coptic\"\n | \"ethiopic\"\n | \"chinese\"\n | \"dangi\";\n\ntype ExtensibleIdentifier = string & Record<never, never>;\n\nexport type CalendarId = BuiltInCalendarId | ExtensibleIdentifier;\n\nexport type LocaleId = string;\nexport type TimeZoneId = string;\nexport type NumberingSystemId = string;\nexport type EraId = string;\nexport type MonthCode = `M${string}`;\n\nexport interface Instant {\n readonly kind: \"instant\";\n readonly epochMilliseconds: number;\n}\n\nexport interface LocalDate {\n readonly kind: \"local-date\";\n readonly year: number;\n readonly month: number;\n readonly day: number;\n}\n\nexport interface LocalTime {\n readonly kind: \"local-time\";\n readonly hour: number;\n readonly minute: number;\n readonly second: number;\n readonly millisecond: number;\n}\n\nexport interface LocalDateTime {\n readonly kind: \"local-date-time\";\n readonly date: LocalDate;\n readonly time: LocalTime;\n}\n\nexport interface CalendarDate {\n readonly kind: \"calendar-date\";\n readonly calendar: CalendarId;\n readonly era?: EraId;\n readonly eraYear?: number;\n readonly year: number;\n readonly monthCode: MonthCode;\n readonly month?: number;\n readonly day: number;\n}\n\nexport interface ZonedDateTime {\n readonly kind: \"zoned-date-time\";\n readonly instant: Instant;\n readonly timeZone: TimeZoneId;\n readonly calendar: CalendarId;\n}\n\nexport type FormatDateInput = LocalDate | CalendarDate | Instant | Date;\nexport type DateOrCalendarDate = LocalDate | CalendarDate;\nexport type IntervalInclusivity = \"()\" | \"[]\" | \"[)\" | \"(]\";\n\nexport interface Duration {\n readonly years?: number;\n readonly months?: number;\n readonly weeks?: number;\n readonly days?: number;\n readonly hours?: number;\n readonly minutes?: number;\n readonly seconds?: number;\n readonly milliseconds?: number;\n}\n\nexport interface DateRange<TDate> {\n readonly start: TDate;\n readonly end: TDate;\n readonly startInclusive: boolean;\n readonly endInclusive: boolean;\n}\n\nexport interface CalendarConversionMetadata {\n readonly requestedCalendar: CalendarId;\n readonly resolvedCalendar: CalendarId;\n readonly engine: \"chronera\" | \"runtime-intl\" | \"custom\";\n readonly algorithm: string;\n readonly deterministic: boolean;\n readonly dataVersion?: string;\n readonly validFrom?: LocalDate;\n readonly validTo?: LocalDate;\n}\n\nexport interface CalendarConversionResult {\n readonly value: CalendarDate;\n readonly metadata: CalendarConversionMetadata;\n}\n\nexport interface ChroneraIssue {\n readonly code: ChroneraErrorCode;\n readonly message: string;\n readonly path?: readonly (string | number)[];\n}\n\nexport type SafeParseResult<T> =\n | {\n readonly success: true;\n readonly value: T;\n }\n | {\n readonly success: false;\n readonly error: ChroneraIssue;\n };\n\nexport type Comparison = -1 | 0 | 1;\n\nexport interface CalendarPlugin {\n readonly id: CalendarId;\n readonly algorithm: string;\n readonly deterministic: boolean;\n readonly validFrom: LocalDate;\n readonly validTo: LocalDate;\n toIsoDate(date: CalendarDate): LocalDate;\n fromIsoDate(date: LocalDate): CalendarDate;\n validate(date: CalendarDate): readonly ChroneraIssue[];\n}\n\nexport interface ChroneraConfig {\n readonly locale?: LocaleId;\n readonly calendar?: CalendarId;\n readonly numberingSystem?: NumberingSystemId;\n readonly timeZone?: TimeZoneId;\n readonly calendars?: readonly CalendarPlugin[];\n readonly formatterCacheSize?: number;\n}\n\nexport interface ResolvedChroneraOptions {\n readonly locale: LocaleId;\n readonly calendar: CalendarId;\n readonly numberingSystem?: NumberingSystemId;\n readonly timeZone: TimeZoneId;\n readonly formatterCacheSize: number;\n}\n\nexport interface FormatDateBaseOptions {\n readonly locale?: LocaleId;\n readonly calendar?: CalendarId;\n readonly numberingSystem?: NumberingSystemId;\n readonly timeZone?: TimeZoneId;\n readonly fallback?: \"error\";\n}\n\nexport type FormatDateOptions = FormatDateBaseOptions &\n (\n | {\n readonly style?: \"numeric\" | \"short\" | \"medium\" | \"long\" | \"full\";\n readonly preset?: never;\n }\n | {\n readonly style?: never;\n readonly preset: PresetName;\n }\n );\n\nexport interface FormatTimeOptions {\n readonly locale?: LocaleId;\n readonly numberingSystem?: NumberingSystemId;\n readonly timeZone?: TimeZoneId;\n readonly style?: \"short\" | \"medium\" | \"long\" | \"full\";\n readonly hourCycle?: \"h11\" | \"h12\" | \"h23\" | \"h24\";\n}\n\nexport interface FormatDateTimeOptions extends FormatDateBaseOptions {\n readonly dateStyle?: \"short\" | \"medium\" | \"long\" | \"full\";\n readonly timeStyle?: \"short\" | \"medium\" | \"long\" | \"full\";\n readonly hourCycle?: \"h11\" | \"h12\" | \"h23\" | \"h24\";\n}\n\nexport type FormatDateRangeOptions = FormatDateOptions & {\n readonly collapse?: \"auto\" | \"none\";\n};\n\nexport interface FormatRelativeOptions {\n readonly relativeTo: Instant | LocalDate;\n readonly locale?: LocaleId;\n readonly numeric?: \"always\" | \"auto\";\n readonly unit?:\n \"second\" | \"minute\" | \"hour\" | \"day\" | \"week\" | \"month\" | \"year\";\n readonly timeZone?: TimeZoneId;\n}\n\nexport interface PatternFormatOptions {\n readonly locale?: LocaleId;\n readonly calendar?: CalendarId;\n readonly numberingSystem?: NumberingSystemId;\n readonly timeZone?: TimeZoneId;\n}\n\nexport interface ParseLocalDateOptions {\n readonly pattern?: string;\n readonly locale?: LocaleId;\n readonly calendar?: \"gregory\" | \"iso8601\";\n readonly numberingSystem?: NumberingSystemId;\n}\n\nexport interface ParseInstantOptions {\n readonly excessFractionalSeconds?: \"reject\" | \"truncate\" | \"round\";\n}\n\nexport interface ConvertCalendarOptions {\n readonly fallback?: \"error\";\n}\n\nexport interface CalendarCapabilities {\n readonly calendar: CalendarId;\n readonly maturity:\n \"stable\" | \"experimental\" | \"runtime-dependent\" | \"planned\" | \"unsupported\";\n readonly canFormat: boolean;\n readonly canParse: boolean;\n readonly canConvertFromAbsoluteDate: boolean;\n readonly canConvertToAbsoluteDate: boolean;\n readonly canValidate: boolean;\n readonly canAddYears: boolean;\n readonly canAddMonths: boolean;\n readonly deterministic: boolean;\n readonly algorithm?: string;\n readonly dataVersion?: string;\n readonly validFrom?: LocalDate;\n readonly validTo?: LocalDate;\n}\n\nexport interface RuntimeCapabilities {\n readonly hasDateTimeFormat: boolean;\n readonly hasFormatToParts: boolean;\n readonly hasFormatRange: boolean;\n readonly hasRelativeTimeFormat: boolean;\n readonly hasLocale: boolean;\n readonly hasSupportedValuesOf: boolean;\n readonly hasTemporal: boolean;\n readonly calendars: Readonly<Record<string, boolean>>;\n readonly timeZones: Readonly<Record<string, boolean>>;\n}\n\nexport interface ChroneraInstance {\n formatDate(\n input: FormatDateInput,\n options?: Readonly<FormatDateOptions>,\n ): string;\n parseLocalDate(\n input: string,\n options?: Readonly<ParseLocalDateOptions>,\n ): LocalDate;\n convertCalendarDate(\n source: CalendarDate,\n targetCalendar: CalendarId,\n options?: Readonly<ConvertCalendarOptions>,\n ): CalendarConversionResult;\n resolvedOptions(): ResolvedChroneraOptions;\n}\n\nexport type { IsoWeekFields } from \"./core/iso-week.js\";\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intech-software/chronera",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "A universal, type-safe date, time, calendar, era, locale, and timezone toolkit for JavaScript and TypeScript.",
5
5
  "keywords": [
6
6
  "date",
@@ -150,6 +150,7 @@
150
150
  "pack:artifact": "pnpm build && pnpm pack --pack-destination artifacts",
151
151
  "pack:check": "node scripts/check-package.mjs && node scripts/verify-consumers.mjs",
152
152
  "verify:consumers": "node scripts/verify-consumers.mjs",
153
- "release:check": "pnpm check && pnpm test:types && pnpm data:check"
153
+ "release:check": "pnpm check && pnpm test:types && pnpm data:check",
154
+ "release:automated": "node --import tsx scripts/automate-release.ts"
154
155
  }
155
156
  }