Skip to content

Commit e25718a

Browse files
committed
Define the API for building a date-time-based format
1 parent ba99d81 commit e25718a

File tree

2 files changed

+100
-0
lines changed

2 files changed

+100
-0
lines changed

core/common/src/format/DateTimeFormatBuilder.kt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,21 @@ public sealed interface DateTimeFormatBuilder {
201201
public fun time(format: DateTimeFormat<LocalTime>)
202202
}
203203

204+
/**
205+
* Functions specific to the date-time format builders containing the local-date and local-time fields.
206+
*/
207+
public sealed interface WithDateTime : WithDate, WithTime {
208+
/**
209+
* An existing [DateTimeFormat] for the date-time part.
210+
*
211+
* Example:
212+
* ```
213+
* dateTime(LocalDateTime.Formats.ISO)
214+
* ```
215+
*/
216+
public fun dateTime(format: DateTimeFormat<LocalDateTime>)
217+
}
218+
204219
/**
205220
* Functions specific to the date-time format builders containing the UTC-offset fields.
206221
*/
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
* Copyright 2019-2023 JetBrains s.r.o. and contributors.
3+
* Use of this source code is governed by the Apache 2.0 License that can be found in the LICENSE.txt file.
4+
*/
5+
6+
package kotlinx.datetime.format
7+
8+
import kotlinx.datetime.*
9+
import kotlinx.datetime.internal.format.*
10+
import kotlinx.datetime.internal.format.parser.Copyable
11+
12+
internal interface DateTimeFieldContainer : DateFieldContainer, TimeFieldContainer
13+
14+
internal class IncompleteLocalDateTime(
15+
val date: IncompleteLocalDate = IncompleteLocalDate(),
16+
val time: IncompleteLocalTime = IncompleteLocalTime(),
17+
) : DateTimeFieldContainer, DateFieldContainer by date, TimeFieldContainer by time, Copyable<IncompleteLocalDateTime> {
18+
fun toLocalDateTime(): LocalDateTime = LocalDateTime(date.toLocalDate(), time.toLocalTime())
19+
20+
fun populateFrom(dateTime: LocalDateTime) {
21+
date.populateFrom(dateTime.date)
22+
time.populateFrom(dateTime.time)
23+
}
24+
25+
override fun copy(): IncompleteLocalDateTime = IncompleteLocalDateTime(date.copy(), time.copy())
26+
}
27+
28+
internal class LocalDateTimeFormat(override val actualFormat: CachedFormatStructure<DateTimeFieldContainer>) :
29+
AbstractDateTimeFormat<LocalDateTime, IncompleteLocalDateTime>() {
30+
override fun intermediateFromValue(value: LocalDateTime): IncompleteLocalDateTime =
31+
IncompleteLocalDateTime().apply { populateFrom(value) }
32+
33+
override fun valueFromIntermediate(intermediate: IncompleteLocalDateTime): LocalDateTime =
34+
intermediate.toLocalDateTime()
35+
36+
override val emptyIntermediate: IncompleteLocalDateTime get() = emptyIncompleteLocalDateTime
37+
38+
companion object {
39+
fun build(block: DateTimeFormatBuilder.WithDateTime.() -> Unit): LocalDateTimeFormat {
40+
val builder = Builder(AppendableFormatStructure())
41+
builder.block()
42+
return LocalDateTimeFormat(builder.build())
43+
}
44+
}
45+
46+
internal class Builder(override val actualBuilder: AppendableFormatStructure<DateTimeFieldContainer>) :
47+
AbstractDateTimeFormatBuilder<DateTimeFieldContainer, Builder>, AbstractWithDateTimeBuilder {
48+
49+
override fun addFormatStructureForDateTime(structure: FormatStructure<DateTimeFieldContainer>) {
50+
actualBuilder.add(structure)
51+
}
52+
53+
override fun createEmpty(): Builder = Builder(AppendableFormatStructure())
54+
}
55+
}
56+
57+
internal interface AbstractWithDateTimeBuilder:
58+
AbstractWithDateBuilder, AbstractWithTimeBuilder, DateTimeFormatBuilder.WithDateTime
59+
{
60+
fun addFormatStructureForDateTime(structure: FormatStructure<DateTimeFieldContainer>)
61+
62+
override fun addFormatStructureForDate(structure: FormatStructure<DateFieldContainer>) {
63+
addFormatStructureForDateTime(structure)
64+
}
65+
66+
override fun addFormatStructureForTime(structure: FormatStructure<TimeFieldContainer>) {
67+
addFormatStructureForDateTime(structure)
68+
}
69+
70+
@Suppress("NO_ELSE_IN_WHEN")
71+
override fun dateTime(format: DateTimeFormat<LocalDateTime>) = when (format) {
72+
is LocalDateTimeFormat -> addFormatStructureForDateTime(format.actualFormat)
73+
}
74+
}
75+
76+
// these are constants so that the formats are not recreated every time they are used
77+
internal val ISO_DATETIME by lazy {
78+
LocalDateTimeFormat.build {
79+
date(ISO_DATE)
80+
alternativeParsing({ char('t') }) { char('T') }
81+
time(ISO_TIME)
82+
}
83+
}
84+
85+
private val emptyIncompleteLocalDateTime = IncompleteLocalDateTime()

0 commit comments

Comments
 (0)