Skip to content

Commit 4177ff2

Browse files
committed
Remove extra hierarchy level in DateTimeUnit sealed class inheritors
1 parent 44b8ee3 commit 4177ff2

File tree

9 files changed

+84
-77
lines changed

9 files changed

+84
-77
lines changed

core/common/src/DateTimeUnit.kt

Lines changed: 42 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -66,44 +66,51 @@ public sealed class DateTimeUnit {
6666

6767
@Serializable(with = DateBasedDateTimeUnitSerializer::class)
6868
public sealed class DateBased : DateTimeUnit() {
69-
// TODO: investigate how to move subclasses up to DateTimeUnit scope
70-
@Serializable(with = DayBasedDateTimeUnitSerializer::class)
71-
public class DayBased(public val days: Int) : DateBased() {
72-
init {
73-
require(days > 0) { "Unit duration must be positive, but was $days days." }
74-
}
69+
@Suppress("TOPLEVEL_TYPEALIASES_ONLY")
70+
@Deprecated("Use DateTimeUnit.DayBased", ReplaceWith("DateTimeUnit.DayBased", "kotlinx.datetime.DateTimeUnit"))
71+
public typealias DayBased = DateTimeUnit.DayBased
72+
@Suppress("TOPLEVEL_TYPEALIASES_ONLY")
73+
@Deprecated("Use DateTimeUnit.MonthBased", ReplaceWith("DateTimeUnit.MonthBased", "kotlinx.datetime.DateTimeUnit"))
74+
public typealias MonthBased = DateTimeUnit.MonthBased
75+
}
76+
77+
@Serializable(with = DayBasedDateTimeUnitSerializer::class)
78+
public class DayBased(public val days: Int) : DateBased() {
79+
init {
80+
require(days > 0) { "Unit duration must be positive, but was $days days." }
81+
}
82+
83+
override fun times(scalar: Int): DateTimeUnit.DayBased = DateTimeUnit.DayBased(safeMultiply(days, scalar))
7584

76-
override fun times(scalar: Int): DayBased = DayBased(safeMultiply(days, scalar))
85+
override fun equals(other: Any?): Boolean =
86+
this === other || (other is DateTimeUnit.DayBased && this.days == other.days)
7787

78-
override fun equals(other: Any?): Boolean =
79-
this === other || (other is DayBased && this.days == other.days)
88+
override fun hashCode(): Int = days xor 0x10000
8089

81-
override fun hashCode(): Int = days xor 0x10000
90+
override fun toString(): String = if (days % 7 == 0)
91+
formatToString(days / 7, "WEEK")
92+
else
93+
formatToString(days, "DAY")
94+
}
8295

83-
override fun toString(): String = if (days % 7 == 0)
84-
formatToString(days / 7, "WEEK")
85-
else
86-
formatToString(days, "DAY")
96+
@Serializable(with = MonthBasedDateTimeUnitSerializer::class)
97+
public class MonthBased(public val months: Int) : DateBased() {
98+
init {
99+
require(months > 0) { "Unit duration must be positive, but was $months months." }
87100
}
88-
@Serializable(with = MonthBasedDateTimeUnitSerializer::class)
89-
public class MonthBased(public val months: Int) : DateBased() {
90-
init {
91-
require(months > 0) { "Unit duration must be positive, but was $months months." }
92-
}
93101

94-
override fun times(scalar: Int): MonthBased = MonthBased(safeMultiply(months, scalar))
102+
override fun times(scalar: Int): DateTimeUnit.MonthBased = DateTimeUnit.MonthBased(safeMultiply(months, scalar))
95103

96-
override fun equals(other: Any?): Boolean =
97-
this === other || (other is MonthBased && this.months == other.months)
104+
override fun equals(other: Any?): Boolean =
105+
this === other || (other is DateTimeUnit.MonthBased && this.months == other.months)
98106

99-
override fun hashCode(): Int = months xor 0x20000
107+
override fun hashCode(): Int = months xor 0x20000
100108

101-
override fun toString(): String = when {
102-
months % 12_00 == 0 -> formatToString(months / 12_00, "CENTURY")
103-
months % 12 == 0 -> formatToString(months / 12, "YEAR")
104-
months % 3 == 0 -> formatToString(months / 3, "QUARTER")
105-
else -> formatToString(months, "MONTH")
106-
}
109+
override fun toString(): String = when {
110+
months % 12_00 == 0 -> formatToString(months / 12_00, "CENTURY")
111+
months % 12 == 0 -> formatToString(months / 12, "YEAR")
112+
months % 3 == 0 -> formatToString(months / 3, "QUARTER")
113+
else -> formatToString(months, "MONTH")
107114
}
108115
}
109116

@@ -117,11 +124,11 @@ public sealed class DateTimeUnit {
117124
public val SECOND: TimeBased = MILLISECOND * 1000
118125
public val MINUTE: TimeBased = SECOND * 60
119126
public val HOUR: TimeBased = MINUTE * 60
120-
public val DAY: DateBased.DayBased = DateBased.DayBased(days = 1)
121-
public val WEEK: DateBased.DayBased = DAY * 7
122-
public val MONTH: DateBased.MonthBased = DateBased.MonthBased(months = 1)
123-
public val QUARTER: DateBased.MonthBased = MONTH * 3
124-
public val YEAR: DateBased.MonthBased = MONTH * 12
125-
public val CENTURY: DateBased.MonthBased = YEAR * 100
127+
public val DAY: DayBased = DayBased(days = 1)
128+
public val WEEK: DayBased = DAY * 7
129+
public val MONTH: MonthBased = MonthBased(months = 1)
130+
public val QUARTER: MonthBased = MONTH * 3
131+
public val YEAR: MonthBased = MONTH * 12
132+
public val CENTURY: MonthBased = YEAR * 100
126133
}
127134
}

core/common/src/serializers/DateTimeUnitSerializers.kt

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -53,21 +53,21 @@ public object TimeBasedDateTimeUnitSerializer: KSerializer<DateTimeUnit.TimeBase
5353
}
5454
}
5555

