Skip to content

Commit 80a8ee3

Browse files
authored
Merge pull request #7 from cquiroz/sync_upstream
Sync upstream
2 parents da0acbf + d45f876 commit 80a8ee3

File tree

10 files changed

+149
-45
lines changed

10 files changed

+149
-45
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,5 @@
3131
!/src/test/
3232

3333
**/TempTest.java
34-
tzdb/
34+
/.idea/
35+
/threetenbp.iml

build.sbt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,10 +173,18 @@ lazy val pomData =
173173
<name>Ludovic Hochet</name>
174174
<url>https://github.com/lhochet</url>
175175
</contributor>
176+
<contributor>
177+
<name>Matias Irland</name>
178+
<url>https://github.com/matir91</url>
179+
</contributor>
176180
<contributor>
177181
<name>Pap Lorinc</name>
178182
<url>https://github.com/paplorinc</url>
179183
</contributor>
184+
<contributor>
185+
<name>Philippe Marschall</name>
186+
<url>https://github.com/marschall</url>
187+
</contributor>
180188
<contributor>
181189
<name>Michael Nascimento Santos</name>
182190
<url>https://github.com/sjmisterm</url>

changes.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,12 @@
8181
</action>
8282
</release>
8383
<release version="1.3.3" date="SNAPSHOT" description="v1.3.3">
84+
<action dev="jodastephen" type="update" >
85+
Update to time-zone data 2016j.
86+
</action>
87+
<action dev="jodastephen" type="fix" >
88+
Avoid referring to JDK internal packages.
89+
</action>
8490
<action dev="jodastephen" type="update" >
8591
Update to time-zone data 2016f.
8692
</action>
978 Bytes
Binary file not shown.

