@@ -17,58 +17,34 @@ import kotlin.reflect.*
17
17
* A collection of date-time fields, used specifically for parsing and formatting.
18
18
*
19
19
* Its main purpose is to provide support for complex date-time formats that don't correspond to any of the standard
20
- * entities in the library. For example, a format that includes only the month and the day of the month, but not the
21
- * year, can not be represented and parsed as a [LocalDate], but it is valid for a [DateTimeComponents].
22
- *
23
- * Example:
24
- * ```
25
- * val input = "2020-03-16T23:59:59.999999999+03:00"
26
- * val components = DateTimeComponents.Formats.ISO_DATE_TIME_OFFSET.parse(input)
27
- * val localDateTime = components.toLocalDateTime() // LocalDateTime(2020, 3, 16, 23, 59, 59, 999_999_999)
28
- * val instant = components.toInstantUsingOffset() // Instant.parse("2020-03-16T20:59:59.999999999Z")
29
- * val offset = components.toUtcOffset() // UtcOffset(hours = 3)
30
- * ```
20
+ * entities in the library. For example, a format that includes only the month and the day of the month but not the
21
+ * year cannot be represented and parsed as a [LocalDate], but it is valid for a [DateTimeComponents].
22
+ * See sample 1.
31
23
*
32
24
* Another purpose is to support parsing and formatting data with out-of-bounds values. For example, parsing
33
25
* `23:59:60` as a [LocalTime] is not possible, but it is possible to parse it as a [DateTimeComponents], adjust the value by
34
26
* setting [second] to `59`, and then convert it to a [LocalTime] via [toLocalTime].
35
- *
36
- * Example:
37
- * ```
38
- * val input = "23:59:60"
39
- * val extraDay: Boolean
40
- * val time = DateTimeComponents.Format {
41
- * time(LocalTime.Formats.ISO)
42
- * }.parse(input).apply {
43
- * if (hour == 23 && minute == 59 && second == 60) {
44
- * hour = 0; minute = 0; second = 0; extraDay = true
45
- * } else {
46
- * extraDay = false
47
- * }
48
- * }.toLocalTime()
49
- * ```
27
+ * See sample 2.
50
28
*
51
29
* Because this class has limited applications, constructing it directly is not possible.
52
30
* For formatting, use the [format] overload that accepts a lambda with a [DateTimeComponents] receiver.
53
- *
54
- * Example:
55
- * ```
56
- * // Mon, 16 Mar 2020 23:59:59 +0300
57
- * DateTimeComponents.Formats.RFC_1123.format {
58
- * setDateTimeOffset(LocalDateTime(2020, 3, 16, 23, 59, 59, 999_999_999))
59
- * setDateTimeOffset(UtcOffset(hours = 3))
60
- * }
61
- * ```
31
+ * See sample 3.
62
32
*
63
33
* Accessing the fields of this class is not thread-safe.
64
34
* Make sure to apply proper synchronization if you are using a single instance from multiple threads.
35
+ *
36
+ * @sample kotlinx.datetime.test.samples.format.DateTimeComponentsSamples.parsingComplexInput
37
+ * @sample kotlinx.datetime.test.samples.format.DateTimeComponentsSamples.parsingInvalidInput
38
+ * @sample kotlinx.datetime.test.samples.format.DateTimeComponentsSamples.simpleFormatting
65
39
*/
66
40
public class DateTimeComponents internal constructor(internal val contents : DateTimeComponentsContents = DateTimeComponentsContents ()) {
67
41
public companion object {
68
42
/* *
69
43
* Creates a [DateTimeFormat] for [DateTimeComponents] values using [DateTimeFormatBuilder.WithDateTimeComponents].
70
44
*
71
45
* There is a collection of predefined formats in [DateTimeComponents.Formats].
46
+ *
47
+ * @sample kotlinx.datetime.test.samples.format.DateTimeComponentsSamples.customFormat
72
48
*/
73
49
@Suppress(" FunctionName" )
74
50
public fun Format (block : DateTimeFormatBuilder .WithDateTimeComponents .() -> Unit ): DateTimeFormat <DateTimeComponents > {
@@ -120,6 +96,8 @@ public class DateTimeComponents internal constructor(internal val contents: Date
120
96
* val localDateTime = components.toLocalDateTime() // 2020-08-30T18:43:00.123456789
121
97
* val offset = components.toUtcOffset() // UtcOffset(hours = 3)
122
98
* ```
99
+ *
100
+ * @sample kotlinx.datetime.test.samples.format.DateTimeComponentsSamples.Formats.iso
123
101
*/
124
102
public val ISO_DATE_TIME_OFFSET : DateTimeFormat <DateTimeComponents > = Format {
125
103
date(ISO_DATE )
@@ -153,6 +131,9 @@ public class DateTimeComponents internal constructor(internal val contents: Date
153
131
* * `30 Jun 2008 11:05:30 UT`
154
132
*
155
133
* North American and military time zone abbreviations are not supported.
134
+ *
135
+ * @sample kotlinx.datetime.test.samples.format.DateTimeComponentsSamples.Formats.rfc1123parsing
136
+ * @sample kotlinx.datetime.test.samples.format.DateTimeComponentsSamples.Formats.rfc1123formatting
156
137
*/
157
138
public val RFC_1123 : DateTimeFormat <DateTimeComponents > = Format {
158
139
alternativeParsing({
@@ -192,6 +173,8 @@ public class DateTimeComponents internal constructor(internal val contents: Date
192
173
* The [localTime] is written to the [hour], [hourOfAmPm], [amPm], [minute], [second] and [nanosecond] fields.
193
174
*
194
175
* If any of the fields are already set, they will be overwritten.
176
+ *
177
+ * @sample kotlinx.datetime.test.samples.format.DateTimeComponentsSamples.time
195
178
*/
196
179
public fun setTime (localTime : LocalTime ) {
197
180
contents.time.populateFrom(localTime)
@@ -202,6 +185,8 @@ public class DateTimeComponents internal constructor(internal val contents: Date
202
185
* The [localDate] is written to the [year], [monthNumber], [dayOfMonth], and [dayOfWeek] fields.
203
186
*
204
187
* If any of the fields are already set, they will be overwritten.
188
+ *
189
+ * @sample kotlinx.datetime.test.samples.format.DateTimeComponentsSamples.date
205
190
*/
206
191
public fun setDate (localDate : LocalDate ) {
207
192
contents.date.populateFrom(localDate)
@@ -214,6 +199,8 @@ public class DateTimeComponents internal constructor(internal val contents: Date
214
199
* [hour], [hourOfAmPm], [amPm], [minute], [second] and [nanosecond] fields.
215
200
*
216
201
* If any of the fields are already set, they will be overwritten.
202
+ *
203
+ * @sample kotlinx.datetime.test.samples.format.DateTimeComponentsSamples.setDateTime
217
204
*/
218
205
public fun setDateTime (localDateTime : LocalDateTime ) {
219
206
contents.date.populateFrom(localDateTime.date)
@@ -226,6 +213,8 @@ public class DateTimeComponents internal constructor(internal val contents: Date
226
213
* [offsetIsNegative] fields.
227
214
*
228
215
* If any of the fields are already set, they will be overwritten.
216
+ *
217
+ * @sample kotlinx.datetime.test.samples.format.DateTimeComponentsSamples.offset
229
218
*/
230
219
public fun setOffset (utcOffset : UtcOffset ) {
231
220
contents.offset.populateFrom(utcOffset)
@@ -242,6 +231,8 @@ public class DateTimeComponents internal constructor(internal val contents: Date
242
231
* However, this also works for instants that are too large to be represented as a [LocalDateTime].
243
232
*
244
233
* If any of the fields are already set, they will be overwritten.
234
+ *
235
+ * @sample kotlinx.datetime.test.samples.format.DateTimeComponentsSamples.setDateTimeOffsetInstant
245
236
*/
246
237
public fun setDateTimeOffset (instant : Instant , utcOffset : UtcOffset ) {
247
238
val smallerInstant = Instant .fromEpochSeconds(
@@ -259,24 +250,31 @@ public class DateTimeComponents internal constructor(internal val contents: Date
259
250
*
260
251
* If [localDateTime] is obtained from an [Instant] using [LocalDateTime.toInstant], it is recommended to use
261
252
* [setDateTimeOffset] that accepts an [Instant] directly.
253
+ *
254
+ * @sample kotlinx.datetime.test.samples.format.DateTimeComponentsSamples.setDateTimeOffset
262
255
*/
263
256
public fun setDateTimeOffset (localDateTime : LocalDateTime , utcOffset : UtcOffset ) {
264
257
setDateTime(localDateTime)
265
258
setOffset(utcOffset)
266
259
}
267
260
268
- /* * The year component of the date. */
261
+ /* *
262
+ * The year component of the date.
263
+ * @sample kotlinx.datetime.test.samples.format.DateTimeComponentsSamples.date
264
+ */
269
265
public var year: Int? by contents.date::year
270
266
271
267
/* *
272
268
* The number-of-month (1..12) component of the date.
273
269
* @throws IllegalArgumentException during assignment if the value is outside the `0..99` range.
270
+ * @sample kotlinx.datetime.test.samples.format.DateTimeComponentsSamples.date
274
271
*/
275
272
public var monthNumber: Int? by TwoDigitNumber (contents.date::monthNumber)
276
273
277
274
/* *
278
275
* The month ([Month]) component of the date.
279
276
* @throws IllegalArgumentException during getting if [monthNumber] is outside the `1..12` range.
277
+ * @sample kotlinx.datetime.test.samples.format.DateTimeComponentsSamples.date
280
278
*/
281
279
public var month: Month ?
282
280
get() = monthNumber?.let { Month (it) }
@@ -287,10 +285,14 @@ public class DateTimeComponents internal constructor(internal val contents: Date
287
285
/* *
288
286
* The day-of-month component of the date.
289
287
* @throws IllegalArgumentException during assignment if the value is outside the `0..99` range.
288
+ * @sample kotlinx.datetime.test.samples.format.DateTimeComponentsSamples.date
290
289
*/
291
290
public var dayOfMonth: Int? by TwoDigitNumber (contents.date::dayOfMonth)
292
291
293
- /* * The day-of-week component of the date. */
292
+ /* *
293
+ * The day-of-week component of the date.
294
+ * @sample kotlinx.datetime.test.samples.format.DateTimeComponentsSamples.dayOfWeek
295
+ */
294
296
public var dayOfWeek: DayOfWeek ?
295
297
get() = contents.date.isoDayOfWeek?.let { DayOfWeek (it) }
296
298
set(value) {
@@ -302,37 +304,43 @@ public class DateTimeComponents internal constructor(internal val contents: Date
302
304
/* *
303
305
* The hour-of-day (0..23) time component.
304
306
* @throws IllegalArgumentException during assignment if the value is outside the `0..99` range.
307
+ * @sample kotlinx.datetime.test.samples.format.DateTimeComponentsSamples.time
305
308
*/
306
309
public var hour: Int? by TwoDigitNumber (contents.time::hour)
307
310
308
311
/* *
309
312
* The 12-hour (1..12) time component.
310
313
* @throws IllegalArgumentException during assignment if the value is outside the `0..99` range.
311
314
* @see amPm
315
+ * @sample kotlinx.datetime.test.samples.format.DateTimeComponentsSamples.timeAmPm
312
316
*/
313
317
public var hourOfAmPm: Int? by TwoDigitNumber (contents.time::hourOfAmPm)
314
318
315
319
/* *
316
320
* The AM/PM state of the time component.
317
321
* @see hourOfAmPm
322
+ * @sample kotlinx.datetime.test.samples.format.DateTimeComponentsSamples.timeAmPm
318
323
*/
319
324
public var amPm: AmPmMarker ? by contents.time::amPm
320
325
321
326
/* *
322
327
* The minute-of-hour component.
323
328
* @throws IllegalArgumentException during assignment if the value is outside the `0..99` range.
329
+ * @sample kotlinx.datetime.test.samples.format.DateTimeComponentsSamples.time
324
330
*/
325
331
public var minute: Int? by TwoDigitNumber (contents.time::minute)
326
332
327
333
/* *
328
334
* The second-of-minute component.
329
335
* @throws IllegalArgumentException during assignment if the value is outside the `0..99` range.
336
+ * @sample kotlinx.datetime.test.samples.format.DateTimeComponentsSamples.time
330
337
*/
331
338
public var second: Int? by TwoDigitNumber (contents.time::second)
332
339
333
340
/* *
334
341
* The nanosecond-of-second component.
335
342
* @throws IllegalArgumentException during assignment if the value is outside the `0..999_999_999` range.
343
+ * @sample kotlinx.datetime.test.samples.format.DateTimeComponentsSamples.time
336
344
*/
337
345
public var nanosecond: Int?
338
346
get() = contents.time.nanosecond
@@ -343,28 +351,37 @@ public class DateTimeComponents internal constructor(internal val contents: Date
343
351
contents.time.nanosecond = value
344
352
}
345
353
346
- /* * True if the offset is negative. */
354
+ /* *
355
+ * True if the offset is negative.
356
+ * @sample kotlinx.datetime.test.samples.format.DateTimeComponentsSamples.offset
357
+ */
347
358
public var offsetIsNegative: Boolean? by contents.offset::isNegative
348
359
349
360
/* *
350
361
* The total amount of full hours in the UTC offset, in the range [0; 18].
351
362
* @throws IllegalArgumentException during assignment if the value is outside the `0..99` range.
363
+ * @sample kotlinx.datetime.test.samples.format.DateTimeComponentsSamples.offset
352
364
*/
353
365
public var offsetHours: Int? by TwoDigitNumber (contents.offset::totalHoursAbs)
354
366
355
367
/* *
356
368
* The amount of minutes that don't add to a whole hour in the UTC offset, in the range [0; 59].
357
369
* @throws IllegalArgumentException during assignment if the value is outside the `0..99` range.
370
+ * @sample kotlinx.datetime.test.samples.format.DateTimeComponentsSamples.offset
358
371
*/
359
372
public var offsetMinutesOfHour: Int? by TwoDigitNumber (contents.offset::minutesOfHour)
360
373
361
374
/* *
362
375
* The amount of seconds that don't add to a whole minute in the UTC offset, in the range [0; 59].
363
376
* @throws IllegalArgumentException during assignment if the value is outside the `0..99` range.
377
+ * @sample kotlinx.datetime.test.samples.format.DateTimeComponentsSamples.offset
364
378
*/
365
379
public var offsetSecondsOfMinute: Int? by TwoDigitNumber (contents.offset::secondsOfMinute)
366
380
367
- /* * The timezone identifier, for example, "Europe/Berlin". */
381
+ /* *
382
+ * The timezone identifier, for example, "Europe/Berlin".
383
+ * @sample kotlinx.datetime.test.samples.format.DateTimeComponentsSamples.timeZoneId
384
+ */
368
385
public var timeZoneId: String? by contents::timeZoneId
369
386
370
387
/* *
@@ -377,6 +394,7 @@ public class DateTimeComponents internal constructor(internal val contents: Date
377
394
* * [offsetSecondsOfMinute] (default value is 0)
378
395
*
379
396
* @throws IllegalArgumentException if any of the fields has an out-of-range value.
397
+ * @sample kotlinx.datetime.test.samples.format.DateTimeComponentsSamples.toUtcOffset
380
398
*/
381
399
public fun toUtcOffset (): UtcOffset = contents.offset.toUtcOffset()
382
400
@@ -391,6 +409,7 @@ public class DateTimeComponents internal constructor(internal val contents: Date
391
409
* Also, [dayOfWeek] is checked for consistency with the other fields.
392
410
*
393
411
* @throws IllegalArgumentException if any of the fields is missing or invalid.
412
+ * @sample kotlinx.datetime.test.samples.format.DateTimeComponentsSamples.toLocalDate
394
413
*/
395
414
public fun toLocalDate (): LocalDate = contents.date.toLocalDate()
396
415
@@ -405,6 +424,7 @@ public class DateTimeComponents internal constructor(internal val contents: Date
405
424
*
406
425
* @throws IllegalArgumentException if hours or minutes are not present, if any of the fields are invalid, or
407
426
* [hourOfAmPm] and [amPm] are inconsistent with [hour].
427
+ * @sample kotlinx.datetime.test.samples.format.DateTimeComponentsSamples.toLocalTime
408
428
*/
409
429
public fun toLocalTime (): LocalTime = contents.time.toLocalTime()
410
430
@@ -427,6 +447,7 @@ public class DateTimeComponents internal constructor(internal val contents: Date
427
447
*
428
448
* @see toLocalDate
429
449
* @see toLocalTime
450
+ * @sample kotlinx.datetime.test.samples.format.DateTimeComponentsSamples.toLocalDateTime
430
451
*/
431
452
public fun toLocalDateTime (): LocalDateTime = toLocalDate().atTime(toLocalTime())
432
453
@@ -440,6 +461,7 @@ public class DateTimeComponents internal constructor(internal val contents: Date
440
461
*
441
462
* @throws IllegalArgumentException if any of the required fields are not present, out-of-range, or inconsistent
442
463
* with one another.
464
+ * @sample kotlinx.datetime.test.samples.format.DateTimeComponentsSamples.toInstantUsingOffset
443
465
*/
444
466
public fun toInstantUsingOffset (): Instant {
445
467
val offset = toUtcOffset()
@@ -482,6 +504,7 @@ public class DateTimeComponents internal constructor(internal val contents: Date
482
504
* @throws IllegalStateException if some values needed for the format are not present or can not be formatted:
483
505
* for example, trying to format [DateTimeFormatBuilder.WithDate.monthName] using a [DateTimeComponents.monthNumber]
484
506
* value of 20.
507
+ * @sample kotlinx.datetime.test.samples.format.DateTimeComponentsSamples.formatting
485
508
*/
486
509
public fun DateTimeFormat<DateTimeComponents>.format (block : DateTimeComponents .() -> Unit ): String =
487
510
format(DateTimeComponents ().apply { block() })
@@ -494,6 +517,7 @@ public fun DateTimeFormat<DateTimeComponents>.format(block: DateTimeComponents.(
494
517
* matches.
495
518
*
496
519
* @throws IllegalArgumentException if the text does not match the format.
520
+ * @sample kotlinx.datetime.test.samples.format.DateTimeComponentsSamples.parsing
497
521
*/
498
522
public fun DateTimeComponents.Companion.parse (
499
523
input : CharSequence ,
0 commit comments