Skip to content

Commit a9d104b

Browse files
committed
Add converters to and from java.time.* types and tests for them
1 parent 1b1a59e commit a9d104b

File tree

3 files changed

+216
-1
lines changed

3 files changed

+216
-1
lines changed

core/darwinTest/src/ConvertersTest.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
* Copyright 2019-2020 JetBrains s.r.o.
33
* Use of this source code is governed by the Apache 2.0 License that can be found in the LICENSE.txt file.
44
*/
5-
package kotlinx.datetime
5+
package kotlinx.datetime.test
6+
7+
import kotlinx.datetime.*
68
import kotlinx.cinterop.*
79
import platform.Foundation.*
810
import kotlin.math.*

core/jvmMain/src/Converters.kt

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright 2019-2020 JetBrains s.r.o.
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
7+
8+
/**
9+
* Converts this [kotlinx.datetime.Instant][Instant] value to a [java.time.Instant][java.time.Instant] value.
10+
*/
11+
public fun Instant.toJavaInstant(): java.time.Instant = this.value
12+
13+
/**
14+
* Converts this [java.time.Instant][java.time.Instant] value to a [kotlinx.datetime.Instant][Instant] value.
15+
*/
16+
public fun java.time.Instant.toKotlinInstant(): Instant = Instant(this)
17+
18+
19+
/**
20+
* Converts this [kotlinx.datetime.LocalDateTime][LocalDateTime] value to a [java.time.LocalDateTime][java.time.LocalDateTime] value.
21+
*/
22+
public fun LocalDateTime.toJavaLocalDateTime(): java.time.LocalDateTime = this.value
23+
24+
/**
25+
* Converts this [java.time.LocalDateTime][java.time.LocalDateTime] value to a [kotlinx.datetime.LocalDateTime][LocalDateTime] value.
26+
*/
27+
public fun java.time.LocalDateTime.toKotlinLocalDateTime(): LocalDateTime = LocalDateTime(this)
28+
29+
30+
/**
31+
* Converts this [kotlinx.datetime.LocalDate][LocalDate] value to a [java.time.LocalDate][java.time.LocalDate] value.
32+
*/
33+
public fun LocalDate.toJavaLocalDate(): java.time.LocalDate = this.value
34+
35+
/**
36+
* Converts this [java.time.LocalDate][java.time.LocalDate] value to a [kotlinx.datetime.LocalDate][LocalDate] value.
37+
*/
38+
public fun java.time.LocalDate.toKotlinLocalDate(): LocalDate = LocalDate(this)
39+
40+
41+
/**
42+
* Converts this [kotlinx.datetime.DatePeriod][DatePeriod] value to a [java.time.Period][java.time.Period] value.
43+
*/
44+
public fun DatePeriod.toJavaPeriod(): java.time.Period = java.time.Period.of(this.years, this.months, this.days)
45+
46+
/**
47+
* Converts this [java.time.Period][java.time.Period] value to a [kotlinx.datetime.DatePeriod][DatePeriod] value.
48+
*/
49+
public fun java.time.Period.toKotlinDatePeriod(): DatePeriod = DatePeriod(this.years, this.months, this.days)
50+
51+
52+
/**
53+
* Converts this [kotlinx.datetime.TimeZone][TimeZone] value to a [java.time.ZoneId][java.time.ZoneId] value.
54+
*/
55+
public fun TimeZone.toJavaZoneId(): java.time.ZoneId = this.zoneId
56+
57+
/**
58+
* Converts this [java.time.ZoneId][java.time.ZoneId] value to a [kotlinx.datetime.TimeZone][TimeZone] value.
59+
*/
60+
public fun java.time.ZoneId.toKotlinTimeZone(): TimeZone = TimeZone(this)
61+
62+
63+
/**
64+
* Converts this [kotlinx.datetime.ZoneOffset][ZoneOffset] value to a [java.time.ZoneOffset][java.time.ZoneOffset] value.
65+
*/
66+
public fun ZoneOffset.toJavaZoneOffset(): java.time.ZoneOffset = this.zoneOffset
67+
68+
/**
69+
* Converts this [java.time.ZoneOffset][java.time.ZoneOffset] value to a [kotlinx.datetime.ZoneOffset][ZoneOffset] value.
70+
*/
71+
public fun java.time.ZoneOffset.toKotlinZoneOffset(): ZoneOffset = ZoneOffset(this)

