Skip to content

Commit 688cc1b

Browse files
committed
Fixes 2
1 parent a4e751b commit 688cc1b

File tree

2 files changed

+13
-11
lines changed

2 files changed

+13
-11
lines changed

darwin-integration/nativeMain/src/Converters.kt

+5-5
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Use of this source code is governed by the Apache 2.0 License that can be found in the LICENSE.txt file.
44
*/
55

6-
package kotlinx.datetimex.darwin.converters
6+
package kotlinx.datetime.darwin.converters
77
import kotlinx.cinterop.*
88
import kotlinx.datetime.*
99
import platform.Foundation.*
@@ -26,19 +26,19 @@ public fun Instant.toNSDate(): NSDate {
2626
/**
2727
* Builds the corresponding [Instant].
2828
* Even though Darwin only uses millisecond precision, it is possible that [date] uses larger resolution, storing
29-
* microseconds or even nanoseconds. In this case, the sub-millisecond parts of [date] are ignored, given that they
30-
* are likely to be conversion artifacts.
29+
* microseconds or even nanoseconds. In this case, the sub-millisecond parts of [date] are rounded to the nearest
30+
* millisecond, given that they are likely to be conversion artifacts.
3131
*/
3232
public fun NSDate.toKotlinInstant(): Instant {
3333
val secs = timeIntervalSince1970()
34-
val millis = secs * 1000
34+
val millis = secs * 1000 + if (secs > 0) 0.5 else -0.5
3535
return Instant.fromUnixMillis(millis.toLong())
3636
}
3737

3838
/**
3939
* Converts the time zone to [NSTimeZone].
4040
* If the time zone is represented as a fixed number of seconds from GMT (for example, if it is the result of a call to
41-
* [Instant.offset]) and the offset is not given in even minutes but also includes seconds, this method throws
41+
* [TimeZone.offset]) and the offset is not given in even minutes but also includes seconds, this method throws
4242
* [DateTimeException] to denote that lossy conversion would happen, as Darwin internally rounds the offsets to the
4343
* nearest minute.
4444
*/

darwin-integration/nativeTest/src/ConvertersTest.kt

+8-6
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
package kotlinx.datetime.darwin.converters
66
import kotlinx.cinterop.*
77
import kotlinx.datetime.*
8-
import kotlinx.datetimex.darwin.converters.*
98
import platform.Foundation.*
109
import kotlin.math.*
1110
import kotlin.random.*
@@ -27,16 +26,19 @@ class ConvertersTest {
2726

2827
@Test
2928
fun testToFromNSDate() {
29+
// The first day on the Gregorian calendar. The day before it is 1582-10-04 in the Julian calendar.
30+
val gregorianCalendarStart = Instant.parse("1582-10-15T00:00:00Z").toUnixMillis()
3031
val minBoundMillis = (NSDate.distantPast.timeIntervalSince1970 * 1000 + 0.5).toLong()
3132
val maxBoundMillis = (NSDate.distantFuture.timeIntervalSince1970 * 1000 - 0.5).toLong()
3233
repeat (1000) {
33-
val millis = Random.nextLong()
34-
if (millis in minBoundMillis..maxBoundMillis) {
35-
val instant = Instant.fromUnixMillis(millis)
36-
val date = instant.toNSDate()
34+
val millis = Random.nextLong(minBoundMillis, maxBoundMillis)
35+
val instant = Instant.fromUnixMillis(millis)
36+
val date = instant.toNSDate()
37+
// Darwin's date printer dynamically adjusts to switching between calendars, while our Instant does not.
38+
if (millis >= gregorianCalendarStart) {
3739
assertEquals(instant, Instant.parse(dateFormatter.stringFromDate(date)))
38-
assertEquals(instant, date.toKotlinInstant())
3940
}
41+
assertEquals(instant, date.toKotlinInstant())
4042
}
4143
}
4244

0 commit comments

Comments
 (0)