Scala Java-Time

Build Status Maven Central Scala.js

This project provides an implementation of the java.time package, a date and time library that was added in Java 8. The implementation is based on the original BSD-licensed reference implementation (before it was contributed to OpenJDK).

Example

import java.time._
// import java.time._

// always returns 2009-02-13T23:31:30
val fixedClock = Clock.fixed(Instant.ofEpochSecond(1234567890L), ZoneOffset.ofHours(0))
// fixedClock: java.time.Clock = FixedClock[2009-02-13T23:31:30Z,Z]

val date = LocalDateTime.now(fixedClock)
// date: java.time.LocalDateTime = 2009-02-13T23:31:30

date.getMonth      == Month.FEBRUARY
// res1: Boolean = true

date.getDayOfWeek  == DayOfWeek.FRIDAY
// res2: Boolean = true

date.getDayOfMonth == 13
// res3: Boolean = true

date.getHour       == 23
// res4: Boolean = true

val tomorrow = date.plusDays(1)
// tomorrow: java.time.LocalDateTime = 2009-02-14T23:31:30

val duration = Duration.between(date, tomorrow)
// duration: java.time.Duration = PT24H

duration.toMinutes == 1440L
// res5: Boolean = true

val period = Period.between(date.toLocalDate, tomorrow.toLocalDate)
// period: java.time.Period = P1D

period.get(temporal.ChronoUnit.DAYS) == 1L
// res6: Boolean = true

val date1 = LocalDate.of(2001, 1, 31)
// date1: java.time.LocalDate = 2001-01-31

date1.plusMonths(1) == LocalDate.of(2001, 2, 28)
// res7: Boolean = true

val date2 = date1.`with`(temporal.TemporalAdjusters.next(DayOfWeek.SUNDAY))
// date2: java.time.LocalDate = 2001-02-04

date2 == LocalDate.of(2001, 2, 4)
// res8: Boolean = true

val offsetTime = OffsetTime.of(date.toLocalTime, ZoneOffset.ofHours(1))
// offsetTime: java.time.OffsetTime = 23:31:30+01:00

offsetTime.isBefore(OffsetTime.of(date.toLocalTime, ZoneOffset.ofHours(0))) == true
// res9: Boolean = true

val format1 = format.DateTimeFormatter.ofPattern("MMMM MM d HH mm ss EE EEEE yyyy G", java.util.Locale.GERMAN)
// format1: java.time.format.DateTimeFormatter = Text(MonthOfYear)' 'Value(MonthOfYear,2)' 'Value(DayOfMonth)' 'Value(HourOfDay,2)' 'Value(MinuteOfHour,2)' 'Value(SecondOfMinute,2)' 'Text(DayOfWeek,SHORT)' 'Text(DayOfWeek)' 'Value(YearOfEra,4,19,EXCEEDS_PAD)' 'Text(Era,SHORT)

date.format(format1) == "Februar 02 13 23 31 30 Fr. Freitag 2009 n. Chr."
// res10: Boolean = false

chrono.JapaneseDate.now(fixedClock).toString     == "Japanese Heisei 21-02-13"
// res11: Boolean = true

chrono.ThaiBuddhistDate.now(fixedClock).toString == "ThaiBuddhist BE 2552-02-13"
// res12: Boolean = true

chrono.MinguoDate.now(fixedClock).toString       == "Minguo ROC 98-02-13"
// res13: Boolean = true

Usage

The scala-java-time library is currently available for Scala (JVM, version 8 and later) and Scala.js (JavaScript). Both Scala 2.11 and Scala 2.12 (2.0.0-M8 and later) are supported.

To get started with SBT, add one of these dependencies:

  • libraryDependencies += "io.github.cquiroz" %% "scala-java-time" % "2.0.0-RC2" (for Scala)
  • libraryDependencies += "io.github.cquiroz" %%% "scala-java-time" % "2.0.0-RC2" (for Scala.js, Scala.js plugin required)