jvm/src/main/scala/org/threeten/bp/zone/TzdbZoneRulesProvider.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ private[zone] object TzdbZoneRulesProvider {
9191
*/
9292
final class TzdbZoneRulesProvider extends ZoneRulesProvider {
9393
/** All the regions that are available. */
94-
private val regionIds: java.util.Set[String] = new CopyOnWriteArraySet[String]
94+
private val regionIds: java.util.List[String] = new java.util.concurrent.CopyOnWriteArrayList[String]
9595
/** All the versions that are available. */
9696
private val versions: ConcurrentNavigableMap[String, TzdbZoneRulesProvider.Version] = new ConcurrentSkipListMap[String, TzdbZoneRulesProvider.Version]
9797
/** All the URLs that have been loaded.

jvm/src/test/scala/org/threeten/bp/TestInstant.scala

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import org.threeten.bp.temporal.ChronoUnit.NANOS
4242
import org.threeten.bp.temporal.ChronoUnit.SECONDS
4343
import java.util.Arrays
4444
import java.util.Locale
45+
import java.lang.{Long => JLong}
4546
import org.testng.annotations.BeforeMethod
4647
import org.testng.annotations.DataProvider
4748
import org.testng.annotations.Test
@@ -250,14 +251,15 @@ object TestInstant {
250251
Instant.ofEpochSecond(Long.MaxValue, Long.MaxValue)
251252
}
252253

253-
@DataProvider(name = "MillisInstantNoNanos") private[bp] def provider_factory_millis_long: Array[Array[_ <: AnyRef]] = {
254-
Array[Array[_ <: AnyRef]](Array[Integer](0, 0, 0), Array[Integer](1, 0, 1000000), Array[Integer](2, 0, 2000000), Array[Integer](999, 0, 999000000), Array[Integer](1000, 1, 0), Array[Integer](1001, 1, 1000000), Array[Integer](-1, -1, 999000000), Array[Integer](-2, -1, 998000000), Array[Integer](-999, -1, 1000000), Array[Integer](-1000, -1, 0), Array[Integer](-1001, -2, 999000000))
254+
@DataProvider(name = "MillisInstantNoNanos") private[bp] def provider_factory_millis_long = {
255+
Array[Array[_ <: AnyRef]](Array[Number](0, 0, 0, 0), Array[Number](0, 999999, 0, 999999), Array[Number](1, 0, 0, 1000000), Array[Number](1, 1, 0, 1000001), Array[Number](2, 0, 0, 2000000), Array[Number](999, 0, 0, 999000000), Array[Number](1000, 0, 1, 0), Array[Number](1001, 0, 1, 1000000), Array[Number](-1, 1, -1, 999000001), Array[Number](-1, 0, -1, 999000000), Array[Number](-2, 999999, -1, 998999999), Array[Number](-2, 0, -1, 998000000), Array[Number](-999, 0, -1, 1000000), Array[Number](-1000, 0, -1, 0), Array[Number](-1001, 0, -2, 999000000), Array[Number](Long.MaxValue, 0, Long.MaxValue / 1000, (Long.MaxValue % 1000).toInt * 1000000), Array[Number](Long.MaxValue - 1, 0, (Long.MaxValue - 1) / 1000, ((Long.MaxValue - 1) % 1000).toInt * 1000000), Array[Number](Long.MinValue, 0, (Long.MinValue / 1000) - 1, (Long.MinValue % 1000).toInt * 1000000 + 1000000000), Array[Number](Long.MinValue, 1, (Long.MinValue / 1000) - 1, (Long.MinValue % 1000).toInt * 1000000 + 1000000000 + 1), Array[Number](Long.MinValue + 1, 0, ((Long.MinValue + 1) / 1000) - 1, ((Long.MinValue + 1) % 1000).toInt * 1000000 + 1000000000), Array[Number](Long.MinValue + 1, 1, ((Long.MinValue + 1) / 1000) - 1, ((Long.MinValue + 1) % 1000).toInt * 1000000 + 1000000000 + 1))
255256
}
256257

257-
@Test(dataProvider = "MillisInstantNoNanos") def factory_millis_long(millis: Long, expectedSeconds: Long, expectedNanoOfSecond: Int): Unit = {
258-
val t: Instant = Instant.ofEpochMilli(millis)
258+
@Test(dataProvider = "MillisInstantNoNanos") def factory_millis_long(millis: Long, nanos: Int, expectedSeconds: Long, expectedNanoOfSecond: Int): Unit = {
259+
val t = Instant.ofEpochMilli(millis).plusNanos(nanos)
259260
assertEquals(t.getEpochSecond, expectedSeconds)
260261
assertEquals(t.getNano, expectedNanoOfSecond)
262+
assertEquals(t.toEpochMilli, millis);
261263
}
262264

263265
@DataProvider(name = "Parse") private[bp] def provider_factory_parse: Array[Array[Any]] = {
@@ -579,6 +581,16 @@ object TestInstant {
579581
i.minusNanos(1)
580582
}
581583

584+
@Test
585+
def test_truncatedTo(): Unit = {
586+
assertEquals(Instant.ofEpochSecond(2L, 1000000).truncatedTo(ChronoUnit.SECONDS), Instant.ofEpochSecond(2L))
587+
assertEquals(Instant.ofEpochSecond(2L, -1000000).truncatedTo(ChronoUnit.SECONDS), Instant.ofEpochSecond(1L))
588+
assertEquals(Instant.ofEpochSecond(0L, -1000000).truncatedTo(ChronoUnit.SECONDS), Instant.ofEpochSecond(-1L))
589+
assertEquals(Instant.ofEpochSecond(-1L).truncatedTo(ChronoUnit.SECONDS), Instant.ofEpochSecond(-1L))
590+
assertEquals(Instant.ofEpochSecond(-1L, -1000000).truncatedTo(ChronoUnit.SECONDS), Instant.ofEpochSecond(-2L))
591+
assertEquals(Instant.ofEpochSecond(-2L).truncatedTo(ChronoUnit.SECONDS), Instant.ofEpochSecond(-2L))
592+
}
593+
582594
@Test def test_toEpochMilli(): Unit = {
583595
assertEquals(Instant.ofEpochSecond(1L, 1000000).toEpochMilli, 1001L)
584596
assertEquals(Instant.ofEpochSecond(1L, 2000000).toEpochMilli, 1002L)
@@ -600,10 +612,18 @@ object TestInstant {
600612
Instant.ofEpochSecond(Long.MaxValue / 1000 + 1).toEpochMilli
601613
}
602614

615+
@Test(expectedExceptions = Array(classOf[ArithmeticException])) def test_toEpochMilli_tooBigDueToNanos() {
616+
Instant.ofEpochMilli(Long.MaxValue).plusMillis(1).toEpochMilli
617+
}
618+
603619
@Test(expectedExceptions = Array(classOf[ArithmeticException])) def test_toEpochMilli_tooSmall(): Unit = {
604620
Instant.ofEpochSecond(Long.MinValue / 1000 - 1).toEpochMilli
605621
}
606622

623+
@Test(expectedExceptions = Array(classOf[ArithmeticException])) def test_toEpochMilli_tooSmallDueToNanos() {
624+
Instant.ofEpochMilli(Long.MinValue).minusMillis(1).toEpochMilli
625+
}
626+
607627
@Test def test_comparisons(): Unit = {
608628
doTest_comparisons_Instant(Instant.ofEpochSecond(-2L, 0), Instant.ofEpochSecond(-2L, 999999998), Instant.ofEpochSecond(-2L, 999999999), Instant.ofEpochSecond(-1L, 0), Instant.ofEpochSecond(-1L, 1), Instant.ofEpochSecond(-1L, 999999998), Instant.ofEpochSecond(-1L, 999999999), Instant.ofEpochSecond(0L, 0), Instant.ofEpochSecond(0L, 1), Instant.ofEpochSecond(0L, 2), Instant.ofEpochSecond(0L, 999999999), Instant.ofEpochSecond(1L, 0), Instant.ofEpochSecond(2L, 0))
609629
}

jvm/src/test/scala/org/threeten/bp/chrono/TestJapaneseChronology.scala

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,29 +106,59 @@ import org.threeten.bp.temporal.TemporalAdjusters
106106
assertEquals(test, LocalDateTime.of(1890, 10, 29, 0, 0))
107107
}
108108

109-
@DataProvider(name = "japaneseEras") private[chrono] def data_japanseseEras: Array[Array[Any]] = {
109+
@DataProvider(name = "japaneseEras") private[chrono] def data_japansesEras: Array[Array[Any]] = {
110110
Array[Array[Any]](Array(JapaneseEra.MEIJI, -1, "Meiji"), Array(JapaneseEra.TAISHO, 0, "Taisho"), Array(JapaneseEra.SHOWA, 1, "Showa"), Array(JapaneseEra.HEISEI, 2, "Heisei"))
111111
}
112112

113113
@Test(dataProvider = "japaneseEras") def test_Japanese_Eras(era: Era, eraValue: Int, name: String): Unit = {
114114
assertEquals(era.getValue, eraValue, "EraValue")
115115
assertEquals(era.toString, name, "Era Name")
116116
assertEquals(era, JapaneseChronology.INSTANCE.eraOf(eraValue), "JapaneseChrono.eraOf()")
117+
assertEquals(JapaneseEra.valueOf(name), era)
117118
val eras: java.util.List[Era] = JapaneseChronology.INSTANCE.eras
118-
assertTrue(eras.contains(era), "Era is not present in JapaneseChrono.INSTANCE.eras()")
119+
assertTrue(eras.contains(era), "Era is not present in JapaneseChronology.INSTANCE.eras()")
119120
}
120121

121122
@Test def test_Japanese_badEras(): Unit = {
122123
val badEras: Array[Int] = Array(-1000, -998, -997, -2, 3, 4, 1000)
123124
for (badEra <- badEras)
124125
try {
125126
val era: Era = JapaneseChronology.INSTANCE.eraOf(badEra)
126-
fail(s"JapaneseChrono.eraOf returned $era + for invalid eraValue $badEra")
127+
fail(s"JapaneseChronology.eraOf returned $era + for invalid eraValue $badEra")
127128
} catch {
128129
case ex: DateTimeException =>
129130
}
131+
try {
132+
val era = JapaneseEra.valueOf("Rubbish")
133+
fail("JapaneseEra.valueOf returned " + era + " + for invalid era name Rubbish")
134+
} catch {
135+
case _: IllegalArgumentException =>
136+
// ignore expected exception
137+
}
130138
}
131139

140+
@Test def test_Japanese_registerEra() {
141+
try {
142+
JapaneseEra.registerEra(JapaneseEra.SHOWA.endDate, "TestAdditional")
143+
fail("JapaneseEra.registerEra should have failed")
144+
} catch {
145+
case _: DateTimeException =>
146+
// ignore expected exception
147+
}
148+
val additional = JapaneseEra.registerEra(LocalDate.of(2100, 1, 1), "TestAdditional")
149+
assertEquals(JapaneseEra.of(3), additional)
150+
assertEquals(JapaneseEra.valueOf("TestAdditional"), additional)
151+
assertEquals(JapaneseEra.values(4), additional)
152+
try {
153+
JapaneseEra.registerEra(LocalDate.of(2200, 1, 1), "TestAdditional2")
154+
fail("JapaneseEra.registerEra should have failed")
155+
156+
} catch {
157+
case ex: DateTimeException =>
158+
// ignore expected exception
159+
}
160+
}
161+
132162
@DataProvider(name = "toString") private[chrono] def data_toString: Array[Array[AnyRef]] =
133163
Array[Array[AnyRef]](Array(JapaneseChronology.INSTANCE.date(1873, 9, 8), "Japanese Meiji 6-09-08"), Array(JapaneseChronology.INSTANCE.date(1912, 7, 29), "Japanese Meiji 45-07-29"), Array(JapaneseChronology.INSTANCE.date(1912, 7, 30), "Japanese Taisho 1-07-30"), Array(JapaneseChronology.INSTANCE.date(1926, 12, 24), "Japanese Taisho 15-12-24"), Array(JapaneseChronology.INSTANCE.date(1926, 12, 25), "Japanese Showa 1-12-25"), Array(JapaneseChronology.INSTANCE.date(1989, 1, 7), "Japanese Showa 64-01-07"), Array(JapaneseChronology.INSTANCE.date(1989, 1, 8), "Japanese Heisei 1-01-08"), Array(JapaneseChronology.INSTANCE.date(2012, 12, 6), "Japanese Heisei 24-12-06"))
134164

jvm/src/test/scala/org/threeten/bp/format/TestDateTimeParsing.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,11 +69,12 @@ object TestDateTimeParsing {
6969
private val INSTANTSECONDS_NOS: DateTimeFormatter = new DateTimeFormatterBuilder().appendValue(INSTANT_SECONDS).appendLiteral('.').appendValue(NANO_OF_SECOND).toFormatter
7070
private val INSTANTSECONDS_NOS_WITH_PARIS: DateTimeFormatter = INSTANTSECONDS_NOS.withZone(PARIS)
7171
private val INSTANTSECONDS_OFFSETSECONDS: DateTimeFormatter = new DateTimeFormatterBuilder().appendValue(INSTANT_SECONDS).appendLiteral(' ').appendValue(OFFSET_SECONDS).toFormatter
72+
//private val INSTANT_OFFSETSECONDS_ZONE = new DateTimeFormatterBuilder().appendInstant.appendLiteral(' ').appendValue(OFFSET_SECONDS).appendLiteral(' ').appendZoneId.toFormatter
7273
}
7374

7475
@Test class TestDateTimeParsing {
7576
@DataProvider(name = "instantZones") private[format] def data_instantZones: Array[Array[AnyRef]] = {
76-
Array[Array[AnyRef]](Array(TestDateTimeParsing.LOCALFIELDS_ZONEID, "2014-06-30 01:02:03 Europe/Paris", ZonedDateTime.of(2014, 6, 30, 1, 2, 3, 0, TestDateTimeParsing.PARIS)), Array(TestDateTimeParsing.LOCALFIELDS_ZONEID, "2014-06-30 01:02:03 +02:30", ZonedDateTime.of(2014, 6, 30, 1, 2, 3, 0, TestDateTimeParsing.OFFSET_0230)), Array(TestDateTimeParsing.LOCALFIELDS_OFFSETID, "2014-06-30 01:02:03 +02:30", ZonedDateTime.of(2014, 6, 30, 1, 2, 3, 0, TestDateTimeParsing.OFFSET_0230)), Array(TestDateTimeParsing.LOCALFIELDS_WITH_PARIS, "2014-06-30 01:02:03", ZonedDateTime.of(2014, 6, 30, 1, 2, 3, 0, TestDateTimeParsing.PARIS)), Array(TestDateTimeParsing.LOCALFIELDS_WITH_0230, "2014-06-30 01:02:03", ZonedDateTime.of(2014, 6, 30, 1, 2, 3, 0, TestDateTimeParsing.OFFSET_0230)), Array(TestDateTimeParsing.INSTANT_WITH_PARIS, "2014-06-30T01:02:03Z", ZonedDateTime.of(2014, 6, 30, 1, 2, 3, 0, ZoneOffset.UTC).withZoneSameInstant(TestDateTimeParsing.PARIS)), Array(TestDateTimeParsing.INSTANT_WITH_0230, "2014-06-30T01:02:03Z", ZonedDateTime.of(2014, 6, 30, 1, 2, 3, 0, ZoneOffset.UTC).withZoneSameInstant(TestDateTimeParsing.OFFSET_0230)), Array(TestDateTimeParsing.INSTANT_OFFSETID, "2014-06-30T01:02:03Z +02:30", ZonedDateTime.of(2014, 6, 30, 1, 2, 3, 0, ZoneOffset.UTC).withZoneSameInstant(TestDateTimeParsing.OFFSET_0230)), Array(TestDateTimeParsing.INSTANT_OFFSETSECONDS, "2014-06-30T01:02:03Z 9000", ZonedDateTime.of(2014, 6, 30, 1, 2, 3, 0, ZoneOffset.UTC).withZoneSameInstant(TestDateTimeParsing.OFFSET_0230)), Array(TestDateTimeParsing.INSTANTSECONDS_WITH_PARIS, "86402", Instant.ofEpochSecond(86402).atZone(TestDateTimeParsing.PARIS)), Array(TestDateTimeParsing.INSTANTSECONDS_NOS_WITH_PARIS, "86402.123456789", Instant.ofEpochSecond(86402, 123456789).atZone(TestDateTimeParsing.PARIS)), Array(TestDateTimeParsing.INSTANTSECONDS_OFFSETSECONDS, "86402 9000", Instant.ofEpochSecond(86402).atZone(TestDateTimeParsing.OFFSET_0230)))
77+
Array[Array[AnyRef]](Array(TestDateTimeParsing.LOCALFIELDS_ZONEID, "2014-06-30 01:02:03 Europe/Paris", ZonedDateTime.of(2014, 6, 30, 1, 2, 3, 0, TestDateTimeParsing.PARIS)), Array(TestDateTimeParsing.LOCALFIELDS_ZONEID, "2014-06-30 01:02:03 +02:30", ZonedDateTime.of(2014, 6, 30, 1, 2, 3, 0, TestDateTimeParsing.OFFSET_0230)), Array(TestDateTimeParsing.LOCALFIELDS_OFFSETID, "2014-06-30 01:02:03 +02:30", ZonedDateTime.of(2014, 6, 30, 1, 2, 3, 0, TestDateTimeParsing.OFFSET_0230)), Array(TestDateTimeParsing.LOCALFIELDS_WITH_PARIS, "2014-06-30 01:02:03", ZonedDateTime.of(2014, 6, 30, 1, 2, 3, 0, TestDateTimeParsing.PARIS)), Array(TestDateTimeParsing.LOCALFIELDS_WITH_0230, "2014-06-30 01:02:03", ZonedDateTime.of(2014, 6, 30, 1, 2, 3, 0, TestDateTimeParsing.OFFSET_0230)), Array(TestDateTimeParsing.INSTANT_WITH_PARIS, "2014-06-30T01:02:03Z", ZonedDateTime.of(2014, 6, 30, 1, 2, 3, 0, ZoneOffset.UTC).withZoneSameInstant(TestDateTimeParsing.PARIS)), Array(TestDateTimeParsing.INSTANT_WITH_0230, "2014-06-30T01:02:03Z", ZonedDateTime.of(2014, 6, 30, 1, 2, 3, 0, ZoneOffset.UTC).withZoneSameInstant(TestDateTimeParsing.OFFSET_0230)), Array(TestDateTimeParsing.INSTANT_OFFSETID, "2014-06-30T01:02:03Z +02:30", ZonedDateTime.of(2014, 6, 30, 1, 2, 3, 0, ZoneOffset.UTC).withZoneSameInstant(TestDateTimeParsing.OFFSET_0230)), Array(TestDateTimeParsing.INSTANT_OFFSETSECONDS, "2014-06-30T01:02:03Z 9000", ZonedDateTime.of(2014, 6, 30, 1, 2, 3, 0, ZoneOffset.UTC).withZoneSameInstant(TestDateTimeParsing.OFFSET_0230)), Array(TestDateTimeParsing.INSTANTSECONDS_WITH_PARIS, "86402", Instant.ofEpochSecond(86402).atZone(TestDateTimeParsing.PARIS)), Array(TestDateTimeParsing.INSTANTSECONDS_NOS_WITH_PARIS, "86402.123456789", Instant.ofEpochSecond(86402, 123456789).atZone(TestDateTimeParsing.PARIS)), Array(TestDateTimeParsing.INSTANTSECONDS_OFFSETSECONDS, "86402 9000", Instant.ofEpochSecond(86402).atZone(TestDateTimeParsing.OFFSET_0230))/*, Array(TestDateTimeParsing.INSTANT_OFFSETSECONDS_ZONE, "2016-10-30T00:30:00Z 7200 Europe/Paris", ZonedDateTime.ofStrict(LocalDateTime.of(2016, 10, 30, 2, 30), ZoneOffset.ofHours(2), TestDateTimeParsing.PARIS)), Array(TestDateTimeParsing.INSTANT_OFFSETSECONDS_ZONE, "2016-10-30T01:30:00Z 3600 Europe/Paris", ZonedDateTime.ofStrict(LocalDateTime.of(2016, 10, 30, 2, 30), ZoneOffset.ofHours(1), TestDateTimeParsing.PARIS))*/)
7778
}
7879

