UNPKG

33.1 kBMarkdownView Raw
1# js-joda cheat sheet
2
3For a detailed API Reference refer to the [ESDoc generated docs](./esdoc/).
4
5## Table of contents
6
7<!-- toc -->
8
9- [General concepts](#general-concepts)
10 * [Method naming conventions](#method-naming-conventions)
11- [LocalDate](#localdate)
12 * [Create a `LocalDate`](#create-a-localdate)
13 * [Get values from `LocalDate`](#get-values-from-localdate)
14 * [Get week of week-based year, quarter of year, day of quarter](#get-week-of-week-based-year-quarter-of-year-day-of-quarter)
15 * [Adding to and subtracting from a `LocalDate`](#adding-to-and-subtracting-from-a-localdate)
16 * [Alter specific fields of a LocalDate](#alter-specific-fields-of-a-localdate)
17 * [Compare one `LocalDate` with another](#compare-one-localdate-with-another)
18 * [Distance on the timeline](#distance-on-the-timeline)
19 * [Converting from and to other temporals](#converting-from-and-to-other-temporals)
20 * [Adjust a date to another date](#adjust-a-date-to-another-date)
21- [LocalTime](#localtime)
22 * [Create a `LocalTime` instance](#create-a-localtime-instance)
23 * [Get values from `LocalTime`](#get-values-from-localtime)
24 * [Adding to/ subtracting from a `LocalTime` instance](#adding-to-subtracting-from-a-localtime-instance)
25 * [Alter specific fields of a `LocalTime` instance](#alter-specific-fields-of-a-localtime-instance)
26 * [Truncate a `LocalTime` instance](#truncate-a-localtime-instance)
27 * [Compare `LocalTime` instances](#compare-localtime-instances)
28 * [Distance between times](#distance-between-times)
29 * [Convert a `LocalTime` from a `moment` or JavaScript `Date`](#convert-a-localtime-from-a-moment-or-javascript-date)
30- [LocalDateTime](#localdatetime)
31 * [Create a `LocalDateTime` instance](#create-a-localdatetime-instance)
32 * [Get values from `LocalDateTime`](#get-values-from-localdatetime)
33 * [Adding to and subtracting from a `LocalDateTime` instance](#adding-to-and-subtracting-from-a-localdatetime-instance)
34 * [Alter specific fields of a `LocalDateTime` instance](#alter-specific-fields-of-a-localdatetime-instance)
35 * [Truncate a `LocalDateTime` instance](#truncate-a-localdatetime-instance)
36 * [Compare `LocalDateTime` instances](#compare-localdatetime-instances)
37 * [Distance between two `LocalDateTime` instances](#distance-between-two-localdatetime-instances)
38 * [Convert from a `moment` or JavaScript `Date`](#convert-from-a-moment-or-javascript-date)
39- [ZonedDateTime](#zoneddatetime)
40 * [The `SYSTEM` zone ID](#the-system-zone-id)
41 * [Working with time zones](#working-with-time-zones)
42 * [Create a ZonedDateTime](#create-a-zoneddatetime)
43 * [Switch time zones](#switch-time-zones)
44 * [Get and manipulate values from a `ZonedDateTime`](#get-and-manipulate-values-from-a-zoneddatetime)
45 * [Calculate values across daylight savings transitions](#calculate-values-across-daylight-savings-transitions)
46- [Period](#period)
47- [Duration](#duration)
48- [Customizing js-joda](#customizing-js-joda)
49 * [Custom temporal adjuster](#custom-temporal-adjuster)
50 * [Custom temporal fields and temporal units](#custom-temporal-fields-and-temporal-units)
51 * [Custom formatter and queries](#custom-formatter-and-queries)
52
53<!-- tocstop -->
54
55---
56
57## General concepts
58
59The API is **immutable**. An existing instance is never changed. All manipulating methods (`plus`, `at`, etc.) return new instances.
60
61**An existing instance is always valid**. If you try to create an invalid value, you'll get an exception instead of a `null` or `undefined` value.
62
63### Method naming conventions
64
65The API uses consistently named methods.
66
67| method name or prefix | usage | examples |
68| --------------------- | -------------------------------------------- | --------------------------------------------------------------- |
69| `.of` | static factory method for building by parts | `LocalDate.of(2016, 2, 23)` <br> `LocalDate.ofInstant(i)` |
70| `.parse` | static factory method for parsing strings | `LocalDate.parse('2016-02-23')` <br> `LocalTime.parse('12:34')` |
71| `.is` | checks for certain conditions | `t1.isAfter(t2)` <br> `d1.isLeapYear()` |
72| `.equals` | checks for equivalence between two instances | `t1.equals(t2)` |
73| `.with` | the immutable equivalent of a setter | `d.withDayOfMonth(1)` <br> `t.withHour(9)` |
74| `.plus` | adds an amount to an object | `t.plusMinutes(5)` <br> `d.plus(3, ChronoUnit.YEARS)` |
75| `.minus` | subtracts an amount from an object | `t.minusHours(1)` <br> `d.minus(1, ChronoUnit.DAYS)` |
76| `.to` | converts this object to another type | `dt.toLocalDate()` <br> `d1.until(d2).toTotalMonths()` |
77| `.at` | combines one object with another | `date.atTime(time)` <br> `localDate.atZone(tz)` |
78
79Note that getter methods for instance properties omit the get keyword: `d.year()`, not ~~`d.getYear()`~~.
80
81## LocalDate
82
83A `LocalDate` represents a date with **no time** and **no time zone** in the [ISO-8601](https://en.wikipedia.org/wiki/ISO_8601) calendar system, such as 2007-12-24.
84
85### Create a `LocalDate`
86
87```javascript
88// obtain the current date in the system default time zone, e.g. 2016-02-23
89LocalDate.now();
90
91// obtain the current date in the UTC time zone, e.g. 2016-02-23
92LocalDate.now(ZoneOffset.UTC);
93
94// obtain an instance of LocalDate from an ISO 8601 formatted text string
95LocalDate.parse('2016-02-23');
96
97// obtain an instance of LocalDate from a year, month, and dayOfMonth value
98LocalDate.of(2016, 2, 23); // 2016-02-23
99
100// obtain an instance of LocalDate from a year, month, and dayOfMonth value
101LocalDate.of(2016, Month.FEBRUARY, 23); // 2016-02-23
102
103// obtain an instance of LocalDate from an epochDay where day 0 is 1970-01-01
104LocalDate.ofEpochDay(-1); // 1969-12-31
105
106// obtain an instance of LocalDate from an epochDay where day 0 is 1970-01-01
107LocalDate.ofYearDay(2016, 42); // 2016-02-11
108```
109
110### Get values from `LocalDate`
111
112```javascript
113var d = LocalDate.parse('2016-12-24');
114
115d.toString(); // '2016-12-24' ISO 8601 format
116
117d.dayOfMonth(); // 24
118d.month(); // Month.DECEMBER
119d.monthValue(); // 12
120d.year(); // 2016
121
122d.dayOfWeek(); // DayOfWeek.SATURDAY
123d.dayOfWeek().value(); // 6
124d.dayOfYear(); // 359
125
126d.isLeapYear(); // true - 2016 is a leap year
127d.plusYears(1).isLeapYear(); // false
128
129// get the epoch day where 0 is 1970-01-01
130d.toEpochDay(); // 17159
131
132// get range of month
133d.lengthOfMonth(); // 31
134d.range(ChronoField.DAY_OF_MONTH); // ValueRange(1 - 31)
135
136// get range of year
137d.lengthOfYear(); // 366
138d.range(ChronoField.DAY_OF_YEAR); // ValueRange(1 - 366)
139
140// get other date-based field like the aligned week of year
141d.get(ChronoField.ALIGNED_WEEK_OF_YEAR); // 52
142
143// or the day of week aligned to the first day of month
144d.get(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH); // 3
145```
146
147### Get week of week-based year, quarter of year, day of quarter
148
149```javascript
150// get week of week-based year as defined by ISO 8601, with a Monday-based week
151d.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR); // 51
152
153d.isoWeekOfWeekyear(); // 51, equivalent to the above
154d.isoWeekyear(); // 2016
155
156LocalDate.of(2017, 1, 1).isoWeekOfWeekyear(); // 52
157LocalDate.of(2017, 1, 1).isoWeekyear(); // 2016
158
159// set the date to week 52 of week-based year with the same day of week
160d.with(IsoFields.WEEK_OF_WEEK_BASED_YEAR, 52); // 2016-12-31
161
162// get the quarter of the year
163d.get(IsoFields.QUARTER_OF_YEAR); // 4
164d.get(IsoFields.DAY_OF_QUARTER); // 85
165
166// set the date to the 15th day of the third quarter
167d.with(IsoFields.QUARTER_OF_YEAR, 3).with(IsoFields.DAY_OF_QUARTER, 15); // 2016-07-15
168```
169
170### Adding to and subtracting from a `LocalDate`
171
172Note that each of these methods returns a new `LocalDate` instance.
173
174```javascript
175var d = LocalDate.parse('2016-02-23');
176
177// add/subtract 366 days
178d.plusDays(366); // '2017-02-23'
179d.minusDays(366); // '2015-02-22'
180
181// add/subtract 12 months
182d.plusMonths(12); // '2017-02-23'
183d.minusMonths(12); // '2015-02-23'
184
185// add/subtract 4 weeks
186d.plusWeeks(4); // '2016-03-22'
187d.minusWeeks(4); // '2016-01-26'
188
189// add/subtract 1 year
190d.plusYears(1); // '2017-02-23'
191d.minusYears(1); // '2015-02-23'
192
193// add/subtract 30 years
194d.plus(3, ChronoUnit.DECADES); // '2046-02-23'
195d.minus(3, ChronoUnit.DECADES); // '1986-02-23'
196
197// add/subtract a Period of 3 Months and 3 Days
198d.plus(Period.ofMonths(3).plusDays(3)); // '2016-05-26'
199d.minus(Period.ofMonths(3).plusDays(3)); // '2015-11-20'
200```
201
202### Alter specific fields of a LocalDate
203
204```javascript
205var d = LocalDate.parse('2016-12-24');
206
207// set the day of month to 1
208d.withDayOfMonth(1); // '2016-12-01'
209
210// set month and the day of month to 1
211d.withMonth(1).withDayOfMonth(1); // '2016-01-01'
212
213// set month to November and the day of month to 1
214d.withMonth(Month.NOVEMBER).withDayOfMonth(1); // '2016-11-01'
215
216// set the year to beginning of era
217d.withYear(1); // '0001-12-24'
218
219// get the last day of the current month
220LocalDate.now()
221 .plusMonths(1)
222 .withDayOfMonth(1)
223 .minusDays(1);
224
225// set the day of year
226d.withDayOfYear(42); // 2016-02-11
227
228// set the week of week-based year to 52
229d.with(IsoFields.WEEK_OF_WEEK_BASED_YEAR, 52); // 2016-12-31
230```
231
232### Compare one `LocalDate` with another
233
234```javascript
235var d1 = LocalDate.parse('2016-12-24');
236var d2 = d1.plusDays(2);
237
238d1.isAfter(d2); // false
239d1.isBefore(d2); // true
240
241d1.equals(d2); // false
242d1.equals(d1.plusDays(0)); // true
243d1.equals(d1.plusDays(1)); // false
244
245d1.compareTo(d1) === 0; // true
246d1.compareTo(d2) < 0; // true
247d2.compareTo(d1) > 0; // true
248
249d1.hashCode(); // 4129560
250d2.hashCode(); // 4129562
251d1.hashCode() !== d2.hashCode(); // true
252```
253
254### Distance on the timeline
255
256```javascript
257var d1 = LocalDate.parse('2016-12-24');
258var d2 = d1.plusMonths(13).plusDays(42);
259
260// obtain the Period between the two dates
261d1.until(d2).toString(); // 'P1Y2M11D' (1 year, 2 months, 11 days in ISO-8601 period format)
262d1.until(d2).toTotalMonths(); // 14
263
264// obtain the distance between the two dates with a specific precision
265d1.until(d2, ChronoUnit.MONTHS); // 14, returns the distance in total months
266d1.until(d2, ChronoUnit.DAYS); // 438, returns the distance in total days
267```
268
269### Converting from and to other temporals
270
271```javascript
272// obtain a LocalDate from a LocalDateTime instance
273var dt = LocalDateTime.now();
274LocalDate.from(dt); // LocalDate from LocalDateTime
275dt.toLocalDate(); // LocalDateTime to LocalDate (equivalent to the above)
276
277var d1 = LocalDate.parse('2016-02-25');
278
279// obtain a LocalDateTime at a certain LocalTime
280d1.atStartOfDay(); // '2016-02-25T00:00'
281d1.atTime(LocalTime.of(11, 55)); // '2016-02-25T11:55'
282d1.atTime(LocalTime.NOON); // '2016-02-25T12:00'
283
284// obtain a LocalDate from a JavaScript Date
285
286// the manual way
287var d = LocalDate.ofInstant(Instant.ofEpochMilli(new Date().getTime()));
288// the recommended way with the JavaScript temporal
289d = LocalDate.from(nativeJs(new Date()));
290// converting from a moment works the same way
291d = LocalDate.from(nativeJs(moment()));
292```
293
294### Adjust a date to another date
295
296`TemporalAdjusters` provide compact business logic for date-based temporals such as `LocalDate`, `LocalDateTime` or `ZonedDateTime`.
297
298```javascript
299var d = LocalDate.parse('2016-12-24');
300
301// get first/ last day of month
302d.with(TemporalAdjusters.firstDayOfMonth()); // 2016-12-01
303d.with(TemporalAdjusters.lastDayOfMonth()); // 2016-12-31
304
305// get the next specified weekday
306d.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY)); // 2016-12-25
307d.with(TemporalAdjusters.nextOrSame(DayOfWeek.SATURDAY)); // 2016-12-24
308d.with(TemporalAdjusters.next(DayOfWeek.SATURDAY)); // 2016-12-31
309
310// get the first/last weekday of month
311d.with(TemporalAdjusters.lastInMonth(DayOfWeek.SATURDAY)); // 2016-12-31
312d.with(TemporalAdjusters.firstInMonth(DayOfWeek.SATURDAY)); // 2016-12-03
313```
314
315Find more adjusters in the TemporalAdjusters API documentation.
316
317## LocalTime
318
319A `LocalTime` represents a time with **no date** and **no time zone** in the [ISO-8601](https://en.wikipedia.org/wiki/ISO_8601) calendar system, such as '10:15:30'
320
321### Create a `LocalTime` instance
322
323```javascript
324// obtain the current time in the system default time zone, e.g. '10:29:05.743'
325LocalTime.now();
326
327// obtain the current time in the UTC time zone, e.g. '09:29:05.743'
328LocalTime.now(ZoneOffset.UTC);
329
330// obtain an instance of LocalTime from an ISO 8601 formatted text string
331LocalTime.parse('09:42'); // '09:42'
332LocalTime.parse('09:42:42'); // '09:42:42'
333LocalTime.parse('09:42:42.123'); // '09:42:42.123'
334LocalTime.parse('09:42:42.123456789'); // '09:42:42.123456789'
335
336// obtain an instance of LocalTime from hour, minute, second, and nanosecond values
337LocalTime.of(23, 55); // '23:55'
338LocalTime.of(23, 55, 42); // '23:55:42'
339LocalTime.of(23, 55, 42, 123000000); // '23:55:42.123'
340
341// obtain an instance of LocalTime from second of day
342LocalTime.ofSecondOfDay(3666); // '01:01:06'
343```
344
345### Get values from `LocalTime`
346
347```javascript
348var t = LocalTime.parse('23:55:42.123');
349
350t.toString(); // '23:55:42.123' ISO 8601 format
351
352t.hour(); // 23
353t.minute(); // 55
354t.second(); // 42
355t.nano(); // 123000000
356
357// get other time-based fields
358t.get(ChronoField.SECOND_OF_DAY); // 86142
359t.get(ChronoField.MILLI_OF_SECOND); // 123
360t.get(ChronoField.HOUR_OF_AMPM); // 11
361// any other time-based ChronoField is allowed as param for get
362```
363
364### Adding to/ subtracting from a `LocalTime` instance
365
366```javascript
367var t = LocalTime.parse('11:55:42');
368
369// add/subtract 12 hours
370t.plusHours(12); // '23:55:42'
371t.minusHours(12); // '23:55:42'
372
373// add/subtract 30 minutes
374t.plusMinutes(30); // '12:25:42'
375t.minusMinutes(30); // '11:25:42'
376
377// add/subtract 30 seconds
378t.plusSeconds(30); // '11:56:12'
379t.minusSeconds(30); // '11:55:12'
380
381// add/subtract 1 million nanoseconds (1 millisecond)
382t.plusNanos(1000000); // '11:56:42.001'
383t.minusNanos(1000000); // '11:55:41.999'
384
385// add/subtract a time-based unit
386t.plus(1, ChronoUnit.MILLIS); // '11:55:42.001'
387t.plus(1, ChronoUnit.HALF_DAYS); // '23:55:42'
388
389// add/subtract a duration of 15 minutes
390t.plus(Duration.ofMinutes(15)); // '12:10:42'
391t.minus(Duration.ofMinutes(15)); // '11:40:42'
392```
393
394### Alter specific fields of a `LocalTime` instance
395
396```javascript
397var t = LocalTime.parse('11:55:42');
398
399// set the hour of day to 1
400t.withHour(1); // '01:55:42'
401
402// set the minute of hour to 1
403t.withMinute(1); // '11:01:42'
404
405// set the second of minute to 1
406t.withSecond(1); // '11:55:01'
407
408// set the MILLI_OF_SECOND to 51
409t.with(ChronoField.MILLI_OF_SECOND, 51); // '11:55:42.051'
410
411// set by a custom TemporalAdjusters
412// sample of a custom adjuster that adjust to the next even second
413nextEvenSecond = {
414 adjustInto: function(t) {
415 return t.second() % 2 === 0 ? t.plusSeconds(2) : t.plusSeconds(1);
416 },
417};
418t.with(nextEvenSecond); // '11:55:44'
419t.plusSeconds(1).with(nextEvenSecond); // '11:55:44'
420```
421
422### Truncate a `LocalTime` instance
423
424```javascript
425var t = LocalTime.parse('23:55:42.123');
426
427t.truncatedTo(ChronoUnit.SECONDS); // '23:55:42'
428t.truncatedTo(ChronoUnit.MINUTES); // '23:55:00'
429t.truncatedTo(ChronoUnit.HOURS); // '23:00'
430t.truncatedTo(ChronoUnit.HALF_DAYS); // '12:00'
431t.truncatedTo(ChronoUnit.DAYS); // '00:00'
432```
433
434### Compare `LocalTime` instances
435
436```javascript
437var t1 = LocalTime.parse('11:55:42');
438var t2 = t1.plusHours(2);
439
440t1.isAfter(t2); // false
441t1.isBefore(t2); // true
442
443t1.equals(t1.plusHours(0)); // true
444t1.equals(t1.plusHours(1)); // false
445
446t1.compareTo(t1) === 0; // true
447t1.compareTo(t2) < 0; // true
448t2.compareTo(t1) > 0; // true
449
450t1.hashCode(); // 916974646
451t2.hashCode(); // -1743180648
452t1.hashCode() !== t2.hashCode(); // true
453```
454
455### Distance between times
456
457```javascript
458var t1 = LocalTime.parse('11:00');
459var t2 = t1
460 .plusHours(2)
461 .plusMinutes(42)
462 .plusSeconds(12);
463
464// obtain the duration between the two dates
465t1.until(t2, ChronoUnit.HOURS); // 2
466t1.until(t2, ChronoUnit.MINUTES); // 162
467t1.until(t2, ChronoUnit.SECONDS); // 9732
468```
469
470### Convert a `LocalTime` from a `moment` or JavaScript `Date`
471
472```javascript
473// obtain a LocalTime instance from a JavaScript Date
474
475// the manual way
476var t = LocalTime.ofInstant(Instant.ofEpochMilli(new Date().getTime()));
477// the recommended way with the JavaScript temporal
478t = LocalTime.from(nativeJs(new Date()));
479// converting from a `moment` instance works the same way
480d = LocalTime.from(nativeJs(moment()));
481```
482
483## LocalDateTime
484
485A LocalDateTime represents a date-time with **no time zone** in the [ISO-8601](https://en.wikipedia.org/wiki/ISO_8601) calendar system, such as '2007-12-03T10:15:30'.
486
487### Create a `LocalDateTime` instance
488
489```javascript
490// obtain the current date and time in the system default time zone, e.g. '2016-02-26T10:29:05.743'
491LocalDateTime.now();
492
493// obtain the current date and time in the UTC time zone
494LocalDateTime.now(ZoneOffset.UTC);
495
496// obtain an instance of LocalDateTime from an ISO 8601 formatted text string
497LocalDateTime.parse('2016-02-26T09:42'); // '2016-02-26T09:42'
498LocalDateTime.parse('2016-02-26T09:42:42.123'); // '2016-02-26T09:42:42.123'
499
500// obtain an instance of LocalDateTime from year, month, dayOfMonth, hour, minute, second and nanosecond values
501LocalDateTime.of(2016, 2, 29); // '2016-02-29T00:00'
502LocalDateTime.of(2016, 2, 29, 12, 55, 42); // '2016-02-29T12:55:42'
503LocalDateTime.of(2016, 2, 29, 12, 55, 42, 9); // '2016-02-29T12:55:42.000000009'
504
505// obtain an instance of LocalDateTime from epoch seconds and a ZoneOffset
506LocalDateTime.ofEpochSecond(0, ZoneOffset.UTC); // '1970-01-01T00:00'
507LocalDateTime.ofInstant(Instant.now()); // current local date-time
508LocalDateTime.ofInstant(Instant.now(), ZoneOffset.UTC); // current local UTC date-time
509```
510
511### Get values from `LocalDateTime`
512
513```javascript
514var dt = LocalDateTime.parse('2016-02-26T23:55:42.123');
515
516dt.toString(); // '2016-02-26T23:55:42.123' ISO 8601 format
517
518dt.year(); // 2016
519dt.month(); // Month.FEBRUARY
520dt.monthValue(); // 2
521dt.dayOfMonth(); // 26
522dt.hour(); // 23
523dt.minute(); // 55
524dt.second(); // 42
525dt.nano(); // 123000000
526
527dt.dayOfWeek(); // DayOfWeek.FRIDAY
528dt.dayOfWeek().value(); // 5
529dt.dayOfYear(); // 57
530
531dt.toLocalDate().isLeapYear(); // true 2016 is a leap year
532
533// obtain the date and time components of the LocalDateTime
534dt.toLocalDate();
535dt.toLocalTime();
536
537// get range of month
538dt.toLocalDate().lengthOfMonth(); // 29
539dt.range(ChronoField.DAY_OF_MONTH); // ValueRange(1 - 29)
540
541// get range of year
542dt.toLocalDate().lengthOfYear(); // 366
543dt.range(ChronoField.DAY_OF_YEAR); // ValueRange(1 - 366)
544
545// get other date-based fields like the aligned week of year
546dt.get(ChronoField.ALIGNED_WEEK_OF_YEAR); // 9
547
548// get week of week-based year
549dt.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR); // 8
550dt.toLocalDate().isoWeekOfWeekyear();
551
552// get other time-based fields
553dt.get(ChronoField.SECOND_OF_DAY); // 86142
554dt.get(ChronoField.MILLI_OF_SECOND); // 123
555dt.get(ChronoField.HOUR_OF_AMPM); // 11
556// any other date or time-based ChronoField can be passed to `get`
557```
558
559### Adding to and subtracting from a `LocalDateTime` instance
560
561```javascript
562var dt = LocalDateTime.parse('2016-02-26T23:55:42.123');
563
564// add/subtract 366 days
565dt.plusDays(366); // '2017-02-26T23:55:42.123'
566dt.minusDays(366); // '2015-02-25T23:55:42.123'
567
568// add/subtract 12 months
569dt.plusMonths(12); // '2017-02-26'
570dt.minusMonths(12); // '2015-02-26'
571
572// add/subtract 4 weeks
573dt.plusWeeks(4); // '2016-03-25T23:55:42.123'
574dt.minusWeeks(4); // '2016-01-29T23:55:42.123'
575
576// add/subtract 1 year to the parsed LocalDate and returns a new instance
577dt.plusYears(1); // '2017-02-26T23:55:42.123'
578dt.minusYears(1); // '2015-02-26T23:55:42.123'
579
580// add/subtract 30 years
581dt.plus(3, ChronoUnit.DECADES); // '2046-02-26T23:55:42.123'
582dt.minus(3, ChronoUnit.DECADES); // '1986-02-26T23:55:42.123'
583
584// add subtract a Period of 3 Months and 3 Days
585dt.plus(Period.ofMonths(3).plusDays(3)); // '2016-05-29T23:55:42.123'
586dt.minus(Period.ofMonths(3).plusDays(3)); // '2015-11-23T23:55:42.123'
587
588// add/subtract 12 hours
589dt.plusHours(12); // '2016-02-27T11:55:42.123'
590dt.minusHours(12); // '2016-02-26T11:55:42.123'
591
592// add/subtract 30 minutes
593dt.plusMinutes(30); // '2016-02-27T00:25:42.123'
594dt.minusMinutes(30); // '2016-02-26T23:25:42.123'
595
596// add/subtract 30 seconds
597dt.plusSeconds(30); // '2016-02-26T23:56:12.123'
598dt.minusSeconds(30); // '2016-02-26T23:55:12.123'
599
600// add/subtract 1 million nanoseconds (1 millisecond)
601dt.plusNanos(1000000); // '2016-02-26T23:55:42.124'
602dt.minusNanos(1000000); // '2016-02-26T23:55:42.122'
603
604// add/subtract a time-based unit
605dt.plus(1, ChronoUnit.MILLIS); // '2016-02-26T23:55:42.124'
606dt.plus(1, ChronoUnit.HALF_DAYS); // '2016-02-26T11:55:42.123'
607
608// add/subtract a duration of 30 hours and 45 minutes
609dt.plus(Duration.ofHours(30).plusMinutes(45)); // '2016-02-28T06:40:42.123'
610dt.minus(Duration.ofHours(30).plusMinutes(45)); // '2016-02-25T17:10:42.123'
611```
612
613### Alter specific fields of a `LocalDateTime` instance
614
615```javascript
616var dt = LocalDateTime.parse('2016-02-26T23:55:42.123');
617
618// set the hour of day to 1
619dt.withHour(1); // '2016-02-26T01:55:42.123'
620
621// set the minute of hour to 1
622dt.withMinute(1); // '2016-02-26T23:01:42.123'
623
624// set the second of minute to 1
625dt.withSecond(1); // '2016-02-26T23:55:01.123'
626
627// set the nanosecond of second to 1
628dt.withNano(0); // '2016-02-26T23:55:42'
629
630// set the millisecond of second to 51
631dt.with(ChronoField.MILLI_OF_SECOND, 51); // '2016-02-26T23:55:42.051'
632
633// set by a custom TemporalAdjuster that adjusts to the next even second
634var nextEvenSecond = {
635 adjustInto: function(t) {
636 return t.second() % 2 === 0 ? t.plusSeconds(2) : t.plusSeconds(1);
637 },
638};
639dt.with(nextEvenSecond); // '2016-02-26T23:55:44.123'
640dt.plusSeconds(1).with(nextEvenSecond); // '2016-02-26T23:55:44.123'
641```
642
643### Truncate a `LocalDateTime` instance
644
645```javascript
646var dt = LocalDateTime.parse('2016-02-26T23:55:42.123');
647
648dt.truncatedTo(ChronoUnit.SECONDS); // '2016-02-26T23:55:42'
649dt.truncatedTo(ChronoUnit.MINUTES); // '2016-02-26T23:55:00'
650dt.truncatedTo(ChronoUnit.HOURS); // '2016-02-26T23:00'
651dt.truncatedTo(ChronoUnit.HALF_DAYS); // '2016-02-26T12:00'
652dt.truncatedTo(ChronoUnit.DAYS); // '2016-02-26T00:00'
653```
654
655### Compare `LocalDateTime` instances
656
657```javascript
658var dt1 = LocalDateTime.parse('2016-02-26T23:55:42.123');
659var dt2 = dt1.plusHours(2);
660
661dt1.isAfter(dt2); // false
662dt1.isBefore(dt2); // true
663
664dt1.equals(dt1.plusHours(0)); // true
665dt1.equals(dt1.plusHours(1)); // false
666
667dt1.compareTo(dt1) === 0; // true
668dt1.compareTo(dt2) < 0; // true
669dt2.compareTo(dt1) > 0; // true
670
671// Warn! hashCode is equal if in insances are equal, but might be equal for unequal instances as well
672dt1.hashCode(); // -2036645668
673dt2.hashCode(); // 1459191821
674dt1.hashCode() !== dt2.hashCode(); // true
675```
676
677### Distance between two `LocalDateTime` instances
678
679```javascript
680var dt1 = LocalDateTime.parse('2016-02-26T23:55:42.123');
681var dt2 = dt1
682 .plusYears(6)
683 .plusMonths(12)
684 .plusHours(2)
685 .plusMinutes(42)
686 .plusSeconds(12);
687
688// obtain the duration between the two dates
689dt1.until(dt2, ChronoUnit.YEARS); // 7
690dt1.until(dt2, ChronoUnit.MONTHS); // 84
691dt1.until(dt2, ChronoUnit.WEEKS); // 356
692dt1.until(dt2, ChronoUnit.DAYS); // 2557
693dt1.until(dt2, ChronoUnit.HOURS); // 61370
694dt1.until(dt2, ChronoUnit.MINUTES); // 3682242
695dt1.until(dt2, ChronoUnit.SECONDS); // 220934532
696```
697
698### Convert from a `moment` or JavaScript `Date`
699
700```javascript
701// obtain a LocalDateTime instance from a JavaScript Date
702
703// the manual way
704var t = LocalDateTime.ofInstant(
705 Instant.ofEpochMilli(new Date().getTime())
706);
707// the recommended way with the JavaScript temporal
708t = LocalDateTime.from(nativeJs(new Date()));
709// converting from a moment works the same way
710d = LocalDateTime.from(nativeJs(moment()));
711```
712
713## ZonedDateTime
714
715A `ZonedDateTime` represents a date-time with a [time offset](https://en.wikipedia.org/wiki/UTC_offset) and/or a [time zone](https://en.wikipedia.org/wiki/Time_zone) in the [ISO-8601](https://en.wikipedia.org/wiki/ISO_8601) calendar system.
716
717On its own, `ZonedDateTime` only supports specifying **time offsets** such as `UTC` or `UTC+02:00`, plus the `SYSTEM` time zone ID.
718
719### The `SYSTEM` zone ID
720
721The `SYSTEM` zone ID is a non-standard ID that is specific to `js-joda`. It represents the default time zone of the current JavaScript runtime. The JavaScript spec does not provide an API this; it only provides the system default time offset for a point in the timeline (`Date.prototype.getTimezoneOffset()`).
722
723You should not exchange `ZonedDateTime` instances using the `SYSTEM` zone ID between JavaScript environments (e.g. between server and client, or between two servers). The time offset on another machine won't necessarily be the same as yours. Before sending a `ZonedDateTime` to someone else, convert it to a fixed offset:
724
725```javascript
726// current time with default `SYSTEM`
727ZonedDateTime.now().toString(); // e.g. 2016-03-18T12:38:23.561+01:00[SYSTEM]
728
729// converted to a fixed time offset
730ZonedDateTime.now()
731 .withFixedOffsetZone()
732 .toString(); // e.g. 2016-03-18T12:38:23.561+01:00
733```
734
735### Working with time zones
736
737A **time zone** and a **time offset** are [not the same thing](https://en.wikipedia.org/wiki/UTC_offset#Time_zones_and_time_offsets). Some timezones change from standard time to [daylight savings time](https://en.wikipedia.org/wiki/Daylight_saving_time) and back every year:
738
739- In the `Europe/Berlin` _time zone_, the _time offset_ is `UTC+2` during the summer, and `UTC+1` during the rest of the year.
740- In the `Africa/Lagos` _time zone_, on the other hand, the _time offset_ is `UTC+1` all year round.
741
742Calculations that might span time zones or daylight savings transitions need to reference the time zone, not just the offset.
743
744The @js-joda/timezone package provides bindings to the the [IANA tz database](https://www.iana.org/time-zones), making `joda-js`'s calculations time zone aware. The `tz` database uses zone names like `Africa/Bujumbura`, `America/New_York`, and `Europe/Lisbon` (see the [full list](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)).
745
746To specify time zones using these names, you just need to `require` @js-joda/timezone.
747
748```javascript
749var jsJoda = require('@js-joda/core');
750require('@js-joda/timezone');
751
752var zdt = ZonedDateTime.now(ZoneId.of('Europe/Paris'));
753```
754
755### Create a ZonedDateTime
756
757```javascript
758// get now with the default system time zone
759ZonedDateTime.now().toString(); // e.g. 2016-03-18T12:38:23.561+01:00[SYSTEM]
760
761// get now with the UTC time zone
762ZonedDateTime.now(ZoneOffset.UTC).toString(); // e.g. 2016-03-18T11:38:23.561Z
763
764// get now with a fixed offset time zone
765ZonedDateTime.now(ZoneId.of('UTC-05:00')).toString(); // e.g. 2016-03-18T06:38:23.561-05:00[UTC-05:00]
766
767// get now with a ZoneRegion (requires `@js-joda/timezone`)
768ZonedDateTime.now(ZoneId.of('Europe/Paris')).toString(); // e.g. 2017-02-04T17:01:15.846+01:00[Europe/Paris]
769
770// parse a date time with a time zone ISO String
771ZonedDateTime.parse('2016-03-18T12:38:23.561+01:00[SYSTEM]');
772ZonedDateTime.parse('2016-03-18T12:38:23.561+01:00');
773ZonedDateTime.parse('2016-03-18T11:38:23.561Z');
774ZonedDateTime.parse('2016-03-18T06:38:23.561-05:00[UTC-05:00]');
775ZonedDateTime.parse('2017-02-04T17:01:15.846+01:00[Europe/Paris]');
776
777// create from a LocalDate(Time) (requires `@js-joda/timezone`)
778LocalDate.parse('2012-06-06')
779 .atStartOfDay()
780 .atZone(ZoneId.of('Europe/Paris')); // 2012-06-06T00:00+02:00[Europe/Paris]
781ZonedDateTime.of(
782 LocalDateTime.parse('2012-06-06T00:00'),
783 ZoneId.of('Europe/Paris')
784); // 2012-06-06T00:00+02:00[Europe/Paris]
785ZonedDateTime.of(
786 LocalDate.parse('2012-06-06'),
787 LocalTime.MIDNIGHT,
788 ZoneId.of('Europe/Paris')
789); // 2012-06-06T00:00+02:00[Europe/Paris]
790
791// create from an Instant
792ZonedDateTime.ofInstant(Instant.now(), ZoneId.SYSTEM); // current system time
793```
794
795### Switch time zones
796
797> These examples require `@js-joda/timezone`.
798
799```javascript
800var d = LocalDate.of(2016, 3, 18);
801var zdt = d.atTime(LocalTime.NOON).atZone(ZoneId.of('America/New_York')); //2016-03-18T12:00-04:00[America/New_York]
802
803// switch time zone retaining the local date-time if possible
804zdt.withZoneSameLocal(ZoneId.of('Europe/Berlin')); // 2016-03-18T12:00+01:00[Europe/Berlin]
805
806// switch time zone and retain the instant
807zdt.withZoneSameInstant(ZoneId.of('Europe/Berlin')); // 2016-03-18T17:00+01:00[Europe/Berlin]
808```
809
810### Get and manipulate values from a `ZonedDateTime`
811
812`ZonedDateTime` implements the same methods as `LocalDateTime` for getting or setting values. See [the examples above](#get-values-from-localdatetime) for `LocalDateTime`.
813
814### Calculate values across daylight savings transitions
815
816When adding to or subtracting from a `ZonedDateTime` instance, the calculation is different depending on whether date or time units are passed.
817
818- Addition/subtraction of **date units** are made on the **local** timeline.
819- Addition/subtraction of **time units** are made on the **instant** timeline.
820
821This example shows the difference for a daylight saving transition.
822
823```javascript
824// assume the system default time zone is CET; we define a time as 2016-03-18 at 17:00 local time
825var zdt = ZonedDateTime.parse('2016-03-18T17:00+01:00[Europe/Berlin]');
826
827// adding a date unit of 2 weeks, crossing a daylight saving transition
828zdt.plusWeeks(2); // 2016-04-01T17:00+02:00[Europe/Berlin] (still 17:00)
829
830// adding a time unit of 2 weeks (2 * 7 * 24)
831zdt.plusHours(2 * 7 * 24); // 2016-04-01T18:00+02:00[Europe/Berlin] (now 18:00)
832```
833
834## Period
835
836`Period` is a **date-based** amount of time in the ISO-8601 calendar system, such as '2 years, 3 months and 4 days'.
837
838```javascript
839// parse and format ISO 8601 period strings
840Period.parse('P1Y10M').toString(); // 'P1Y10M'
841
842// obtain a Period of 10 years, 5 month and 30 days
843Period.of(10, 5, 30).toString(); // 'P10Y5M30D'
844
845// 10 years
846Period.ofYears(10).toString(); // 'P10Y'
847
848// add 45 days to a Period
849Period.ofYears(10)
850 .plusDays(45)
851 .toString(); // 'P10Y45D'
852
853// normalize a Period of years and month
854Period.of(1, 37, 0)
855 .normalized()
856 .toString(); // 'P4Y1M'
857
858// add/subtract from a Period
859Period.ofYears(10)
860 .plusMonths(10)
861 .minusDays(42)
862 .toString(); // 'P10Y10M-42D'
863
864// add a Period to LocalDate
865var p = Period.ofMonths(1);
866LocalDate.parse('2012-12-12').plus(p); // '2013-01-12';
867LocalDate.parse('2012-01-31').plus(p); // '2012-02-29';
868LocalDateTime.parse('2012-05-31T12:00').plus(p); // '2012-06-30T12:00';
869
870// calculate the Period between two Dates
871Period.between(
872 LocalDate.parse('2012-06-30'),
873 LocalDate.parse('2012-08-31')
874); // 'P2M1D'
875```
876
877## Duration
878
879`Duration` is a **time-based** amount of time, such as '34.5 seconds'.
880
881```javascript
882// obtain a Duration of 10 hours
883Duration.ofHours(10).toString(); // 'PT10H'
884
885// obtain a Duration of 10 days (10 x 24 hours)
886Duration.ofDays(10).toString(); // 'PT240H'
887
888// add/subtract a duration from a LocalDateTime
889var dt = LocalDateTime.parse('2012-12-24T12:00');
890
891dt.plus(Duration.ofHours(10).plusMinutes(30)).toString(); // '2012-12-24T22:30'
892dt.minus(Duration.ofHours(12).multipliedBy(10)).toString(); // '2012-12-19T12:00'
893
894// calculate the durations beetween to time-based temporals
895var dt1 = LocalDateTime.parse('2012-12-24T12:00');
896
897Duration.between(dt1, dt1.plusHours(10)).toString(); // 'PT10H'
898```
899
900## Customizing js-joda
901
902This package is extensible, allowing you to create your own custom temporal calculations. See the temporal interface documentation for more information.
903
904### Custom temporal adjuster
905
906```javascript
907// implement a TemporalAdjuster that the next or same even day of month
908var nextOrSameEvenDay = {
909 adjustInto: function(t) {
910 return t.dayOfMonth() % 2 === 0 ? t : t.plusDays(1);
911 },
912};
913
914LocalDateTime.parse('2012-12-23T12:00').with(nextOrSameEvenDay); // '2012-12-24T12:00'
915LocalDate.parse('2012-12-24').with(nextOrSameEvenDay); // '2012-12-24'
916```
917
918### Custom temporal fields and temporal units
919
920See the source for temporal/IsoFields as an example how to implement custom fields and units. `IsoFields` implements fields and units for an ISO week-based year.
921
922### Custom formatter and queries
923
924The following example implements a parser for a local date with an optional local time. It returns either a `LocalDate` or a `LocalDateTime`, depending on the parsed fields.
925
926```javascript
927// build a custom date time formatter where the time field is optional
928var OPTIONAL_FORMATTER = DateTimeFormatter.ofPattern(
929 'yyyy-MM-dd['T'HH:mm[:ss]]'
930);
931
932// create a temporal query that create a new Temporal depending on the existing fields
933dateOrDateTimeQuery = {
934 queryFrom: function(temporal) {
935 var date = temporal.query(TemporalQueries.localDate());
936 var time = temporal.query(TemporalQueries.localTime());
937 if (time == null) return date;
938 else return date.atTime(time);
939 }
940};
941
942localDate = OPTIONAL_FORMATTER.parse('2012-12-24', dateOrDateTimeQuery);
943localDateTime = OPTIONAL_FORMATTER.parse(
944 '2012-12-24T23:59',
945 dateOrDateTimeQuery
946);
947```