0
# Serialization Support
1
2
This document covers the complete serialization support for all datetime types, including ISO 8601 string serializers, component-based JSON object serializers, and custom format serializers.
3
4
## Overview
5
6
kotlinx-datetime provides comprehensive serialization support through kotlinx.serialization, offering multiple serialization strategies:
7
8
- **ISO 8601 Serializers**: Serialize as standardized ISO strings
9
- **Component Serializers**: Serialize as JSON objects with separate fields
10
- **Custom Format Serializers**: Use custom format patterns for serialization
11
12
## ISO 8601 String Serializers
13
14
These serializers represent datetime values as ISO 8601 standard strings.
15
16
### InstantIso8601Serializer
17
18
```kotlin { .api }
19
object InstantIso8601Serializer : KSerializer<Instant>
20
```
21
22
Serializes `Instant` as ISO 8601 string with UTC timezone.
23
24
```kotlin
25
@Serializable
26
data class Event(
27
@Serializable(with = InstantIso8601Serializer::class)
28
val timestamp: Instant
29
)
30
31
// JSON: {"timestamp": "2023-12-25T14:30:00Z"}
32
```
33
34
### LocalDateIso8601Serializer
35
36
```kotlin { .api }
37
object LocalDateIso8601Serializer : KSerializer<LocalDate>
38
```
39
40
Serializes `LocalDate` as ISO 8601 date string.
41
42
```kotlin
43
@Serializable
44
data class Person(
45
@Serializable(with = LocalDateIso8601Serializer::class)
46
val birthDate: LocalDate
47
)
48
49
// JSON: {"birthDate": "1990-06-15"}
50
```
51
52
### LocalTimeIso8601Serializer
53
54
```kotlin { .api }
55
object LocalTimeIso8601Serializer : KSerializer<LocalTime>
56
```
57
58
Serializes `LocalTime` as ISO 8601 time string.
59
60
```kotlin
61
@Serializable
62
data class Schedule(
63
@Serializable(with = LocalTimeIso8601Serializer::class)
64
val startTime: LocalTime
65
)
66
67
// JSON: {"startTime": "09:30:00"}
68
```
69
70
### LocalDateTimeIso8601Serializer
71
72
```kotlin { .api }
73
object LocalDateTimeIso8601Serializer : KSerializer<LocalDateTime>
74
```
75
76
Serializes `LocalDateTime` as ISO 8601 datetime string.
77
78
```kotlin
79
@Serializable
80
data class Appointment(
81
@Serializable(with = LocalDateTimeIso8601Serializer::class)
82
val scheduledAt: LocalDateTime
83
)
84
85
// JSON: {"scheduledAt": "2023-12-25T14:30:00"}
86
```
87
88
### TimeZoneSerializer
89
90
```kotlin { .api }
91
object TimeZoneSerializer : KSerializer<TimeZone>
92
```
93
94
Serializes `TimeZone` as timezone identifier string.
95
96
```kotlin
97
@Serializable
98
data class Meeting(
99
@Serializable(with = TimeZoneSerializer::class)
100
val timeZone: TimeZone
101
)
102
103
// JSON: {"timeZone": "America/New_York"}
104
```
105
106
### YearMonthIso8601Serializer
107
108
```kotlin { .api }
109
object YearMonthIso8601Serializer : KSerializer<YearMonth>
110
```
111
112
Serializes `YearMonth` as ISO 8601 year-month string.
113
114
```kotlin
115
@Serializable
116
data class Report(
117
@Serializable(with = YearMonthIso8601Serializer::class)
118
val period: YearMonth
119
)
120
121
// JSON: {"period": "2023-12"}
122
```
123
124
### DateTimePeriodIso8601Serializer
125
126
```kotlin { .api }
127
object DateTimePeriodIso8601Serializer : KSerializer<DateTimePeriod>
128
```
129
130
Serializes `DateTimePeriod` as ISO 8601 period string.
131
132
```kotlin
133
@Serializable
134
data class Task(
135
@Serializable(with = DateTimePeriodIso8601Serializer::class)
136
val duration: DateTimePeriod
137
)
138
139
// JSON: {"duration": "P1Y2M3DT4H5M6S"}
140
```
141
142
### DatePeriodIso8601Serializer
143
144
```kotlin { .api }
145
object DatePeriodIso8601Serializer : KSerializer<DatePeriod>
146
```
147
148
Serializes `DatePeriod` as ISO 8601 date period string.
149
150
```kotlin
151
@Serializable
152
data class Vacation(
153
@Serializable(with = DatePeriodIso8601Serializer::class)
154
val length: DatePeriod
155
)
156
157
// JSON: {"length": "P2W"}
158
```
159
160
### MonthIso8601Serializer
161
162
```kotlin { .api }
163
object MonthIso8601Serializer : KSerializer<Month>
164
```
165
166
Serializes `Month` as ISO 8601 month number (1-12).
167
168
```kotlin
169
@Serializable
170
data class SeasonalData(
171
@Serializable(with = MonthIso8601Serializer::class)
172
val month: Month
173
)
174
175
// JSON: {"month": 12}
176
```
177
178
### DayOfWeekSerializer
179
180
```kotlin { .api }
181
object DayOfWeekSerializer : KSerializer<DayOfWeek>
182
```
183
184
Serializes `DayOfWeek` as ISO day number (1-7, Monday=1).
185
186
```kotlin
187
@Serializable
188
data class WeeklySchedule(
189
@Serializable(with = DayOfWeekSerializer::class)
190
val dayOfWeek: DayOfWeek
191
)
192
193
// JSON: {"dayOfWeek": 1}
194
```
195
196
### DateTimeUnitSerializer
197
198
```kotlin { .api }
199
object DateTimeUnitSerializer : KSerializer<DateTimeUnit>
200
```
201
202
Serializes `DateTimeUnit` with appropriate representation based on unit type.
203
204
## Component Serializers
205
206
These serializers represent datetime values as JSON objects with separate fields for each component.
207
208
### LocalDateComponentSerializer
209
210
```kotlin { .api }
211
object LocalDateComponentSerializer : KSerializer<LocalDate>
212
```
213
214
Serializes `LocalDate` as object with year, monthNumber, and dayOfMonth fields.
215
216
```kotlin
217
@Serializable
218
data class Person(
219
@Serializable(with = LocalDateComponentSerializer::class)
220
val birthDate: LocalDate
221
)
222
223
// JSON: {"birthDate": {"year": 1990, "monthNumber": 6, "dayOfMonth": 15}}
224
```
225
226
### LocalTimeComponentSerializer
227
228
```kotlin { .api }
229
object LocalTimeComponentSerializer : KSerializer<LocalTime>
230
```
231
232
Serializes `LocalTime` as object with hour, minute, second, and nanosecond fields.
233
234
```kotlin
235
@Serializable
236
data class Schedule(
237
@Serializable(with = LocalTimeComponentSerializer::class)
238
val startTime: LocalTime
239
)
240
241
// JSON: {"startTime": {"hour": 9, "minute": 30, "second": 0, "nanosecond": 0}}
242
```
243
244
### LocalDateTimeComponentSerializer
245
246
```kotlin { .api }
247
object LocalDateTimeComponentSerializer : KSerializer<LocalDateTime>
248
```
249
250
Serializes `LocalDateTime` as object combining date and time components.
251
252
```kotlin
253
@Serializable
254
data class Event(
255
@Serializable(with = LocalDateTimeComponentSerializer::class)
256
val dateTime: LocalDateTime
257
)
258
259
// JSON: {"dateTime": {"year": 2023, "monthNumber": 12, "dayOfMonth": 25, "hour": 14, "minute": 30, "second": 0, "nanosecond": 0}}
260
```
261
262
### YearMonthComponentSerializer
263
264
```kotlin { .api }
265
object YearMonthComponentSerializer : KSerializer<YearMonth>
266
```
267
268
Serializes `YearMonth` as object with year and monthNumber fields.
269
270
```kotlin
271
@Serializable
272
data class Report(
273
@Serializable(with = YearMonthComponentSerializer::class)
274
val period: YearMonth
275
)
276
277
// JSON: {"period": {"year": 2023, "monthNumber": 12}}
278
```
279
280
### DateTimePeriodComponentSerializer
281
282
```kotlin { .api }
283
object DateTimePeriodComponentSerializer : KSerializer<DateTimePeriod>
284
```
285
286
Serializes `DateTimePeriod` as object with all period components.
287
288
```kotlin
289
@Serializable
290
data class Task(
291
@Serializable(with = DateTimePeriodComponentSerializer::class)
292
val duration: DateTimePeriod
293
)
294
295
// JSON: {"duration": {"years": 1, "months": 2, "days": 3, "hours": 4, "minutes": 5, "seconds": 6, "nanoseconds": 0}}
296
```
297
298
### DatePeriodComponentSerializer
299
300
```kotlin { .api }
301
object DatePeriodComponentSerializer : KSerializer<DatePeriod>
302
```
303
304
Serializes `DatePeriod` as object with date components only.
305
306
```kotlin
307
@Serializable
308
data class Interval(
309
@Serializable(with = DatePeriodComponentSerializer::class)
310
val period: DatePeriod
311
)
312
313
// JSON: {"period": {"years": 0, "months": 6, "days": 15}}
314
```
315
316
## Custom Format Serializers
317
318
Abstract base classes for creating custom format-based serializers.
319
320
### LocalDateFormatSerializer
321
322
```kotlin { .api }
323
abstract class LocalDateFormatSerializer(
324
private val format: DateTimeFormat<LocalDate>
325
) : KSerializer<LocalDate>
326
```
327
328
Base class for custom `LocalDate` serializers using specific formats.
329
330
```kotlin
331
object CustomDateSerializer : LocalDateFormatSerializer(
332
LocalDate.Format {
333
dayOfMonth(Padding.ZERO)
334
char('/')
335
monthNumber(Padding.ZERO)
336
char('/')
337
year()
338
}
339
)
340
341
@Serializable
342
data class Event(
343
@Serializable(with = CustomDateSerializer::class)
344
val date: LocalDate
345
)
346
347
// JSON: {"date": "25/12/2023"}
348
```
349
350
### LocalTimeFormatSerializer
351
352
```kotlin { .api }
353
abstract class LocalTimeFormatSerializer(
354
private val format: DateTimeFormat<LocalTime>
355
) : KSerializer<LocalTime>
356
```
357
358
Base class for custom `LocalTime` serializers using specific formats.
359
360
### LocalDateTimeFormatSerializer
361
362
```kotlin { .api }
363
abstract class LocalDateTimeFormatSerializer(
364
private val format: DateTimeFormat<LocalDateTime>
365
) : KSerializer<LocalDateTime>
366
```
367
368
Base class for custom `LocalDateTime` serializers using specific formats.
369
370
### Other Format Serializers
371
372
Similar abstract base classes are available for:
373
- `YearMonthFormatSerializer`
374
- `UtcOffsetFormatSerializer`
375
- `InstantFormatSerializer`
376
377
## Default Serialization
378
379
When no explicit serializer is specified, datetime types use their default serializers:
380
381
```kotlin { .api }
382
// Default serializers (applied automatically)
383
@Serializable
384
data class Event(
385
val instant: Instant, // Uses InstantIso8601Serializer
386
val date: LocalDate, // Uses LocalDateIso8601Serializer
387
val time: LocalTime, // Uses LocalTimeIso8601Serializer
388
val dateTime: LocalDateTime, // Uses LocalDateTimeIso8601Serializer
389
val timeZone: TimeZone, // Uses TimeZoneSerializer
390
val period: DateTimePeriod, // Uses DateTimePeriodIso8601Serializer
391
val month: Month, // Uses MonthIso8601Serializer
392
val dayOfWeek: DayOfWeek // Uses DayOfWeekSerializer
393
)
394
```
395
396
## Usage Examples
397
398
### Choosing Serialization Strategy
399
400
```kotlin
401
// ISO 8601 strings - compact, standardized, human-readable
402
@Serializable
403
data class EventIso(
404
val name: String,
405
val startTime: Instant, // "2023-12-25T14:30:00Z"
406
val date: LocalDate, // "2023-12-25"
407
val duration: DateTimePeriod // "PT2H30M"
408
)
409
410
// Component objects - explicit fields, easier for API consumers
411
@Serializable
412
data class EventComponents(
413
val name: String,
414
@Serializable(with = LocalDateComponentSerializer::class)
415
val date: LocalDate, // {"year": 2023, "monthNumber": 12, "dayOfMonth": 25}
416
@Serializable(with = DateTimePeriodComponentSerializer::class)
417
val duration: DateTimePeriod // {"hours": 2, "minutes": 30, ...}
418
)
419
420
// Custom format - domain-specific requirements
421
object UsDateSerializer : LocalDateFormatSerializer(
422
LocalDate.Format {
423
monthNumber(Padding.ZERO)
424
char('/')
425
dayOfMonth(Padding.ZERO)
426
char('/')
427
year()
428
}
429
)
430
431
@Serializable
432
data class EventCustom(
433
val name: String,
434
@Serializable(with = UsDateSerializer::class)
435
val date: LocalDate // "12/25/2023"
436
)
437
```
438
439
### Collection Serialization
440
441
```kotlin
442
@Serializable
443
data class Schedule(
444
@Serializable(with = LocalTimeIso8601Serializer::class)
445
val meetings: List<LocalTime>,
446
447
@Serializable(with = DatePeriodComponentSerializer::class)
448
val vacations: Map<String, DatePeriod>
449
)
450
451
val schedule = Schedule(
452
meetings = listOf(LocalTime(9, 0), LocalTime(14, 30)),
453
vacations = mapOf(
454
"summer" to DatePeriod(days = 14),
455
"winter" to DatePeriod(days = 7)
456
)
457
)
458
459
// JSON:
460
// {
461
// "meetings": ["09:00:00", "14:30:00"],
462
// "vacations": {
463
// "summer": {"years": 0, "months": 0, "days": 14},
464
// "winter": {"years": 0, "months": 0, "days": 7}
465
// }
466
// }
467
```
468
469
### Nullable Values
470
471
```kotlin
472
@Serializable
473
data class OptionalEvent(
474
val name: String,
475
val startDate: LocalDate?, // null serializes as null
476
val endDate: LocalDate? = null // default null value
477
)
478
```
479
480
### Polymorphic Serialization
481
482
```kotlin
483
@Serializable
484
sealed class TimeRange {
485
@Serializable
486
data class DateRange(
487
val start: LocalDate,
488
val end: LocalDate
489
) : TimeRange()
490
491
@Serializable
492
data class PeriodRange(
493
@Serializable(with = DatePeriodIso8601Serializer::class)
494
val period: DatePeriod
495
) : TimeRange()
496
}
497
```
498
499
### Integration with REST APIs
500
501
```kotlin
502
// API request/response DTOs
503
@Serializable
504
data class CreateEventRequest(
505
val title: String,
506
val startTime: Instant, // ISO string in JSON
507
val duration: DateTimePeriod, // ISO period string
508
val timeZone: TimeZone // timezone ID string
509
)
510
511
@Serializable
512
data class EventResponse(
513
val id: String,
514
val title: String,
515
@Serializable(with = LocalDateTimeComponentSerializer::class)
516
val localDateTime: LocalDateTime, // Component object for frontend
517
val timeZone: TimeZone
518
)
519
```
520
521
## Error Handling
522
523
```kotlin
524
// Deserialization errors are thrown as SerializationException
525
try {
526
val json = """{"date": "invalid-date"}"""
527
val event = Json.decodeFromString<EventWithDate>(json)
528
} catch (e: SerializationException) {
529
println("Failed to deserialize: ${e.message}")
530
}
531
532
// For graceful error handling, use nullable fields or custom serializers
533
@Serializable
534
data class EventWithOptionalDate(
535
val title: String,
536
val date: LocalDate? = null // Will be null if deserialization fails
537
)
538
```
539
540
## Performance Considerations
541
542
- **ISO 8601 serializers** are most compact for network transmission
543
- **Component serializers** may be larger but are more explicit for API consumers
544
- **Custom format serializers** should be used sparingly as they may not be as well optimized
545
- Consider using `@EncodeDefault` for optional fields with sensible defaults