To get the latest snapshots add the repo

resolvers +=
  Resolver.sonatypeRepo("snapshots")

and either:

  • libraryDependencies += "io.github.cquiroz" %% "scala-java-time" % "2.0.0-RC3-SNAPSHOT" (for Scala)
  • libraryDependencies += "io.github.cquiroz" %%% "scala-java-time" % "2.0.0-RC3-SNAPSHOT" (for Scala.js, Scala.js plugin required)

Time zones

No timezones

If you don’t need to use timezones in your application you can just stop here. By default UTC will always be available but otherwise the library will work fine and produce the smallest possible js file

Time-zone data (JS) alternative I (All timezones)

The timezone for js is provided in a separate bundle which contains all time zones available from IANA Time Zone Database. To use them you need to add the following dependency

  • libraryDependencies += "io.github.cquiroz" %%% "scala-java-time-tzdb" % "2.0.0-RC2_2019a" (for Scala.js, Scala.js plugin required)

Note that the db is fairly large and due to the characteristics of the API it’s not very ammenable to optimization This database is published every now and then so it maybe old. For current version see the following section.

Time-zone data (JS) alternative II (Selective timezones)

It is possible to build a custom tz db for your application using sbt-tzdb. This has two big benefits:

  • You can select exactly what version of tzdb to use. Eventually you can you use the latest always.
  • You can filter the time zones relevant to your application. This can dramatically reduce your js size

To do that you need to:

  • Add sbt-tzdb to your list of plugins (Note you need sbt 1.x)
addSbtPlugin("io.github.cquiroz" % "sbt-tzdb" % "0.3.2")
  • Enable the plugin for your Scala.js project:
  .enablePlugins(TzdbPlugin)

or for cross projects, enable it only one the js side

lazy val lib = crossProject(JVMPlatform, JSPlatform)
  ...

lazy val libJVM = lib.jvm
lazy val libJS  = lib.js.enablePlugins(TzdbPlugin)

This will build a tzdb exactly as on step 1 with all timezones. However you can filter the zones you want, e.g. add to your build:

zonesFilter := {(z: String) => z == "America/Santiago" || z == "Pacific/Honolulu"},

Time-zone data (JVM)

The time-zone database is stored as a pre-compiled dat file that is included in the built jar. The version of the time-zone data used is stored within the dat file (near the start). Updating the time-zone database involves using the TzdbZoneRulesCompiler class and re-compiling the jar file. Pull requests with later versions of the dat file will be accepted.

Building

This project builds using sbt. Run sbt scalajavatimeTestsJVM/test to run the test suite on the JVM and sbt scalajavatimeTestsJS/test to run the test suite in JavaScript.

Contributing

We welcome all contributions, including ideas, suggestions, bug reports, bug fixes and code! We are especially interested in contributions that tackle the following issues:

  • Find ways to reduce the size of the library
  • Implement missing methods

Have a look at the issues or issues to find something to work on! Let us know if you need help!

Plans

2.0

A stable release of 2.0 will be published with only java.time on its binary after RC3 is published.

FAQs

What’s with the packages? the code uses org.threeten.bp but I use java.time

The original code was in the org.threeten.bp and that has been maintained, among other reasons, because writing code on the java namespace tends to produce issues with the security controls of the JVM

Thus the code is on org.threeten.bp but during packaging the code is moved to java.time and org.threeten.bp is removed.

Most applications would use the java.time package mirroring the JVM

Is this project derived from OpenJDK?

No. This project is derived from the Reference Implementation previously hosted on GitHub. That project had a BSD license, which has been preserved here. Thus, this project is a fork of the original code before entry to OpenJDK.

What is the relation to this project

This is a fork from the original project aim to complete the API to work on Scala.js

Are there are differences with the Java Time API?

The project aims to be an exact port of the java time API to scala. The only differences are classes not on the official java API but still present as private, e.g. DateTimeTextProvider in the format package that have been moved to the internal package to ease compatibility across versions