Skip to content

Sync upstream #7

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Dec 22, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@
!/src/test/

**/TempTest.java
tzdb/
/.idea/
/threetenbp.iml
8 changes: 8 additions & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -173,10 +173,18 @@ lazy val pomData =
<name>Ludovic Hochet</name>
<url>https://github.com/lhochet</url>
</contributor>
<contributor>
<name>Matias Irland</name>
<url>https://github.com/matir91</url>
</contributor>
<contributor>
<name>Pap Lorinc</name>
<url>https://github.com/paplorinc</url>
</contributor>
<contributor>
<name>Philippe Marschall</name>
<url>https://github.com/marschall</url>
</contributor>
<contributor>
<name>Michael Nascimento Santos</name>
<url>https://github.com/sjmisterm</url>
Expand Down
6 changes: 6 additions & 0 deletions changes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,12 @@
</action>
</release>
<release version="1.3.3" date="SNAPSHOT" description="v1.3.3">
<action dev="jodastephen" type="update" >
Update to time-zone data 2016j.
</action>
<action dev="jodastephen" type="fix" >
Avoid referring to JDK internal packages.
</action>
<action dev="jodastephen" type="update" >
Update to time-zone data 2016f.
</action>
Expand Down
Binary file modified jvm/src/main/resources/org/threeten/bp/TZDB.dat
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ private[zone] object TzdbZoneRulesProvider {
*/
final class TzdbZoneRulesProvider extends ZoneRulesProvider {
/** All the regions that are available. */
private val regionIds: java.util.Set[String] = new CopyOnWriteArraySet[String]
private val regionIds: java.util.List[String] = new java.util.concurrent.CopyOnWriteArrayList[String]
/** All the versions that are available. */
private val versions: ConcurrentNavigableMap[String, TzdbZoneRulesProvider.Version] = new ConcurrentSkipListMap[String, TzdbZoneRulesProvider.Version]
/** All the URLs that have been loaded.
Expand Down
28 changes: 24 additions & 4 deletions jvm/src/test/scala/org/threeten/bp/TestInstant.scala
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import org.threeten.bp.temporal.ChronoUnit.NANOS
import org.threeten.bp.temporal.ChronoUnit.SECONDS
import java.util.Arrays
import java.util.Locale
import java.lang.{Long => JLong}
import org.testng.annotations.BeforeMethod
import org.testng.annotations.DataProvider
import org.testng.annotations.Test
Expand Down Expand Up @@ -250,14 +251,15 @@ object TestInstant {
Instant.ofEpochSecond(Long.MaxValue, Long.MaxValue)
}

@DataProvider(name = "MillisInstantNoNanos") private[bp] def provider_factory_millis_long: Array[Array[_ <: AnyRef]] = {
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))
@DataProvider(name = "MillisInstantNoNanos") private[bp] def provider_factory_millis_long = {
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))
}

@Test(dataProvider = "MillisInstantNoNanos") def factory_millis_long(millis: Long, expectedSeconds: Long, expectedNanoOfSecond: Int): Unit = {
val t: Instant = Instant.ofEpochMilli(millis)
@Test(dataProvider = "MillisInstantNoNanos") def factory_millis_long(millis: Long, nanos: Int, expectedSeconds: Long, expectedNanoOfSecond: Int): Unit = {
val t = Instant.ofEpochMilli(millis).plusNanos(nanos)
assertEquals(t.getEpochSecond, expectedSeconds)
assertEquals(t.getNano, expectedNanoOfSecond)
assertEquals(t.toEpochMilli, millis);
}

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

@Test
def test_truncatedTo(): Unit = {
assertEquals(Instant.ofEpochSecond(2L, 1000000).truncatedTo(ChronoUnit.SECONDS), Instant.ofEpochSecond(2L))
assertEquals(Instant.ofEpochSecond(2L, -1000000).truncatedTo(ChronoUnit.SECONDS), Instant.ofEpochSecond(1L))
assertEquals(Instant.ofEpochSecond(0L, -1000000).truncatedTo(ChronoUnit.SECONDS), Instant.ofEpochSecond(-1L))
assertEquals(Instant.ofEpochSecond(-1L).truncatedTo(ChronoUnit.SECONDS), Instant.ofEpochSecond(-1L))
assertEquals(Instant.ofEpochSecond(-1L, -1000000).truncatedTo(ChronoUnit.SECONDS), Instant.ofEpochSecond(-2L))
assertEquals(Instant.ofEpochSecond(-2L).truncatedTo(ChronoUnit.SECONDS), Instant.ofEpochSecond(-2L))
}

@Test def test_toEpochMilli(): Unit = {
assertEquals(Instant.ofEpochSecond(1L, 1000000).toEpochMilli, 1001L)
assertEquals(Instant.ofEpochSecond(1L, 2000000).toEpochMilli, 1002L)
Expand All @@ -600,10 +612,18 @@ object TestInstant {
Instant.ofEpochSecond(Long.MaxValue / 1000 + 1).toEpochMilli
}

@Test(expectedExceptions = Array(classOf[ArithmeticException])) def test_toEpochMilli_tooBigDueToNanos() {
Instant.ofEpochMilli(Long.MaxValue).plusMillis(1).toEpochMilli
}

@Test(expectedExceptions = Array(classOf[ArithmeticException])) def test_toEpochMilli_tooSmall(): Unit = {
Instant.ofEpochSecond(Long.MinValue / 1000 - 1).toEpochMilli
}

@Test(expectedExceptions = Array(classOf[ArithmeticException])) def test_toEpochMilli_tooSmallDueToNanos() {
Instant.ofEpochMilli(Long.MinValue).minusMillis(1).toEpochMilli
}

@Test def test_comparisons(): Unit = {
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))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,29 +106,59 @@ import org.threeten.bp.temporal.TemporalAdjusters
assertEquals(test, LocalDateTime.of(1890, 10, 29, 0, 0))
}

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

@Test(dataProvider = "japaneseEras") def test_Japanese_Eras(era: Era, eraValue: Int, name: String): Unit = {
assertEquals(era.getValue, eraValue, "EraValue")
assertEquals(era.toString, name, "Era Name")
assertEquals(era, JapaneseChronology.INSTANCE.eraOf(eraValue), "JapaneseChrono.eraOf()")
assertEquals(JapaneseEra.valueOf(name), era)
val eras: java.util.List[Era] = JapaneseChronology.INSTANCE.eras
assertTrue(eras.contains(era), "Era is not present in JapaneseChrono.INSTANCE.eras()")
assertTrue(eras.contains(era), "Era is not present in JapaneseChronology.INSTANCE.eras()")
}

@Test def test_Japanese_badEras(): Unit = {
val badEras: Array[Int] = Array(-1000, -998, -997, -2, 3, 4, 1000)
for (badEra <- badEras)
try {
val era: Era = JapaneseChronology.INSTANCE.eraOf(badEra)
fail(s"JapaneseChrono.eraOf returned $era + for invalid eraValue $badEra")
fail(s"JapaneseChronology.eraOf returned $era + for invalid eraValue $badEra")
} catch {
case ex: DateTimeException =>
}
try {
val era = JapaneseEra.valueOf("Rubbish")
fail("JapaneseEra.valueOf returned " + era + " + for invalid era name Rubbish")
} catch {
case _: IllegalArgumentException =>
// ignore expected exception
}
}

@Test def test_Japanese_registerEra() {
try {
JapaneseEra.registerEra(JapaneseEra.SHOWA.endDate, "TestAdditional")
fail("JapaneseEra.registerEra should have failed")
} catch {
case _: DateTimeException =>
// ignore expected exception
}
val additional = JapaneseEra.registerEra(LocalDate.of(2100, 1, 1), "TestAdditional")
assertEquals(JapaneseEra.of(3), additional)
assertEquals(JapaneseEra.valueOf("TestAdditional"), additional)
assertEquals(JapaneseEra.values(4), additional)
try {
JapaneseEra.registerEra(LocalDate.of(2200, 1, 1), "TestAdditional2")
fail("JapaneseEra.registerEra should have failed")

} catch {
case ex: DateTimeException =>
// ignore expected exception
}
}

@DataProvider(name = "toString") private[chrono] def data_toString: Array[Array[AnyRef]] =
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"))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,12 @@ object TestDateTimeParsing {
private val INSTANTSECONDS_NOS: DateTimeFormatter = new DateTimeFormatterBuilder().appendValue(INSTANT_SECONDS).appendLiteral('.').appendValue(NANO_OF_SECOND).toFormatter
private val INSTANTSECONDS_NOS_WITH_PARIS: DateTimeFormatter = INSTANTSECONDS_NOS.withZone(PARIS)
private val INSTANTSECONDS_OFFSETSECONDS: DateTimeFormatter = new DateTimeFormatterBuilder().appendValue(INSTANT_SECONDS).appendLiteral(' ').appendValue(OFFSET_SECONDS).toFormatter
//private val INSTANT_OFFSETSECONDS_ZONE = new DateTimeFormatterBuilder().appendInstant.appendLiteral(' ').appendValue(OFFSET_SECONDS).appendLiteral(' ').appendZoneId.toFormatter
}

@Test class TestDateTimeParsing {
@DataProvider(name = "instantZones") private[format] def data_instantZones: Array[Array[AnyRef]] = {
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[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))*/)
}