7980
@Test(dataProvider = "instantZones") def test_parse_instantZones_ZDT(formatter: DateTimeFormatter, text: String, expected: ZonedDateTime): Unit = {

shared/src/main/scala/org/threeten/bp/Instant.scala

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ object Instant {
7676
private val NANOS_PER_SECOND: Int = 1000000000
7777
/** Constant for nanos per milli. */
7878
private val NANOS_PER_MILLI: Int = 1000000
79+
/** Constant for millis per sec. */
80+
private val MILLIS_PER_SEC = 1000
7981

8082
/** The minimum supported {@code Instant}, '-1000000000-01-01T00:00Z'.
8183
* This could be used by an application as a "far past" instant.
@@ -594,7 +596,8 @@ final class Instant private(private val seconds: Long, private val nanos: Int) e
594596
throw new DateTimeException("Unit must divide into a standard day without remainder")
595597
}
596598
val nod: Long = (seconds % LocalTime.SECONDS_PER_DAY) * LocalTime.NANOS_PER_SECOND + nanos
597-
val result: Long = (nod / dur) * dur
599+
val result: Long = Math.floorDiv(nod, dur) * dur
600+
598601
plusNanos(result - nod)
599602
}
600603

@@ -928,10 +931,20 @@ final class Instant private(private val seconds: Long, private val nanos: Int) e
928931
* @return the number of milliseconds since the epoch of 1970-01-01T00:00:00Z
929932
* @throws ArithmeticException if numeric overflow occurs
930933
*/
931-
def toEpochMilli: Long = {
932-
val millis: Long = Math.multiplyExact(seconds, 1000)
933-
millis + nanos / Instant.NANOS_PER_MILLI
934-
}
934+
def toEpochMilli: Long =
935+
if (seconds >= 0) {
936+
val millis: Long = Math.multiplyExact(seconds, Instant.MILLIS_PER_SEC)
937+
Math.addExact(millis, nanos / Instant.NANOS_PER_MILLI)
938+
} else {
939+
// prevent an overflow in seconds * 1000
940+
// instead of going form the second farther away from 0
941+
// going toward 0
942+
// we go from the second closer to 0 away from 0
943+
// that way we always stay in the valid long range
944+
// seconds + 1 can not overflow because it is negative
945+
val millis = Math.multiplyExact(seconds + 1, Instant.MILLIS_PER_SEC)
946+
Math.subtractExact(millis, Instant.MILLIS_PER_SEC - nanos / Instant.NANOS_PER_MILLI)
947+
}
935948

936949
/** Compares this instant to the specified instant.
937950
*

0 commit comments

Comments
 (0)