-
Notifications
You must be signed in to change notification settings - Fork 110
/
Copy pathZonedDateTime.kt
99 lines (77 loc) · 3.88 KB
/
ZonedDateTime.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package kotlinx.datetime
/** A timezone-aware date-time object. */
public sealed class ZonedDateTime(
protected val localDateTime: LocalDateTime,
) : Comparable<ZonedDateTime> {
public abstract val timeZone: TimeZone
// XXX: If the underlying time zone database can change while the current process is running
// this value could become incorrect. Maybe don't cache at all? Or detect time zone db changes?
private val instant: Instant by lazy { localDateTime.toInstant(timeZone) }
public val year: Int get() = localDateTime.year
public val monthNumber: Int get() = localDateTime.monthNumber
public val month: Month get() = localDateTime.month
public val dayOfMonth: Int get() = localDateTime.dayOfMonth
public val dayOfWeek: DayOfWeek get() = localDateTime.dayOfWeek
public val dayOfYear: Int get() = localDateTime.dayOfYear
public val hour: Int get() = localDateTime.hour
public val minute: Int get() = localDateTime.minute
public val second: Int get() = localDateTime.second
public val nanosecond: Int get() = localDateTime.nanosecond
public fun toInstant(): Instant = instant
public fun toLocalDateTime(): LocalDateTime = localDateTime
public fun toLocalDateTime(timeZone: TimeZone): LocalDateTime =
toInstant().toLocalDateTime(timeZone)
public fun toLocalDate(): LocalDate = toLocalDateTime().date
public fun toLocalDate(timeZone: TimeZone): LocalDate = toLocalDateTime(timeZone).date
override fun compareTo(other: ZonedDateTime): Int = toInstant().compareTo(other.toInstant())
override fun equals(other: Any?): Boolean =
this === other || (other is ZonedDateTime && compareTo(other) == 0)
override fun hashCode(): Int = localDateTime.hashCode() xor timeZone.hashCode()
public companion object {
public fun parse(isoString: String): ZonedDateTime {
TODO()
}
}
}
/** Constructs a new [ZonedDateTime] from the given [localDateTime] and [timeZone]. */
public fun ZonedDateTime(localDateTime: LocalDateTime, timeZone: TimeZone): ZonedDateTime =
when (timeZone) {
is FixedOffsetTimeZone -> OffsetDateTime(localDateTime, timeZone)
// TODO: Define a common RegionTimeZone and make TimeZone a sealed class/interface
else -> RegionDateTime(localDateTime, timeZone)
}
public fun String.toZonedDateTime(): ZonedDateTime = ZonedDateTime.parse(this)
/**
* A [ZonedDateTime] describing a region-based [TimeZone].
*
* This class tries to represent how humans think in terms of dates.
* For example, adding one day will result in the same local time even if a DST change happens
* within that day.
* Also, you can safely represent future dates because time zone database changes are taken into
* account.
*/
public class RegionDateTime(
localDateTime: LocalDateTime,
// TODO: this should be a RegionTimeZone
override val timeZone: TimeZone,
// TODO: Add optional DST offset or at least a UTC offset (should it be part of RegionTimeZone?)
) : ZonedDateTime(localDateTime) {
public constructor(instant: Instant, timeZone: TimeZone) :
this(instant.toLocalDateTime(timeZone), timeZone)
// TODO: Should RegionTimeZone.toString() print with surrounding `[]`?
override fun toString(): String = "$localDateTime[$timeZone]"
}
/**
* A [ZonedDateTime] with a [FixedOffsetTimeZone]. Use this only for representing past events.
*
* Don't use this to represent future dates (e.g. in a calendar) because this fails to work
* correctly under time zone database changes. Use [RegionDateTime] instead.
*/
public class OffsetDateTime(
localDateTime: LocalDateTime,
override val timeZone: FixedOffsetTimeZone,
) : ZonedDateTime(localDateTime) {
public constructor(instant: Instant, timeZone: FixedOffsetTimeZone) :
this(instant.toLocalDateTime(timeZone), timeZone)
override fun toString(): String = "$localDateTime$timeZone"
}