56-
public object DayBasedDateTimeUnitSerializer: KSerializer<DateTimeUnit.DateBased.DayBased> {
56+
public object DayBasedDateTimeUnitSerializer: KSerializer<DateTimeUnit.DayBased> {
5757

5858
override val descriptor: SerialDescriptor = buildClassSerialDescriptor("DayBased") {
5959
element<Int>("days")
6060
}
6161

62-
override fun serialize(encoder: Encoder, value: DateTimeUnit.DateBased.DayBased) {
62+
override fun serialize(encoder: Encoder, value: DateTimeUnit.DayBased) {
6363
encoder.encodeStructure(descriptor) {
6464
encodeIntElement(descriptor, 0, value.days)
6565
}
6666
}
6767

6868
@ExperimentalSerializationApi
6969
@Suppress("INVISIBLE_MEMBER") // to be able to throw `MissingFieldException`
70-
override fun deserialize(decoder: Decoder): DateTimeUnit.DateBased.DayBased {
70+
override fun deserialize(decoder: Decoder): DateTimeUnit.DayBased {
7171
var seen = false
7272
var days = 0
7373
decoder.decodeStructure(descriptor) {
@@ -88,25 +88,25 @@ public object DayBasedDateTimeUnitSerializer: KSerializer<DateTimeUnit.DateBased
8888
}
8989
}
9090
if (!seen) throw MissingFieldException("days")
91-
return DateTimeUnit.DateBased.DayBased(days)
91+
return DateTimeUnit.DayBased(days)
9292
}
9393
}
9494

95-
public object MonthBasedDateTimeUnitSerializer: KSerializer<DateTimeUnit.DateBased.MonthBased> {
95+
public object MonthBasedDateTimeUnitSerializer: KSerializer<DateTimeUnit.MonthBased> {
9696

9797
override val descriptor: SerialDescriptor = buildClassSerialDescriptor("MonthBased") {
9898
element<Int>("months")
9999
}
100100

101-
override fun serialize(encoder: Encoder, value: DateTimeUnit.DateBased.MonthBased) {
101+
override fun serialize(encoder: Encoder, value: DateTimeUnit.MonthBased) {
102102
encoder.encodeStructure(descriptor) {
103103
encodeIntElement(descriptor, 0, value.months)
104104
}
105105
}
106106

107107
@ExperimentalSerializationApi
108108
@Suppress("INVISIBLE_MEMBER") // to be able to throw `MissingFieldException`
109-
override fun deserialize(decoder: Decoder): DateTimeUnit.DateBased.MonthBased {
109+
override fun deserialize(decoder: Decoder): DateTimeUnit.MonthBased {
110110
var seen = false
111111
var months = 0
112112
decoder.decodeStructure(descriptor) {
@@ -127,7 +127,7 @@ public object MonthBasedDateTimeUnitSerializer: KSerializer<DateTimeUnit.DateBas
127127
}
128128
}
129129
if (!seen) throw MissingFieldException("months")
130-
return DateTimeUnit.DateBased.MonthBased(months)
130+
return DateTimeUnit.MonthBased(months)
131131
}
132132
}
133133

@@ -136,7 +136,7 @@ public object DateBasedDateTimeUnitSerializer: AbstractPolymorphicSerializer<Dat
136136

137137
private val impl = SealedClassSerializer("kotlinx.datetime.DateTimeUnit.DateBased",
138138
DateTimeUnit.DateBased::class,
139-
arrayOf(DateTimeUnit.DateBased.DayBased::class, DateTimeUnit.DateBased.MonthBased::class),
139+
arrayOf(DateTimeUnit.DayBased::class, DateTimeUnit.MonthBased::class),
140140
arrayOf(DayBasedDateTimeUnitSerializer, MonthBasedDateTimeUnitSerializer))
141141

142142
@InternalSerializationApi
@@ -164,7 +164,7 @@ public object DateTimeUnitSerializer: AbstractPolymorphicSerializer<DateTimeUnit
164164

165165
private val impl = SealedClassSerializer("kotlinx.datetime.DateTimeUnit",
166166
DateTimeUnit::class,
167-
arrayOf(DateTimeUnit.DateBased.DayBased::class, DateTimeUnit.DateBased.MonthBased::class, DateTimeUnit.TimeBased::class),
167+
arrayOf(DateTimeUnit.DayBased::class, DateTimeUnit.MonthBased::class, DateTimeUnit.TimeBased::class),
168168
arrayOf(DayBasedDateTimeUnitSerializer, MonthBasedDateTimeUnitSerializer, TimeBasedDateTimeUnitSerializer))
169169

170170
@InternalSerializationApi

core/js/src/Instant.kt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -145,9 +145,9 @@ public actual fun Instant.plus(value: Long, unit: DateTimeUnit, timeZone: TimeZo
145145
is DateTimeUnit.TimeBased -> {
146146
plus(value, unit).value.checkZone(timeZone)
147147
}
148-
is DateTimeUnit.DateBased.DayBased ->
148+
is DateTimeUnit.DayBased ->
149149
thisZdt.plusDays(value.toDouble() * unit.days).toInstant()
150-
is DateTimeUnit.DateBased.MonthBased ->
150+
is DateTimeUnit.MonthBased ->
151151
thisZdt.plusMonths(value.toDouble() * unit.months).toInstant()
152152
}.let(::Instant)
153153
} catch (e: Throwable) {
@@ -161,9 +161,9 @@ public actual fun Instant.plus(value: Int, unit: DateTimeUnit, timeZone: TimeZon
161161
when (unit) {
162162
is DateTimeUnit.TimeBased ->
163163
plus(value.toLong(), unit).value.checkZone(timeZone)
164-
is DateTimeUnit.DateBased.DayBased ->
164+
is DateTimeUnit.DayBased ->
165165
thisZdt.plusDays(value.toDouble() * unit.days).toInstant()
166-
is DateTimeUnit.DateBased.MonthBased ->
166+
is DateTimeUnit.MonthBased ->
167167
thisZdt.plusMonths(value.toDouble() * unit.months).toInstant()
168168
}.let(::Instant)
169169
} catch (e: Throwable) {
@@ -208,8 +208,8 @@ public actual fun Instant.until(other: Instant, unit: DateTimeUnit, timeZone: Ti
208208
val otherZdt = other.atZone(timeZone)
209209
when(unit) {
210210
is DateTimeUnit.TimeBased -> until(other, unit)
211-
is DateTimeUnit.DateBased.DayBased -> (thisZdt.until(otherZdt, ChronoUnit.DAYS).toDouble() / unit.days).toLong()
212-
is DateTimeUnit.DateBased.MonthBased -> (thisZdt.until(otherZdt, ChronoUnit.MONTHS).toDouble() / unit.months).toLong()
211+
is DateTimeUnit.DayBased -> (thisZdt.until(otherZdt, ChronoUnit.DAYS).toDouble() / unit.days).toLong()
212+
is DateTimeUnit.MonthBased -> (thisZdt.until(otherZdt, ChronoUnit.MONTHS).toDouble() / unit.months).toLong()
213213
}
214214
} catch (e: ArithmeticException) {
215215
if (this < other) Long.MAX_VALUE else Long.MIN_VALUE

core/js/src/LocalDate.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ public actual fun LocalDate.plus(value: Long, unit: DateTimeUnit.DateBased): Loc
5959
private fun LocalDate.plusNumber(value: Number, unit: DateTimeUnit.DateBased): LocalDate =
6060
try {
6161
when (unit) {
62-
is DateTimeUnit.DateBased.DayBased -> this.value.plusDays(value.toDouble() * unit.days)
63-
is DateTimeUnit.DateBased.MonthBased -> this.value.plusMonths(value.toDouble() * unit.months)
62+
is DateTimeUnit.DayBased -> this.value.plusDays(value.toDouble() * unit.days)
63+
is DateTimeUnit.MonthBased -> this.value.plusMonths(value.toDouble() * unit.months)
6464
}.let(::LocalDate)
6565
} catch (e: Throwable) {
6666
if (!e.isJodaDateTimeException() && !e.isJodaArithmeticException()) throw e
@@ -92,8 +92,8 @@ public actual fun LocalDate.periodUntil(other: LocalDate): DatePeriod {
9292
}
9393

9494
public actual fun LocalDate.until(other: LocalDate, unit: DateTimeUnit.DateBased): Int = when(unit) {
95-
is DateTimeUnit.DateBased.MonthBased -> monthsUntil(other) / unit.months
96-
is DateTimeUnit.DateBased.DayBased -> daysUntil(other) / unit.days
95+
is DateTimeUnit.MonthBased -> monthsUntil(other) / unit.months
96+
is DateTimeUnit.DayBased -> daysUntil(other) / unit.days
9797
}
9898

9999
public actual fun LocalDate.daysUntil(other: LocalDate): Int =

core/jvm/src/Instant.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,9 @@ public actual fun Instant.plus(value: Long, unit: DateTimeUnit, timeZone: TimeZo
133133
when (unit) {
134134
is DateTimeUnit.TimeBased ->
135135
plus(value, unit).value.also { it.atZone(timeZone.zoneId) }
136-
is DateTimeUnit.DateBased.DayBased ->
136+
is DateTimeUnit.DayBased ->
137137
thisZdt.plusDays(safeMultiply(value, unit.days.toLong())).toInstant()
138-
is DateTimeUnit.DateBased.MonthBased ->
138+
is DateTimeUnit.MonthBased ->
139139
thisZdt.plusMonths(safeMultiply(value, unit.months.toLong())).toInstant()
140140
}.let(::Instant)
141141
} catch (e: Exception) {
@@ -173,8 +173,8 @@ public actual fun Instant.until(other: Instant, unit: DateTimeUnit, timeZone: Ti
173173
val otherZdt = other.atZone(timeZone)
174174
when(unit) {
175175
is DateTimeUnit.TimeBased -> until(other, unit)
176-
is DateTimeUnit.DateBased.DayBased -> thisZdt.until(otherZdt, ChronoUnit.DAYS) / unit.days
177-
is DateTimeUnit.DateBased.MonthBased -> thisZdt.until(otherZdt, ChronoUnit.MONTHS) / unit.months
176+
is DateTimeUnit.DayBased -> thisZdt.until(otherZdt, ChronoUnit.DAYS) / unit.days
177+
is DateTimeUnit.MonthBased -> thisZdt.until(otherZdt, ChronoUnit.MONTHS) / unit.months
178178
}
179179
} catch (e: DateTimeException) {
180180
throw DateTimeArithmeticException(e)

core/jvm/src/LocalDate.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,11 @@ public actual fun LocalDate.minus(value: Int, unit: DateTimeUnit.DateBased): Loc
6363
public actual fun LocalDate.plus(value: Long, unit: DateTimeUnit.DateBased): LocalDate =
6464
try {
6565
when (unit) {
66-
is DateTimeUnit.DateBased.DayBased -> {
66+
is DateTimeUnit.DayBased -> {
6767
val addDays: Long = safeMultiply(value, unit.days.toLong())
6868
ofEpochDayChecked(safeAdd(this.value.toEpochDay(), addDays))
6969
}
70-
is DateTimeUnit.DateBased.MonthBased ->
70+
is DateTimeUnit.MonthBased ->
7171
this.value.plusMonths(safeMultiply(value, unit.months.toLong()))
7272
}.let(::LocalDate)
7373
} catch (e: Exception) {
@@ -109,8 +109,8 @@ public actual fun LocalDate.periodUntil(other: LocalDate): DatePeriod {
109109
}
110110

111111
public actual fun LocalDate.until(other: LocalDate, unit: DateTimeUnit.DateBased): Int = when(unit) {
112-
is DateTimeUnit.DateBased.MonthBased -> (this.value.until(other.value, ChronoUnit.MONTHS) / unit.months).clampToInt()
113-
is DateTimeUnit.DateBased.DayBased -> (this.value.until(other.value, ChronoUnit.DAYS) / unit.days).clampToInt()
112+
is DateTimeUnit.MonthBased -> (this.value.until(other.value, ChronoUnit.MONTHS) / unit.months).clampToInt()
113+
is DateTimeUnit.DayBased -> (this.value.until(other.value, ChronoUnit.DAYS) / unit.days).clampToInt()
114114
}
115115

116116
public actual fun LocalDate.daysUntil(other: LocalDate): Int =

core/native/src/LocalDate.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -256,8 +256,8 @@ public actual fun LocalDate.plus(unit: DateTimeUnit.DateBased): LocalDate =
256256
public actual fun LocalDate.plus(value: Int, unit: DateTimeUnit.DateBased): LocalDate =
257257
try {
258258
when (unit) {
259-
is DateTimeUnit.DateBased.DayBased -> plusDays(safeMultiply(value, unit.days))
260-
is DateTimeUnit.DateBased.MonthBased -> plusMonths(safeMultiply(value, unit.months))
259+
is DateTimeUnit.DayBased -> plusDays(safeMultiply(value, unit.days))
260+
is DateTimeUnit.MonthBased -> plusMonths(safeMultiply(value, unit.months))
261261
}
262262
} catch (e: ArithmeticException) {
263263
throw DateTimeArithmeticException("Arithmetic overflow when adding a value to a date", e)
@@ -286,8 +286,8 @@ public actual operator fun LocalDate.plus(period: DatePeriod): LocalDate =
286286
}
287287

288288
public actual fun LocalDate.until(other: LocalDate, unit: DateTimeUnit.DateBased): Int = when(unit) {
289-
is DateTimeUnit.DateBased.MonthBased -> monthsUntil(other) / unit.months
290-
is DateTimeUnit.DateBased.DayBased -> daysUntil(other) / unit.days
289+
is DateTimeUnit.MonthBased -> monthsUntil(other) / unit.months
290+
is DateTimeUnit.DayBased -> daysUntil(other) / unit.days
291291
}
292292

293293
// org.threeten.bp.LocalDate#daysUntil

core/native/src/LocalDateTime.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,8 @@ internal fun LocalDateTime.until(other: LocalDateTime, unit: DateTimeUnit.DateBa
9494
endDate = endDate.plusDays(1) // won't throw: date - endDate >= 1
9595
}
9696
return when (unit) {
97-
is DateTimeUnit.DateBased.MonthBased -> date.monthsUntil(endDate) / unit.months
98-
is DateTimeUnit.DateBased.DayBased -> date.daysUntil(endDate) / unit.days
97+
is DateTimeUnit.MonthBased -> date.monthsUntil(endDate) / unit.months
98+
is DateTimeUnit.DayBased -> date.daysUntil(endDate) / unit.days
9999
}
100100
}
101101

serialization/common/test/DateTimeUnitSerializationTest.kt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,20 @@ class DateTimeUnitSerializationTest {
2424
}
2525
}
2626

27-
private fun dayBasedSerialization(serializer: KSerializer<DateTimeUnit.DateBased.DayBased>) {
27+
private fun dayBasedSerialization(serializer: KSerializer<DateTimeUnit.DayBased>) {
2828
repeat(100) {
2929
val days = Random.nextInt(1, Int.MAX_VALUE)
30-
val unit = DateTimeUnit.DateBased.DayBased(days)
30+
val unit = DateTimeUnit.DayBased(days)
3131
val json = "{\"days\":$days}"
3232
assertEquals(json, Json.encodeToString(serializer, unit))
3333
assertEquals(unit, Json.decodeFromString(serializer, json))
3434
}
3535
}
3636

37-
private fun monthBasedSerialization(serializer: KSerializer<DateTimeUnit.DateBased.MonthBased>) {
37+
private fun monthBasedSerialization(serializer: KSerializer<DateTimeUnit.MonthBased>) {
3838
repeat(100) {
3939
val months = Random.nextInt(1, Int.MAX_VALUE)
40-
val unit = DateTimeUnit.DateBased.MonthBased(months)
40+
val unit = DateTimeUnit.MonthBased(months)
4141
val json = "{\"months\":$months}"
4242
assertEquals(json, Json.encodeToString(serializer, unit))
4343
assertEquals(unit, Json.decodeFromString(serializer, json))
@@ -47,14 +47,14 @@ class DateTimeUnitSerializationTest {
4747
private fun dateBasedSerialization(serializer: KSerializer<DateTimeUnit.DateBased>) {
4848
repeat(100) {
4949
val days = Random.nextInt(1, Int.MAX_VALUE)
50-
val unit = DateTimeUnit.DateBased.DayBased(days)
50+
val unit = DateTimeUnit.DayBased(days)
5151
val json = "{\"type\":\"DayBased\",\"days\":$days}"
5252
assertEquals(json, Json.encodeToString(serializer, unit))
5353
assertEquals(unit, Json.decodeFromString(serializer, json))
5454
}
5555
repeat(100) {
5656
val months = Random.nextInt(1, Int.MAX_VALUE)
57-
val unit = DateTimeUnit.DateBased.MonthBased(months)
57+
val unit = DateTimeUnit.MonthBased(months)
5858
val json = "{\"type\":\"MonthBased\",\"months\":$months}"
5959
assertEquals(json, Json.encodeToString(serializer, unit))
6060
assertEquals(unit, Json.decodeFromString(serializer, json))
@@ -71,14 +71,14 @@ class DateTimeUnitSerializationTest {
7171
}
7272
repeat(100) {
7373
val days = Random.nextInt(1, Int.MAX_VALUE)
74-
val unit = DateTimeUnit.DateBased.DayBased(days)
74+
val unit = DateTimeUnit.DayBased(days)
7575
val json = "{\"type\":\"DayBased\",\"days\":$days}"
7676
assertEquals(json, Json.encodeToString(serializer, unit))
7777
assertEquals(unit, Json.decodeFromString(serializer, json))
7878
}
7979
repeat(100) {
8080
val months = Random.nextInt(1, Int.MAX_VALUE)
81-
val unit = DateTimeUnit.DateBased.MonthBased(months)
81+
val unit = DateTimeUnit.MonthBased(months)
8282
val json = "{\"type\":\"MonthBased\",\"months\":$months}"
8383
assertEquals(json, Json.encodeToString(serializer, unit))
8484
assertEquals(unit, Json.decodeFromString(serializer, json))

0 commit comments

Comments
 (0)