@Test(dataProvider = "instantZones") def test_parse_instantZones_ZDT(formatter: DateTimeFormatter, text: String, expected: ZonedDateTime): Unit = {
Expand Down
23 changes: 18 additions & 5 deletions shared/src/main/scala/org/threeten/bp/Instant.scala
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ object Instant {
private val NANOS_PER_SECOND: Int = 1000000000
/** Constant for nanos per milli. */
private val NANOS_PER_MILLI: Int = 1000000
/** Constant for millis per sec. */
private val MILLIS_PER_SEC = 1000

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

plusNanos(result - nod)
}

Expand Down Expand Up @@ -928,10 +931,20 @@ final class Instant private(private val seconds: Long, private val nanos: Int) e
* @return the number of milliseconds since the epoch of 1970-01-01T00:00:00Z
* @throws ArithmeticException if numeric overflow occurs
*/
def toEpochMilli: Long = {
val millis: Long = Math.multiplyExact(seconds, 1000)
millis + nanos / Instant.NANOS_PER_MILLI
}
def toEpochMilli: Long =
if (seconds >= 0) {
val millis: Long = Math.multiplyExact(seconds, Instant.MILLIS_PER_SEC)
Math.addExact(millis, nanos / Instant.NANOS_PER_MILLI)
} else {
// prevent an overflow in seconds * 1000
// instead of going form the second farther away from 0
// going toward 0
// we go from the second closer to 0 away from 0
// that way we always stay in the valid long range
// seconds + 1 can not overflow because it is negative
val millis = Math.multiplyExact(seconds + 1, Instant.MILLIS_PER_SEC)
Math.subtractExact(millis, Instant.MILLIS_PER_SEC - nanos / Instant.NANOS_PER_MILLI)
}

/** Compares this instant to the specified instant.
*
Expand Down
Loading