@item-enonic-types/lib-time 1.6.1 → 2.0.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 CHANGED
@@ -1,14 +1,17 @@
1
1
  # Time library for Enonic XP
2
2
 
3
- This library enables the usage of classes from the [`java.time`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/package-summary.html) package from Enonic XP application code.
3
+ This library enables the usage of classes from the [`java.time`](https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/time/package-summary.html) package from Enonic XP application code.
4
4
  Other JavaScript-based time libraries like _Moment.js_ or _date-fns_ will negatively impact your bundle size and build time. This library is only a **thin TypeScript-wrapper** around the excellent core `java.time` library already present in your system!
5
5
 
6
6
  [![](https://repo.itemtest.no/api/badge/latest/releases/no/item/lib-xp-time)](https://repo.itemtest.no/#/releases/no/item/lib-xp-time)
7
+ ![Enonic XP8 badge](https://market.enonic.com/badges/xp8.svg)
7
8
 
8
9
  <img src="https://github.com/ItemConsulting/lib-xp-time/raw/main/docs/icon.svg?sanitize=true" width="150">
9
10
 
10
11
  ## Installation
11
12
 
13
+ Version 2 of this library requires Enonic XP 8, and is built against XP 8.0.0. Use version 1.x for Enonic XP 7.
14
+
12
15
  To install this library you need to add a new dependency to your app's build.gradle file.
13
16
 
14
17
  ### Gradle
@@ -19,7 +22,7 @@ repositories {
19
22
  }
20
23
 
21
24
  dependencies {
22
- include "no.item:lib-xp-time:1.5.0"
25
+ include "no.item:lib-xp-time:2.0.0"
23
26
  }
24
27
  ```
25
28
 
@@ -72,31 +75,112 @@ const time = fiftyMinutesAgo.toLocalTime();
72
75
  // time = "11:25:30"
73
76
  ```
74
77
 
75
- *This library also exposes a utility function `formatDate()` to simply format a date:*
78
+ ### Amounts of time with `Duration`, `Period` and `ChronoUnit`
79
+
80
+ There are two kinds of amounts of time, and they behave differently:
81
+
82
+ - A `Duration` is an exact amount of time in hours, minutes and seconds. A day is always 24 hours. Use it for what a
83
+ stopwatch would measure, such as the length of a video or how long ago something was published.
84
+ - A `Period` is an amount of years, months and days that follows the calendar. Use it for what a calendar would
85
+ measure, such as an age or "valid for 6 months".
86
+
87
+ ```typescript
88
+ import { Duration, Instant, LocalDate, Period } from "/lib/time";
89
+
90
+ const published = Instant.parse("2023-02-08T10:15:30Z");
91
+ const now = Instant.parse("2023-02-08T11:45:30Z");
92
+ const sincePublished = Duration.between(published, now);
93
+ // sincePublished.toMinutes() = 90
94
+ // sincePublished.toString() = "PT1H30M"
95
+
96
+ const age = Period.between(LocalDate.parse("1990-05-17"), LocalDate.parse("2023-02-08"));
97
+ // age.getYears() = 32
98
+ ```
99
+
100
+ Both can be added to and subtracted from the date-time classes with `plus()` and `minus()`, and both can be parsed
101
+ from ISO-8601 text such as `"PT1H30M"` and `"P1Y2M3D"`. A `Duration` can only be added to something with a time of
102
+ day, and a `Period` only to something with a date.
103
+
104
+ ```typescript
105
+ import { Duration, LocalDate, LocalDateTime, Period } from "/lib/time";
106
+
107
+ const expires = LocalDate.parse("2023-01-31").plus(Period.ofMonths(1));
108
+ // expires = "2023-02-28"
109
+
110
+ const ends = LocalDateTime.parse("2023-02-08T23:15:30").plus(Duration.ofMinutes(90));
111
+ // ends = "2023-02-09T00:45:30"
112
+ ```
113
+
114
+ The difference between the two shows when the clocks change. Summer time in Oslo started on 26 March 2023, so that
115
+ day was only 23 hours long:
116
+
117
+ ```typescript
118
+ import { Duration, Period, ZonedDateTime } from "/lib/time";
119
+
120
+ const dayBefore = ZonedDateTime.parse("2023-03-25T12:00:00+01:00[Europe/Oslo]");
121
+
122
+ dayBefore.plus(Period.ofDays(1)); // "2023-03-26T12:00+02:00[Europe/Oslo]", the same time the next day
123
+ dayBefore.plus(Duration.ofDays(1)); // "2023-03-26T13:00+02:00[Europe/Oslo]", exactly 24 hours later
124
+ ```
125
+
126
+ `ChronoUnit` is the list of units, from `NANOS` to `MILLENNIA`. It counts whole units between two dates or times, and
127
+ is used with `plus()`, `minus()`, `until()` and `truncatedTo()`.
128
+
129
+ ```typescript
130
+ import { ChronoUnit, LocalDate, LocalDateTime } from "/lib/time";
131
+
132
+ const daysUntilEvent = ChronoUnit.DAYS.between(LocalDate.parse("2023-02-08"), LocalDate.parse("2023-03-01"));
133
+ // daysUntilEvent = 21
134
+
135
+ const inThreeWeeks = LocalDate.parse("2023-02-08").plus(3, ChronoUnit.WEEKS);
136
+ // inThreeWeeks = "2023-03-01"
137
+
138
+ const startOfHour = LocalDateTime.parse("2023-02-08T10:15:30").truncatedTo(ChronoUnit.HOURS);
139
+ // startOfHour = "2023-02-08T10:00"
140
+ ```
141
+
142
+ ### Formatting dates with `formatDate()`
143
+
144
+ The utility function `formatDate()` formats a date in one call. It takes a
145
+ [pattern](https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/time/format/DateTimeFormatter.html#patterns),
146
+ and optionally a `locale` and a `timezoneId`.
76
147
 
77
148
  ```typescript
78
149
  import { formatDate } from "/lib/time";
79
150
 
80
151
  const today = formatDate({
81
152
  date: "2023-02-21",
82
- pattern: "dd-MM-yyyy",
153
+ pattern: "EEEE d. MMMM yyyy",
83
154
  locale: "no"
84
155
  });
85
- // today = "21-02-2023"
156
+ // today = "tirsdag 21. februar 2023"
86
157
  ```
87
- *Use `formatDate()` with a given timezoneId*
158
+
159
+ *Use `timezoneId` to convert a point in time to a time zone:*
160
+
88
161
  ```typescript
89
162
  import { formatDate } from "/lib/time";
90
163
 
91
- const today = formatDate({
92
- date: "2023-02-21",
93
- pattern: "dd-MM-yyyy",
94
- locale: "no",
164
+ const time = formatDate({
165
+ date: "2023-02-21T12:15:30Z",
166
+ pattern: "dd.MM.yyyy HH:mm",
95
167
  timezoneId: "Europe/Oslo"
96
168
  });
97
- // today = "21-02-2023"
169
+ // time = "21.02.2023 13:15"
98
170
  ```
99
171
 
172
+ The `date` can be a JavaScript `Date` or a string, and `formatDate()` returns `undefined` if it is `undefined`, `null`
173
+ or an empty string.
174
+
175
+ | `date` | Example | Without `timezoneId` | With `timezoneId` |
176
+ |----------------------------------------------------|------------------------------------------|--------------------------------------|----------------------------|
177
+ | `Date` | `new Date()` | Shown in the time zone of the server | Converted to the time zone |
178
+ | Date and time with `Z`, an offset or a zone id | `"2023-02-21T12:15:30+01:00"` | Shown as written | Converted to the time zone |
179
+ | Date and time without an offset | `"2023-02-21T12:15:30"` | Shown as written | Shown as written |
180
+ | Date | `"2023-02-21"` | Shown as written | Shown as written |
181
+
182
+ A `timezoneId` that is not a valid time zone falls back to the time zone of the server.
183
+
100
184
  *Example of using `Locale` in formatting a `LocalDateTime` and get a normalized timestamp :*
101
185
  ```typescript
102
186
  import { LocalDateTime, DateTimeFormatter, Locale } from "/lib/time";
@@ -107,7 +191,7 @@ const time = today.format(formatter);
107
191
  // time = "tirsdag 21. februar 2023 12:15:30"
108
192
  ```
109
193
 
110
- *Example of using hte `LanguageRange` utility to find the preferred locale among the ones supported by the application.*
194
+ *Example of using the `LanguageRange` utility to find the preferred locale among the ones supported by the application.*
111
195
 
112
196
  ```typescript
113
197
  import { LanguageRange, Locale } from "/lib/time";
@@ -127,10 +211,32 @@ export function get(req: Request): Response {
127
211
 
128
212
  ```
129
213
 
130
- ### Constants exposed from `"/lib/time"`
131
- The following classes is exposed/exported from `"/lib/time"`:
214
+ ### Lists and sets from Java
215
+
216
+ Some methods return a Java collection instead of a JavaScript array. They are typed as `JavaList` and `JavaSet`:
217
+
218
+ - A `JavaList`, such as the result of `LanguageRange.parse()` and `Locale.filterTags()`, can be read by index, has a
219
+ `length` and can be looped over with `forEach()`. It also has `size()`, `get()`, `contains()` and `isEmpty()`. Array
220
+ methods such as `map()` and `filter()` are not available on every script engine, so they are left out of the type.
221
+ - A `JavaSet`, such as the result of `ZoneId.getAvailableZoneIds()`, has `size()`, `contains()`, `isEmpty()` and
222
+ `forEach()`. It has no order, so it can not be read by index.
223
+
224
+ ```typescript
225
+ import { ZoneId } from "/lib/time";
226
+
227
+ const isKnownTimeZone = ZoneId.getAvailableZoneIds().contains("Europe/Oslo");
228
+ // isKnownTimeZone = true
229
+ ```
230
+
231
+ ### Exported from `"/lib/time"`
232
+
233
+ The following classes are exported from `"/lib/time"`:
234
+
235
+ * `ChronoUnit`
132
236
  * `DateTimeFormatter`
133
237
  * `DayOfWeek`
238
+ * `Duration`
239
+ * `FormatStyle`
134
240
  * `Instant`
135
241
  * `LanguageRange`
136
242
  * `LocalDate`
@@ -140,21 +246,41 @@ The following classes is exposed/exported from `"/lib/time"`:
140
246
  * `Month`
141
247
  * `OffsetDateTime`
142
248
  * `OffsetTime`
249
+ * `Period`
250
+ * `TextStyle`
143
251
  * `Year`
144
252
  * `ZonedDateTime`
145
253
  * `ZoneId`
146
254
  * `ZoneOffset`
147
255
 
148
- ## Deploying
256
+ Together with the function `formatDate()`, and the types `JavaList`, `JavaSet`, `MonthNumber`,
257
+ `Temporal`, `TemporalAmount` and `TimeTemporal`.
258
+
259
+ ## Development
149
260
 
150
261
  ### Building
151
262
 
263
+ Building requires Java 25, which is what Enonic XP 8 compiles against. Node.js is downloaded by Gradle, in the version
264
+ given in *.nvmrc*.
265
+
152
266
  To build the project, run the following command
153
267
 
154
268
  ```bash
155
- enonic project build
269
+ ./gradlew build
156
270
  ```
157
271
 
272
+ This checks the code with Biome and TypeScript, bundles it with tsdown, runs the tests and builds the jar.
273
+ `enonic project build` does the same, when the project is linked to an XP 8 sandbox.
274
+
275
+ ### Testing
276
+
277
+ The tests are JavaScript files in *src/test/resources/tests*. Every file named *\*Test.js* is picked up, and every
278
+ function it exports with a name starting with `test` is run as a test of its own, so there is nothing to register.
279
+
280
+ They run on both of the script engines of XP 8: `./gradlew test` uses Nashorn, and `./gradlew testGraalJS` uses
281
+ GraalJS. The time zone of the tests is set to Europe/Oslo in *build.gradle*, so they give the same result on every
282
+ machine.
283
+
158
284
  ### Deploying locally
159
285
 
160
286
  To deploy to a local sandbox, run the following command
@@ -163,14 +289,12 @@ To deploy to a local sandbox, run the following command
163
289
  enonic project deploy
164
290
  ```
165
291
 
166
- ### Deploy to Maven
292
+ ### Releasing
167
293
 
168
- ```bash
169
- ./gradlew publish -P com.enonic.xp.app.production=true
170
- ```
294
+ Releases are made by GitHub Actions, using [Changesets](https://github.com/changesets/changesets).
171
295
 
172
- ### Deploy to npm
173
-
174
- ```bash
175
- npm publish
176
- ```
296
+ 1. Describe your change by running `npx changeset`, and commit the file it creates together with the change.
297
+ 2. When the change is merged to `main`, a pull request named "Version Packages" is opened or updated. It bumps the
298
+ version and writes the changelog.
299
+ 3. Merging that pull request publishes the types to npm, tags the release on GitHub and publishes the jar to
300
+ [repo.itemtest.no](https://repo.itemtest.no/#/releases/no/item/lib-xp-time).
package/day-of-week.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { TextStyle } from "./format/text-style";
2
- import { Locale } from "./util";
1
+ import type { TextStyle } from "./format/text-style";
2
+ import type { Locale } from "./util";
3
3
  /**
4
4
  * DayOfWeek is an enum representing the 7 days of the week - Monday, Tuesday, Wednesday, Thursday, Friday, Saturday and Sunday.
5
- * @see {@link https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/DayOfWeek.html}
5
+ * @see {@link https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/time/DayOfWeek.html}
6
6
  */
7
7
  export declare const DayOfWeek: DayOfWeekConstructor;
8
8
  export type WeekDayNumber = 1 | 2 | 3 | 4 | 5 | 6 | 7;
package/duration.d.ts ADDED
@@ -0,0 +1,85 @@
1
+ import type { ChronoUnit } from "/lib/time";
2
+ import type { TimeTemporal } from "/lib/time/temporal/temporal";
3
+ /**
4
+ * A time-based amount of time, such as '34.5 seconds'.
5
+ *
6
+ * This class models a quantity or amount of time in terms of seconds and nanoseconds. A day is always exactly 24 hours.
7
+ * Use Period for an amount of time in years, months and days that follows the calendar.
8
+ * @see {@link https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/time/Duration.html}
9
+ */
10
+ export declare const Duration: DurationConstructor;
11
+ export interface DurationConstructor {
12
+ ZERO: Duration;
13
+ between(startInclusive: TimeTemporal, endExclusive: TimeTemporal): Duration;
14
+ of(amount: number, unit: ChronoUnit): Duration;
15
+ ofDays(days: number): Duration;
16
+ ofHours(hours: number): Duration;
17
+ ofMillis(millis: number): Duration;
18
+ ofMinutes(minutes: number): Duration;
19
+ ofNanos(nanos: number): Duration;
20
+ ofSeconds(seconds: number): Duration;
21
+ ofSeconds(seconds: number, nanoAdjustment: number): Duration;
22
+ /**
23
+ * Parses an ISO-8601 duration, such as "PT1H30M" or "P2DT3H".
24
+ */
25
+ parse(text: string): Duration;
26
+ }
27
+ export interface Duration {
28
+ abs(): Duration;
29
+ compareTo(otherDuration: Duration): number;
30
+ dividedBy(divisor: number): Duration;
31
+ /**
32
+ * The number of whole times the other duration fits in this one
33
+ */
34
+ dividedBy(divisor: Duration): number;
35
+ equals(otherDuration: unknown): boolean;
36
+ getNano(): number;
37
+ getSeconds(): number;
38
+ hashCode(): number;
39
+ isNegative(): boolean;
40
+ isPositive(): boolean;
41
+ isZero(): boolean;
42
+ minus(duration: Duration): Duration;
43
+ minus(amountToSubtract: number, unit: ChronoUnit): Duration;
44
+ minusDays(daysToSubtract: number): Duration;
45
+ minusHours(hoursToSubtract: number): Duration;
46
+ minusMillis(millisToSubtract: number): Duration;
47
+ minusMinutes(minutesToSubtract: number): Duration;
48
+ minusNanos(nanosToSubtract: number): Duration;
49
+ minusSeconds(secondsToSubtract: number): Duration;
50
+ multipliedBy(multiplicand: number): Duration;
51
+ negated(): Duration;
52
+ plus(duration: Duration): Duration;
53
+ plus(amountToAdd: number, unit: ChronoUnit): Duration;
54
+ plusDays(daysToAdd: number): Duration;
55
+ plusHours(hoursToAdd: number): Duration;
56
+ plusMillis(millisToAdd: number): Duration;
57
+ plusMinutes(minutesToAdd: number): Duration;
58
+ plusNanos(nanosToAdd: number): Duration;
59
+ plusSeconds(secondsToAdd: number): Duration;
60
+ /**
61
+ * The whole duration in days, where a day is 24 hours
62
+ */
63
+ toDays(): number;
64
+ toDaysPart(): number;
65
+ /**
66
+ * The whole duration in hours. Use toHoursPart() for the hours left after the days are taken out.
67
+ */
68
+ toHours(): number;
69
+ toHoursPart(): number;
70
+ toMillis(): number;
71
+ toMillisPart(): number;
72
+ toMinutes(): number;
73
+ toMinutesPart(): number;
74
+ toNanos(): number;
75
+ toNanosPart(): number;
76
+ toSeconds(): number;
77
+ toSecondsPart(): number;
78
+ /**
79
+ * The ISO-8601 representation, such as "PT1H30M"
80
+ */
81
+ toString(): string;
82
+ truncatedTo(unit: ChronoUnit): Duration;
83
+ withNanos(nanoOfSecond: number): Duration;
84
+ withSeconds(seconds: number): Duration;
85
+ }
@@ -1,11 +1,13 @@
1
- import type { ZoneId, Locale } from "/lib/time";
1
+ import type { Locale, ZoneId } from "/lib/time";
2
2
  import type { FormatStyle } from "/lib/time/format/format-style";
3
+ import type { Temporal } from "/lib/time/temporal/temporal";
3
4
  /**
4
5
  * Formatter for printing and parsing date-time objects.
5
- * @see {@link https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/format/DateTimeFormatter.html}
6
+ * @see {@link https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/time/format/DateTimeFormatter.html}
6
7
  */
7
8
  export declare const DateTimeFormatter: DateTimeFormatterConstructor;
8
9
  export interface DateTimeFormatter {
10
+ format(temporal: Temporal): string;
9
11
  getLocale(): Locale;
10
12
  getZone(): ZoneId;
11
13
  localizedBy(locale: Locale): DateTimeFormatter;
@@ -13,7 +15,6 @@ export interface DateTimeFormatter {
13
15
  withZone(zone: ZoneId): DateTimeFormatter;
14
16
  }
15
17
  export interface DateTimeFormatterConstructor {
16
- new (): DateTimeFormatter;
17
18
  BASIC_ISO_DATE: DateTimeFormatter;
18
19
  ISO_DATE: DateTimeFormatter;
19
20
  ISO_DATE_TIME: DateTimeFormatter;
@@ -21,6 +22,8 @@ export interface DateTimeFormatterConstructor {
21
22
  ISO_LOCAL_DATE: DateTimeFormatter;
22
23
  ISO_LOCAL_DATE_TIME: DateTimeFormatter;
23
24
  ISO_LOCAL_TIME: DateTimeFormatter;
25
+ ISO_OFFSET_DATE: DateTimeFormatter;
26
+ ISO_OFFSET_DATE_TIME: DateTimeFormatter;
24
27
  ISO_OFFSET_TIME: DateTimeFormatter;
25
28
  ISO_ORDINAL_DATE: DateTimeFormatter;
26
29
  ISO_TIME: DateTimeFormatter;
@@ -2,7 +2,7 @@
2
2
  * Enumeration of the style of a localized date, time or date-time formatter.
3
3
  *
4
4
  * These styles are used when obtaining a date-time style from configuration. See DateTimeFormatter and DateTimeFormatterBuilder for usage.
5
- * @see {@link https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/format/FormatStyle.html}
5
+ * @see {@link https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/time/format/FormatStyle.html}
6
6
  */
7
7
  export declare const FormatStyle: FormatStyleConstructor;
8
8
  export interface FormatStyleConstructor {
@@ -6,7 +6,7 @@
6
6
  * The difference between the three sizes is obvious in most languages. For example, in English the 'full' month is 'January', the 'short' month is 'Jan' and the 'narrow' month is 'J'. Note that the narrow size is often not unique. For example, 'January', 'June' and 'July' all have the 'narrow' text 'J'.
7
7
  *
8
8
  * The difference between the 'standard' and 'stand-alone' forms is trickier to describe as there is no difference in English. However, in other languages there is a difference in the word used when the text is used alone, as opposed to in a complete date. For example, the word used for a month when used alone in a date picker is different to the word used for month in association with a day and year in a date.
9
- * @see {@link https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/format/TextStyle.html}
9
+ * @see {@link https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/time/format/TextStyle.html}
10
10
  */
11
11
  export declare const TextStyle: TextStyleConstructor;
12
12
  export interface TextStyleConstructor {
package/index.d.ts CHANGED
@@ -1,22 +1,26 @@
1
1
  export { DayOfWeek } from "/lib/time/day-of-week";
2
- export { LocalDateTime } from "/lib/time/local-date-time";
3
- export { ZonedDateTime } from "/lib/time/zoned-date-time";
4
- export { Locale, LanguageRange } from "/lib/time/util";
2
+ export { Duration } from "/lib/time/duration";
5
3
  export { DateTimeFormatter } from "/lib/time/format/date-time-formatter";
6
- export { TextStyle } from "/lib/time/format/text-style";
7
4
  export { FormatStyle } from "/lib/time/format/format-style";
5
+ export { TextStyle } from "/lib/time/format/text-style";
8
6
  export { Instant } from "/lib/time/instant";
9
7
  export { LocalDate } from "/lib/time/local-date";
8
+ export { LocalDateTime } from "/lib/time/local-date-time";
10
9
  export { LocalTime } from "/lib/time/local-time";
11
10
  export { Month, type MonthNumber } from "/lib/time/month";
12
11
  export { OffsetDateTime } from "/lib/time/offset-date-time";
13
12
  export { OffsetTime } from "/lib/time/offset-time";
13
+ export { Period } from "/lib/time/period";
14
+ export { ChronoUnit } from "/lib/time/temporal/chrono-unit";
15
+ export type { Temporal, TemporalAmount, TimeTemporal } from "/lib/time/temporal/temporal";
16
+ export { type JavaList, type JavaSet, LanguageRange, Locale } from "/lib/time/util";
14
17
  export { Year } from "/lib/time/year";
15
18
  export { ZoneId } from "/lib/time/zone-id";
16
19
  export { ZoneOffset } from "/lib/time/zone-offset";
20
+ export { ZonedDateTime } from "/lib/time/zoned-date-time";
17
21
  /**
18
22
  * Format a date to a string
19
- * @see {@link https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/format/DateTimeFormatter.html#patterns}
23
+ * @see {@link https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/time/format/DateTimeFormatter.html#patterns}
20
24
  *
21
25
  * @param date The date as a string
22
26
  * @param pattern The shape of the output string
package/instant.d.ts CHANGED
@@ -1,9 +1,10 @@
1
- import type { ZoneOffset, OffsetDateTime, ZoneId, ZonedDateTime } from "/lib/time";
1
+ import type { ChronoUnit, Duration, OffsetDateTime, ZonedDateTime, ZoneId, ZoneOffset } from "/lib/time";
2
+ import type { Temporal } from "/lib/time/temporal/temporal";
2
3
  /**
3
4
  * An instantaneous point on the time-line.
4
5
  *
5
6
  * This class models a single instantaneous point on the time-line. This might be used to record event time-stamps in the application.
6
- * @see {@link https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/Instant.html}
7
+ * @see {@link https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/time/Instant.html}
7
8
  */
8
9
  export declare const Instant: InstantConstructor;
9
10
  export interface InstantConstructor {
@@ -14,6 +15,18 @@ export interface InstantConstructor {
14
15
  parse(text: string): Instant;
15
16
  }
16
17
  export interface Instant {
18
+ minus(amountToSubtract: Duration): Instant;
19
+ minus(amountToSubtract: number, unit: ChronoUnit): Instant;
20
+ plus(amountToAdd: Duration): Instant;
21
+ plus(amountToAdd: number, unit: ChronoUnit): Instant;
22
+ /**
23
+ * Sets every unit smaller than the given one to zero, so truncating to hours gives the start of the hour
24
+ */
25
+ truncatedTo(unit: ChronoUnit): Instant;
26
+ /**
27
+ * The number of whole units until the other one. It is negative if the other one is earlier.
28
+ */
29
+ until(endExclusive: Temporal, unit: ChronoUnit): number;
17
30
  atOffset(offset: ZoneOffset): OffsetDateTime;
18
31
  atZone(zone: ZoneId): ZonedDateTime;
19
32
  compareTo(otherInstant: Instant): number;
@@ -1,7 +1,8 @@
1
- import type { DateTimeFormatter, Month, LocalDate, LocalTime, ZoneOffset, Instant, ZoneId, DayOfWeek, OffsetDateTime, ZonedDateTime } from "/lib/time";
1
+ import type { ChronoUnit, DateTimeFormatter, DayOfWeek, Instant, LocalDate, LocalTime, Month, OffsetDateTime, ZonedDateTime, ZoneId, ZoneOffset } from "/lib/time";
2
+ import type { Temporal, TemporalAmount } from "/lib/time/temporal/temporal";
2
3
  /**
3
4
  * LocalDateTime is an immutable date-time object that represents a date-time
4
- * @see {@link https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/LocalDateTime.html}
5
+ * @see {@link https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/time/LocalDateTime.html}
5
6
  */
6
7
  export declare const LocalDateTime: LocalDateTimeConstructor;
7
8
  export interface LocalDateTimeConstructor {
@@ -14,14 +15,26 @@ export interface LocalDateTimeConstructor {
14
15
  of(year: number, month: number, dayOfMonth: number, hour: number, minute: number): LocalDateTime;
15
16
  of(year: number, month: number, dayOfMonth: number, hour: number, minute: number, second: number): LocalDateTime;
16
17
  of(year: number, month: number, dayOfMonth: number, hour: number, minute: number, second: number, nanoOfSecond: number): LocalDateTime;
17
- of(year: number, month: Month, dayOfMonth: number, hour: number, minute: number, second: number, nanoOfSecond: number): LocalDateTime;
18
- of(year: number, month: Month, dayOfMonth: number, hour: number, minute: number, second: number, nanoOfSecond: number): LocalDateTime;
18
+ of(year: number, month: Month, dayOfMonth: number, hour: number, minute: number): LocalDateTime;
19
+ of(year: number, month: Month, dayOfMonth: number, hour: number, minute: number, second: number): LocalDateTime;
19
20
  of(year: number, month: Month, dayOfMonth: number, hour: number, minute: number, second: number, nanoOfSecond: number): LocalDateTime;
20
21
  of(date: LocalDate, time: LocalTime): LocalDateTime;
21
22
  ofEpochSecond(epochSecond: number, nanoOfSecond: number, offset: ZoneOffset): LocalDateTime;
22
23
  ofInstant(instant: Instant, zone: ZoneId): LocalDateTime;
23
24
  }
24
25
  export interface LocalDateTime {
26
+ minus(amountToSubtract: TemporalAmount): LocalDateTime;
27
+ minus(amountToSubtract: number, unit: ChronoUnit): LocalDateTime;
28
+ plus(amountToAdd: TemporalAmount): LocalDateTime;
29
+ plus(amountToAdd: number, unit: ChronoUnit): LocalDateTime;
30
+ /**
31
+ * Sets every unit smaller than the given one to zero, so truncating to hours gives the start of the hour
32
+ */
33
+ truncatedTo(unit: ChronoUnit): LocalDateTime;
34
+ /**
35
+ * The number of whole units until the other one. It is negative if the other one is earlier.
36
+ */
37
+ until(endExclusive: Temporal, unit: ChronoUnit): number;
25
38
  atOffset(offset: ZoneOffset): OffsetDateTime;
26
39
  atZone(zone: ZoneId): ZonedDateTime;
27
40
  format(formatter: DateTimeFormatter): string;
package/local-date.d.ts CHANGED
@@ -1,9 +1,10 @@
1
- import type { DateTimeFormatter, ZoneId, Month, Instant, LocalDateTime, ZonedDateTime, LocalTime, OffsetTime, OffsetDateTime, DayOfWeek, ZoneOffset } from "/lib/time";
1
+ import type { ChronoUnit, DateTimeFormatter, DayOfWeek, Instant, LocalDateTime, LocalTime, Month, OffsetDateTime, OffsetTime, Period, ZonedDateTime, ZoneId, ZoneOffset } from "/lib/time";
2
+ import type { Temporal } from "/lib/time/temporal/temporal";
2
3
  /**
3
4
  * A date without a time-zone in the ISO-8601 calendar system, such as 2007-12-03.
4
5
  *
5
6
  * LocalDate is an immutable date-time object that represents a date, often viewed as year-month-day. Other date fields, such as day-of-year, day-of-week and week-of-year, can also be accessed. For example, the value "2nd October 2007" can be stored in a LocalDate.
6
- * @see {@link https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/LocalDate.html}
7
+ * @see {@link https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/time/LocalDate.html}
7
8
  */
8
9
  export declare const LocalDate: LocalDateConstructor;
9
10
  interface LocalDateConstructor {
@@ -21,6 +22,18 @@ interface LocalDateConstructor {
21
22
  parse(text: string, formatter: DateTimeFormatter): LocalDate;
22
23
  }
23
24
  export interface LocalDate {
25
+ minus(amountToSubtract: Period): LocalDate;
26
+ minus(amountToSubtract: number, unit: ChronoUnit): LocalDate;
27
+ plus(amountToAdd: Period): LocalDate;
28
+ plus(amountToAdd: number, unit: ChronoUnit): LocalDate;
29
+ /**
30
+ * The years, months and days until the other date
31
+ */
32
+ until(endDateExclusive: LocalDate): Period;
33
+ /**
34
+ * The number of whole units until the other one. It is negative if the other one is earlier.
35
+ */
36
+ until(endExclusive: Temporal, unit: ChronoUnit): number;
24
37
  atStartOfDay(): LocalDateTime;
25
38
  atStartOfDay(zone: ZoneId): ZonedDateTime;
26
39
  atTime(hour: number, minute: number): LocalDateTime;
package/local-time.d.ts CHANGED
@@ -1,9 +1,10 @@
1
- import type { ZoneId, Instant, DateTimeFormatter, LocalDateTime, LocalDate, ZoneOffset, OffsetTime } from "/lib/time";
1
+ import type { ChronoUnit, DateTimeFormatter, Duration, Instant, LocalDate, LocalDateTime, OffsetTime, ZoneId, ZoneOffset } from "/lib/time";
2
+ import type { Temporal } from "/lib/time/temporal/temporal";
2
3
  /**
3
4
  * A time without a time-zone in the ISO-8601 calendar system, such as 10:15:30.
4
5
  *
5
6
  * LocalTime is an immutable date-time object that represents a time, often viewed as hour-minute-second. Time is represented to nanosecond precision. For example, the value "13:45.30.123456789" can be stored in a LocalTime.
6
- * @see {@link https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/LocalTime.html}
7
+ * @see {@link https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/time/LocalTime.html}
7
8
  */
8
9
  export declare const LocalTime: LocalTimeConstructor;
9
10
  export interface LocalTimeConstructor {
@@ -23,6 +24,18 @@ export interface LocalTimeConstructor {
23
24
  parse(text: string, formatter: DateTimeFormatter): LocalTime;
24
25
  }
25
26
  export interface LocalTime {
27
+ minus(amountToSubtract: Duration): LocalTime;
28
+ minus(amountToSubtract: number, unit: ChronoUnit): LocalTime;
29
+ plus(amountToAdd: Duration): LocalTime;
30
+ plus(amountToAdd: number, unit: ChronoUnit): LocalTime;
31
+ /**
32
+ * Sets every unit smaller than the given one to zero, so truncating to hours gives the start of the hour
33
+ */
34
+ truncatedTo(unit: ChronoUnit): LocalTime;
35
+ /**
36
+ * The number of whole units until the other one. It is negative if the other one is earlier.
37
+ */
38
+ until(endExclusive: Temporal, unit: ChronoUnit): number;
26
39
  atDate(date: LocalDate): LocalDateTime;
27
40
  atOffset(offset: ZoneOffset): OffsetTime;
28
41
  compareTo(other: LocalTime): number;
package/month.d.ts CHANGED
@@ -4,7 +4,7 @@ import type { Locale } from "./util";
4
4
  * A month-of-year, such as 'July'.
5
5
  *
6
6
  * Month is an enum representing the 12 months of the year - January, February, March, April, May, June, July, August, September, October, November and December.
7
- * @see {@link https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/Month.html}
7
+ * @see {@link https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/time/Month.html}
8
8
  */
9
9
  export declare const Month: MonthConstructor;
10
10
  export type MonthNumber = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
@@ -1,9 +1,10 @@
1
- import type { ZoneId, ZoneOffset, LocalDate, LocalTime, LocalDateTime, Instant, DateTimeFormatter, ZonedDateTime, DayOfWeek, Month, OffsetTime } from "/lib/time";
1
+ import type { ChronoUnit, DateTimeFormatter, DayOfWeek, Instant, LocalDate, LocalDateTime, LocalTime, Month, OffsetTime, ZonedDateTime, ZoneId, ZoneOffset } from "/lib/time";
2
+ import type { Temporal, TemporalAmount } from "/lib/time/temporal/temporal";
2
3
  /**
3
4
  * A date-time with an offset from UTC/Greenwich in the ISO-8601 calendar system, such as 2007-12-03T10:15:30+01:00.
4
5
  *
5
6
  * OffsetDateTime is an immutable representation of a date-time with an offset. This class stores all date and time fields, to a precision of nanoseconds, as well as the offset from UTC/Greenwich. For example, the value "2nd October 2007 at 13:45:30.123456789 +02:00" can be stored in an OffsetDateTime.
6
- * @see {@link https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/OffsetDateTime.html}
7
+ * @see {@link https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/time/OffsetDateTime.html}
7
8
  */
8
9
  export declare const OffsetDateTime: OffsetDateTimeConstructor;
9
10
  export interface OffsetDateTimeConstructor {
@@ -19,6 +20,18 @@ export interface OffsetDateTimeConstructor {
19
20
  parse(text: string, formatter: DateTimeFormatter): OffsetDateTime;
20
21
  }
21
22
  export interface OffsetDateTime {
23
+ minus(amountToSubtract: TemporalAmount): OffsetDateTime;
24
+ minus(amountToSubtract: number, unit: ChronoUnit): OffsetDateTime;
25
+ plus(amountToAdd: TemporalAmount): OffsetDateTime;
26
+ plus(amountToAdd: number, unit: ChronoUnit): OffsetDateTime;
27
+ /**
28
+ * Sets every unit smaller than the given one to zero, so truncating to hours gives the start of the hour
29
+ */
30
+ truncatedTo(unit: ChronoUnit): OffsetDateTime;
31
+ /**
32
+ * The number of whole units until the other one. It is negative if the other one is earlier.
33
+ */
34
+ until(endExclusive: Temporal, unit: ChronoUnit): number;
22
35
  atZoneSameInstant(zone: ZoneId): ZonedDateTime;
23
36
  atZoneSimilarLocal(zone: ZoneId): ZonedDateTime;
24
37
  compareTo(other: OffsetDateTime): number;
package/offset-time.d.ts CHANGED
@@ -1,9 +1,10 @@
1
- import type { ZoneId, ZoneOffset, LocalDate, LocalTime, Instant, DateTimeFormatter, OffsetDateTime } from "/lib/time";
1
+ import type { ChronoUnit, DateTimeFormatter, Duration, Instant, LocalDate, LocalTime, OffsetDateTime, ZoneId, ZoneOffset } from "/lib/time";
2
+ import type { Temporal } from "/lib/time/temporal/temporal";
2
3
  /**
3
4
  * A time without a time-zone in the ISO-8601 calendar system, such as 10:15:30.
4
5
  *
5
6
  * LocalTime is an immutable date-time object that represents a time, often viewed as hour-minute-second. Time is represented to nanosecond precision. For example, the value "13:45.30.123456789" can be stored in a LocalTime.
6
- * @see {@link https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/OffsetTime.html}
7
+ * @see {@link https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/time/OffsetTime.html}
7
8
  */
8
9
  export declare const OffsetTime: OffsetTimeConstructor;
9
10
  export interface OffsetTimeConstructor {
@@ -18,6 +19,18 @@ export interface OffsetTimeConstructor {
18
19
  parse(text: string, formatter: DateTimeFormatter): OffsetTime;
19
20
  }
20
21
  export interface OffsetTime {
22
+ minus(amountToSubtract: Duration): OffsetTime;
23
+ minus(amountToSubtract: number, unit: ChronoUnit): OffsetTime;
24
+ plus(amountToAdd: Duration): OffsetTime;
25
+ plus(amountToAdd: number, unit: ChronoUnit): OffsetTime;
26
+ /**
27
+ * Sets every unit smaller than the given one to zero, so truncating to hours gives the start of the hour
28
+ */
29
+ truncatedTo(unit: ChronoUnit): OffsetTime;
30
+ /**
31
+ * The number of whole units until the other one. It is negative if the other one is earlier.
32
+ */
33
+ until(endExclusive: Temporal, unit: ChronoUnit): number;
21
34
  atDate(date: LocalDate): OffsetDateTime;
22
35
  compareTo(other: OffsetTime): number;
23
36
  format(formatter: DateTimeFormatter): string;
package/package.json CHANGED
@@ -1,39 +1,40 @@
1
1
  {
2
2
  "name": "@item-enonic-types/lib-time",
3
- "version": "1.6.1",
3
+ "version": "2.0.0",
4
4
  "description": "Type definitions for lib-time",
5
5
  "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/ItemConsulting/lib-xp-time.git"
9
+ },
6
10
  "files": [
7
11
  "*.d.ts",
8
12
  "format/*.d.ts",
13
+ "temporal/*.d.ts",
9
14
  "tsconfig.json"
10
15
  ],
11
16
  "devDependencies": {
12
- "@changesets/cli": "^2.29.8",
13
- "@item-enonic-types/lib-testing": "^7.13.0",
14
- "@swc/core": "^1.15.8",
15
- "@types/node": "^25.0.3",
16
- "eslint": "^9.39.2",
17
- "eslint-config-prettier": "^10.1.8",
18
- "eslint-plugin-prettier": "^5.5.4",
19
- "concurrently": "^9.2.1",
20
- "glob": "^13.0.0",
21
- "prettier": "^3.7.4",
22
- "tsup": "^8.5.1",
23
- "typescript": "^5.9.3",
24
- "typescript-eslint": "^8.52.0"
17
+ "@biomejs/biome": "^2.5.15",
18
+ "@changesets/cli": "^3.0.3",
19
+ "@item-enonic-types/lib-testing": "^8.0.0",
20
+ "@swc/core": "^1.16.18",
21
+ "@types/node": "^26.6.5",
22
+ "concurrently": "^10.0.6",
23
+ "tsdown": "^0.23.1",
24
+ "typescript": "^7.0.2"
25
25
  },
26
26
  "dependencies": {
27
27
  "@item-enonic-types/nashorn-env": "^0.0.2"
28
28
  },
29
29
  "scripts": {
30
- "build": "node tsup/anyServerFiles.js && npx tsup -d build/resources/main",
30
+ "build": "tsdown",
31
31
  "check": "concurrently -c auto -g --timings npm:check:types npm:lint",
32
- "check:types": "node tsup/anyServerFiles.js && npx tsc --noEmit -p src/main/resources/tsconfig.json || exit 0",
33
- "lint": "eslint --cache \"src/main/resources/**/*.ts\"",
32
+ "check:types": "tsc --noEmit -p src/main/resources/tsconfig.json",
33
+ "lint": "biome ci",
34
+ "lint:fix": "biome check --write",
34
35
  "prepublishOnly": "tsc --project src/main/resources/tsconfig.json --declarationDir build/types --emitDeclarationOnly true --declaration true && cp -r ./build/types/* .",
35
- "postpublish": "rm ./*.d.ts && rm -r ./format",
36
- "release": "npm run build",
37
- "versioning": "npx changeset version && npm i --package-lock-only && NEW_VERSION=$(node -p \"require('./package.json').version\") && sed -i \"s/version.*/version = ${NEW_VERSION}/\" gradle.properties"
36
+ "postpublish": "rm ./*.d.ts && rm -r ./format ./temporal",
37
+ "release": "changeset publish",
38
+ "versioning": "changeset version && npm i --package-lock-only && node .changeset/gradle-version.mjs"
38
39
  }
39
40
  }
package/period.d.ts ADDED
@@ -0,0 +1,53 @@
1
+ import type { LocalDate } from "/lib/time";
2
+ /**
3
+ * A date-based amount of time in the ISO-8601 calendar system, such as '2 years, 3 months and 4 days'.
4
+ *
5
+ * This class models a quantity or amount of time in terms of years, months and days. How long that is depends on the
6
+ * date it is added to: a month can be 28 to 31 days. Use Duration for an exact amount of time.
7
+ * @see {@link https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/time/Period.html}
8
+ */
9
+ export declare const Period: PeriodConstructor;
10
+ export interface PeriodConstructor {
11
+ ZERO: Period;
12
+ between(startDateInclusive: LocalDate, endDateExclusive: LocalDate): Period;
13
+ of(years: number, months: number, days: number): Period;
14
+ ofDays(days: number): Period;
15
+ ofMonths(months: number): Period;
16
+ ofWeeks(weeks: number): Period;
17
+ ofYears(years: number): Period;
18
+ /**
19
+ * Parses an ISO-8601 period, such as "P1Y2M3D" or "P2W".
20
+ */
21
+ parse(text: string): Period;
22
+ }
23
+ export interface Period {
24
+ equals(otherPeriod: unknown): boolean;
25
+ getDays(): number;
26
+ getMonths(): number;
27
+ getYears(): number;
28
+ hashCode(): number;
29
+ isNegative(): boolean;
30
+ isZero(): boolean;
31
+ minus(amountToSubtract: Period): Period;
32
+ minusDays(daysToSubtract: number): Period;
33
+ minusMonths(monthsToSubtract: number): Period;
34
+ minusYears(yearsToSubtract: number): Period;
35
+ multipliedBy(scalar: number): Period;
36
+ negated(): Period;
37
+ /**
38
+ * Moves whole years out of the months, so "P15M" becomes "P1Y3M". The days are left as they are.
39
+ */
40
+ normalized(): Period;
41
+ plus(amountToAdd: Period): Period;
42
+ plusDays(daysToAdd: number): Period;
43
+ plusMonths(monthsToAdd: number): Period;
44
+ plusYears(yearsToAdd: number): Period;
45
+ /**
46
+ * The ISO-8601 representation, such as "P1Y2M3D"
47
+ */
48
+ toString(): string;
49
+ toTotalMonths(): number;
50
+ withDays(days: number): Period;
51
+ withMonths(months: number): Period;
52
+ withYears(years: number): Period;
53
+ }
@@ -0,0 +1,41 @@
1
+ import type { Duration } from "/lib/time";
2
+ import type { Temporal } from "/lib/time/temporal/temporal";
3
+ /**
4
+ * A standard set of date periods units.
5
+ *
6
+ * This set of units provide unit-based access to manipulate a date, time or date-time. For example,
7
+ * `ChronoUnit.DAYS.between(start, end)` gives the number of whole days between two dates.
8
+ * @see {@link https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/time/temporal/ChronoUnit.html}
9
+ */
10
+ export declare const ChronoUnit: ChronoUnitConstructor;
11
+ export interface ChronoUnitConstructor {
12
+ NANOS: ChronoUnit;
13
+ MICROS: ChronoUnit;
14
+ MILLIS: ChronoUnit;
15
+ SECONDS: ChronoUnit;
16
+ MINUTES: ChronoUnit;
17
+ HOURS: ChronoUnit;
18
+ HALF_DAYS: ChronoUnit;
19
+ DAYS: ChronoUnit;
20
+ WEEKS: ChronoUnit;
21
+ MONTHS: ChronoUnit;
22
+ YEARS: ChronoUnit;
23
+ DECADES: ChronoUnit;
24
+ CENTURIES: ChronoUnit;
25
+ MILLENNIA: ChronoUnit;
26
+ ERAS: ChronoUnit;
27
+ FOREVER: ChronoUnit;
28
+ valueOf(name: string): ChronoUnit;
29
+ values(): ChronoUnit[];
30
+ }
31
+ export interface ChronoUnit {
32
+ /**
33
+ * The number of whole units between the two. It is negative if the end is before the start.
34
+ */
35
+ between(startInclusive: Temporal, endExclusive: Temporal): number;
36
+ getDuration(): Duration;
37
+ isDateBased(): boolean;
38
+ isDurationEstimated(): boolean;
39
+ isTimeBased(): boolean;
40
+ toString(): string;
41
+ }
@@ -0,0 +1,15 @@
1
+ import type { Duration, Instant, LocalDate, LocalDateTime, LocalTime, OffsetDateTime, OffsetTime, Period, Year, ZonedDateTime } from "/lib/time";
2
+ /**
3
+ * The date-time objects in this library: the ones that can be formatted, compared and have time added to them.
4
+ * @see {@link https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/time/temporal/Temporal.html}
5
+ */
6
+ export type Temporal = Instant | LocalDate | LocalDateTime | LocalTime | OffsetDateTime | OffsetTime | Year | ZonedDateTime;
7
+ /**
8
+ * The date-time objects that have a time of day, which is what an exact amount of time can be measured between.
9
+ */
10
+ export type TimeTemporal = Instant | LocalDateTime | LocalTime | OffsetDateTime | OffsetTime | ZonedDateTime;
11
+ /**
12
+ * An amount of time, that can be added to or subtracted from a date-time object.
13
+ * @see {@link https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/time/temporal/TemporalAmount.html}
14
+ */
15
+ export type TemporalAmount = Duration | Period;
package/tsconfig.json CHANGED
@@ -1,18 +1,18 @@
1
1
  {
2
- "include": [
3
- "**/*.ts"
4
- ],
2
+ "include": ["**/*.ts", "**/*.mts"],
5
3
  "exclude": [
6
4
  "**/*.d.ts",
7
- "src/**/*.*", // Avoid Enonic XP source files
5
+ "src/**/*.*" // Avoid Enonic XP source files
8
6
  ],
9
7
 
10
8
  "compilerOptions": {
9
+ "strict": true,
11
10
  "lib": [
12
11
  "es2023" // string.replaceAll
13
12
  ],
14
- "types": [
15
- "node"
16
- ],
17
- },
13
+ "types": ["node"],
14
+ "skipLibCheck": true,
15
+ "module": "preserve",
16
+ "moduleResolution": "bundler"
17
+ }
18
18
  }
package/util.d.ts CHANGED
@@ -1,12 +1,38 @@
1
1
  /**
2
2
  * A Locale object represents a specific geographical, political, or cultural region.
3
- * @see {@link https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Locale.html}
3
+ * @see {@link https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/util/Locale.html}
4
4
  */
5
5
  export declare const Locale: LocaleConstructor;
6
6
  /**
7
7
  * A LanguageRange can be used to parse `req.headers["Accept-Language"]` to determine the best matching language.
8
8
  */
9
9
  export declare const LanguageRange: LanguageRangeConstructor;
10
+ /**
11
+ * A `java.util.List` returned from Java. It can be read by index and looped over like an array, but it is not a
12
+ * JavaScript array: methods such as `map()` and `filter()` are not available on every script engine.
13
+ */
14
+ export interface JavaList<T> {
15
+ readonly [index: number]: T;
16
+ readonly length: number;
17
+ forEach(callback: (value: T) => void): void;
18
+ contains(value: T): boolean;
19
+ get(index: number): T;
20
+ isEmpty(): boolean;
21
+ size(): number;
22
+ }
23
+ /**
24
+ * A `java.util.Set` returned from Java. It has no order, so it can not be read by index.
25
+ */
26
+ export interface JavaSet<T> {
27
+ forEach(callback: (value: T) => void): void;
28
+ contains(value: T): boolean;
29
+ isEmpty(): boolean;
30
+ size(): number;
31
+ }
32
+ /**
33
+ * Where Java takes a list of language ranges, both a JavaScript array and the list from `LanguageRange.parse()` work.
34
+ */
35
+ export type LanguagePriorityList = LanguageRange[] | JavaList<LanguageRange>;
10
36
  export interface LocaleConstructor {
11
37
  new (language: string, country?: string, variant?: string): Locale;
12
38
  CANADA: Locale;
@@ -31,19 +57,18 @@ export interface LocaleConstructor {
31
57
  UK: Locale;
32
58
  UNICODE_LOCALE_EXTENSION: Locale;
33
59
  US: Locale;
34
- filter(priorityList: LanguageRange[], locales: Locale[]): Locale[];
35
- filterTags(priorityList: LanguageRange[], tags: string[]): string[];
60
+ filter(priorityList: LanguagePriorityList, locales: Locale[]): JavaList<Locale>;
61
+ filterTags(priorityList: LanguagePriorityList, tags: string[]): JavaList<string>;
36
62
  forLanguageTag(languageTag: string): Locale;
37
63
  getAvailableLocales(): Locale[];
38
64
  getDefault(): Locale;
39
65
  getISOCountries(): string[];
40
66
  getISOLanguages(): string[];
41
- lookup(priorityList: LanguageRange[], locales: Locale[]): Locale;
42
- lookupTag(priorityList: LanguageRange[], tags: string[]): Locale;
67
+ lookup(priorityList: LanguagePriorityList, locales: Locale[]): Locale | null;
68
+ lookupTag(priorityList: LanguagePriorityList, tags: string[]): string | null;
43
69
  setDefault(newLocale: Locale): void;
44
70
  }
45
71
  export interface Locale {
46
- getSubLocale(): string;
47
72
  getCountry(): string;
48
73
  getDisplayCountry(): string;
49
74
  getDisplayLanguage(): string;
@@ -73,9 +98,9 @@ interface LanguageRangeConstructor {
73
98
  new (range: string, weight?: number): LanguageRange;
74
99
  MAX_WEIGHT: number;
75
100
  MIN_WEIGHT: number;
76
- mapEquivalents(priorityList: LanguageRange[], map: Record<string, string[]>): LanguageRange[];
77
- parse(ranges: string): LanguageRange[];
78
- parse(ranges: string, map: Record<string, string[]>): LanguageRange[];
101
+ mapEquivalents(priorityList: LanguagePriorityList, map: Record<string, string[]>): JavaList<LanguageRange>;
102
+ parse(ranges: string): JavaList<LanguageRange>;
103
+ parse(ranges: string, map: Record<string, string[]>): JavaList<LanguageRange>;
79
104
  }
80
105
  export interface LanguageRange {
81
106
  getRange(): string;
package/year.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- import type { ZoneId } from "./zone-id";
2
- import type { LocalDate } from "./local-date";
3
1
  import type { DateTimeFormatter } from "./format/date-time-formatter";
2
+ import type { LocalDate } from "./local-date";
3
+ import type { ZoneId } from "./zone-id";
4
4
  /**
5
5
  * A year in the ISO-8601 calendar system, such as 2007.
6
6
  * Year is an immutable date-time object that represents a year. Any field that can be derived from a year can be obtained.
7
- * @see {@link https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/Year.html}
7
+ * @see {@link https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/time/Year.html}
8
8
  */
9
9
  export declare const Year: YearConstructor;
10
10
  export interface YearConstructor {
@@ -20,7 +20,7 @@ export interface Year {
20
20
  toString(): string;
21
21
  hashCode(): number;
22
22
  atDay(dayOfYear: number): LocalDate;
23
- compareTo(other: Year): boolean;
23
+ compareTo(other: Year): number;
24
24
  format(formatter: DateTimeFormatter): string;
25
25
  isAfter(other: Year): boolean;
26
26
  isBefore(other: Year): boolean;
package/zone-id.d.ts CHANGED
@@ -1,12 +1,13 @@
1
1
  import type { ZoneOffset } from "/lib/time";
2
+ import type { JavaSet } from "/lib/time/util";
2
3
  /**
3
4
  * A time-zone ID, such as Europe/Paris.
4
- * @see {@link https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/ZoneId.html}
5
+ * @see {@link https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/time/ZoneId.html}
5
6
  */
6
7
  export declare const ZoneId: ZoneIdConstructor;
7
8
  export interface ZoneIdConstructor {
8
9
  SHORT_IDS: Record<string, string>;
9
- getAvailableZoneIds(): ReadonlyArray<string>;
10
+ getAvailableZoneIds(): JavaSet<string>;
10
11
  of(zoneId: string): ZoneId;
11
12
  of(zoneId: string, aliasMap: Record<string, string>): ZoneId;
12
13
  ofOffset(prefix: string, offset: ZoneOffset): ZoneId;
package/zone-offset.d.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  * A time-zone offset from Greenwich/UTC, such as +02:00.
3
3
  *
4
4
  * A time-zone offset is the amount of time that a time-zone differs from Greenwich/UTC. This is usually a fixed number of hours and minutes.
5
- * @see {@link https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/ZoneOffset.html}
5
+ * @see {@link https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/time/ZoneOffset.html}
6
6
  */
7
7
  export declare const ZoneOffset: ZoneOffsetConstructor;
8
8
  export interface ZoneOffsetConstructor {
@@ -1,7 +1,8 @@
1
- import type { DateTimeFormatter, ZoneId, ZoneOffset, LocalDate, LocalTime, LocalDateTime, Instant, OffsetDateTime, DayOfWeek, Month } from "/lib/time";
1
+ import type { ChronoUnit, DateTimeFormatter, DayOfWeek, Instant, LocalDate, LocalDateTime, LocalTime, Month, OffsetDateTime, ZoneId, ZoneOffset } from "/lib/time";
2
+ import type { Temporal, TemporalAmount } from "/lib/time/temporal/temporal";
2
3
  /**
3
4
  * ZonedDateTime is an immutable representation of a date-time with a time-zone.
4
- * @see {@link https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/ZonedDateTime.html}
5
+ * @see {@link https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/time/ZonedDateTime.html}
5
6
  */
6
7
  export declare const ZonedDateTime: ZonedDateTimeConstructor;
7
8
  export interface ZonedDateTimeConstructor {
@@ -18,6 +19,18 @@ export interface ZonedDateTimeConstructor {
18
19
  parse(text: string, formatter: DateTimeFormatter): ZonedDateTime;
19
20
  }
20
21
  export interface ZonedDateTime {
22
+ minus(amountToSubtract: TemporalAmount): ZonedDateTime;
23
+ minus(amountToSubtract: number, unit: ChronoUnit): ZonedDateTime;
24
+ plus(amountToAdd: TemporalAmount): ZonedDateTime;
25
+ plus(amountToAdd: number, unit: ChronoUnit): ZonedDateTime;
26
+ /**
27
+ * Sets every unit smaller than the given one to zero, so truncating to hours gives the start of the hour
28
+ */
29
+ truncatedTo(unit: ChronoUnit): ZonedDateTime;
30
+ /**
31
+ * The number of whole units until the other one. It is negative if the other one is earlier.
32
+ */
33
+ until(endExclusive: Temporal, unit: ChronoUnit): number;
21
34
  format(formatter: DateTimeFormatter): string;
22
35
  getDayOfMonth(): number;
23
36
  getDayOfWeek(): DayOfWeek;