core/jvmTest/src/ConvertersTest.kt

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
/*
2+
* Copyright 2019-2020 JetBrains s.r.o.
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+
package kotlinx.datetime.test
6+
7+
import kotlinx.datetime.*
8+
import kotlin.random.Random
9+
import kotlin.test.*
10+
import java.time.Instant as JTInstant
11+
import java.time.LocalDateTime as JTLocalDateTime
12+
import java.time.LocalDate as JTLocalDate
13+
import java.time.Period as JTPeriod
14+
import java.time.ZoneId
15+
import java.time.ZoneOffset as JTZoneOffset
16+
17+
class ConvertersTest {
18+
19+
@Test
20+
fun instant() {
21+
fun test(seconds: Long, nanosecond: Int) {
22+
val ktInstant = Instant.fromEpochSeconds(seconds, nanosecond.toLong())
23+
val jtInstant = JTInstant.ofEpochSecond(seconds, nanosecond.toLong())
24+
25+
assertEquals(ktInstant, jtInstant.toKotlinInstant())
26+
assertEquals(jtInstant, ktInstant.toJavaInstant())
27+
28+
assertEquals(ktInstant, jtInstant.toString().toInstant())
29+
assertEquals(jtInstant, ktInstant.toString().let(JTInstant::parse))
30+
}
31+
32+
repeat(1000) {
33+
val seconds = Random.nextLong(1_000_000_000_000)
34+
val nanos = Random.nextInt()
35+
test(seconds, nanos)
36+
}
37+
}
38+
39+
private fun randomDate(): LocalDate {
40+
val year = Random.nextInt(-20000, 20000)
41+
val month = Month.values().random()
42+
val day = (1..java.time.YearMonth.of(year, month).lengthOfMonth()).random()
43+
return LocalDate(year, month.number, day)
44+
}
45+
46+
private fun randomDateTime(): LocalDateTime = randomDate().atTime(
47+
Random.nextInt(24),
48+
Random.nextInt(60),
49+
Random.nextInt(60),
50+
Random.nextInt(1_000_000_000))
51+
52+
@Test
53+
fun localDateTime() {
54+
fun test(ktDateTime: LocalDateTime) {
55+
val jtDateTime = with(ktDateTime) { JTLocalDateTime.of(year, month, dayOfMonth, hour, minute, second, nanosecond) }
56+
57+
assertEquals(ktDateTime, jtDateTime.toKotlinLocalDateTime())
58+
assertEquals(jtDateTime, ktDateTime.toJavaLocalDateTime())
59+
60+
assertEquals(ktDateTime, jtDateTime.toString().toLocalDateTime())
61+
assertEquals(jtDateTime, ktDateTime.toString().let(JTLocalDateTime::parse))
62+
}
63+
64+
repeat(1000) {
65+
test(randomDateTime())
66+
}
67+
}
68+
69+
@Test
70+
fun localDate() {
71+
fun test(ktDate: LocalDate) {
72+
val jtDate = with(ktDate) { JTLocalDate.of(year, month, dayOfMonth) }
73+
74+
assertEquals(ktDate, jtDate.toKotlinLocalDate())
75+
assertEquals(jtDate, ktDate.toJavaLocalDate())
76+
77+
assertEquals(ktDate, jtDate.toString().toLocalDate())
78+
assertEquals(jtDate, ktDate.toString().let(JTLocalDate::parse))
79+
}
80+
81+
repeat(1000) {
82+
test(randomDate())
83+
}
84+
}
85+
86+
@Test
87+
fun datePeriod() {
88+
fun test(years: Int, months: Int, days: Int) {
89+
val ktPeriod = DatePeriod(years, months, days)
90+
val jtPeriod = JTPeriod.of(years, months, days)
91+
92+
assertEquals(ktPeriod, jtPeriod.toKotlinDatePeriod())
93+
assertEquals(jtPeriod, ktPeriod.toJavaPeriod())
94+
95+
// TODO: assertEquals(ktPeriod, jtPeriod.toString().let(DatePeriod::parse))
96+
assertEquals(jtPeriod, ktPeriod.toString().let(JTPeriod::parse))
97+
}
98+
99+
repeat(1000) {
100+
test(Random.nextInt(-1000, 1000), Random.nextInt(-1000, 1000), Random.nextInt(-1000, 1000))
101+
}
102+
}
103+
104+
@Test
105+
fun timeZone() {
106+
fun test(tzid: String) {
107+
val ktZone = TimeZone.of(tzid)
108+
val jtZone = ZoneId.of(tzid)
109+
110+
assertEquals(ktZone, jtZone.toKotlinTimeZone())
111+
assertEquals(jtZone, ktZone.toJavaZoneId())
112+
}
113+
114+
test("Z")
115+
test("Etc/UTC")
116+
test("+00")
117+
test("+0000")
118+
test("+00:00")
119+
test("America/New_York")
120+
test("Europe/Berlin")
121+
}
122+
123+
@Test
124+
fun zoneOffset() {
125+
fun test(offsetString: String) {
126+
val ktZoneOffset = TimeZone.of(offsetString).offsetAt(Instant.fromEpochMilliseconds(0))
127+
val jtZoneOffset = JTZoneOffset.of(offsetString)
128+
129+
assertEquals(ktZoneOffset, jtZoneOffset.toKotlinZoneOffset())
130+
assertEquals(ktZoneOffset, jtZoneOffset.toKotlinTimeZone())
131+
assertEquals(jtZoneOffset, ktZoneOffset.toJavaZoneOffset())
132+
assertEquals(jtZoneOffset, ktZoneOffset.toJavaZoneId())
133+
}
134+
135+
test("Z")
136+
test("+1")
137+
test("-10")
138+
test("+08")
139+
test("+08")
140+
test("-103030")
141+
}
142+
}

0 commit comments

Comments
 (0)