diff options
author | Arthur Rand <arand@ucsc.edu> | 2018-03-28 05:56:21 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-03-28 05:56:21 -0700 |
commit | fc6ecfe212c84271a3454617054aaf25890e886a (patch) | |
tree | 4d6b85e059e10aa5b461af9e21c32c84bd73250f /src/main/scala/xyz/driver/core/time.scala | |
parent | 30dba9ebf2abfd06452f46bac2b4c922043f56e6 (diff) | |
download | driver-core-fc6ecfe212c84271a3454617054aaf25890e886a.tar.gz driver-core-fc6ecfe212c84271a3454617054aaf25890e886a.tar.bz2 driver-core-fc6ecfe212c84271a3454617054aaf25890e886a.zip |
[API-1468] add TimeOfDay (#141)v1.8.11
* add TimeOfDay
* add formatter
* .
* Revert "."
This reverts commit 89576de98092dd75d3af7d82d244d5eaa24d31d9.
* scalafmt
* add before and after to ToD, and tests
* rearrage, make fromStrings
* add generator
* address comments
* use explicit string for TimeZoneId
* renaming
* revert Converters changes
* change name of private method
* change apply method
* use month
Diffstat (limited to 'src/main/scala/xyz/driver/core/time.scala')
-rw-r--r-- | src/main/scala/xyz/driver/core/time.scala | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/src/main/scala/xyz/driver/core/time.scala b/src/main/scala/xyz/driver/core/time.scala index 3bcc7bc..bab304d 100644 --- a/src/main/scala/xyz/driver/core/time.scala +++ b/src/main/scala/xyz/driver/core/time.scala @@ -4,7 +4,10 @@ import java.text.SimpleDateFormat import java.util._ import java.util.concurrent.TimeUnit +import xyz.driver.core.date.Month + import scala.concurrent.duration._ +import scala.util.Try object time { @@ -39,6 +42,90 @@ object time { } } + /** + * Encapsulates a time and timezone without a specific date. + */ + final case class TimeOfDay(localTime: java.time.LocalTime, timeZone: TimeZone) { + + /** + * Is this time before another time on a specific day. Day light savings safe. These are zero-indexed + * for month/day. + */ + def isBefore(other: TimeOfDay, day: Int, month: Month, year: Int): Boolean = { + toCalendar(day, month, year).before(other.toCalendar(day, month, year)) + } + + /** + * Is this time after another time on a specific day. Day light savings safe. + */ + def isAfter(other: TimeOfDay, day: Int, month: Month, year: Int): Boolean = { + toCalendar(day, month, year).after(other.toCalendar(day, month, year)) + } + + def sameTimeAs(other: TimeOfDay, day: Int, month: Month, year: Int): Boolean = { + toCalendar(day, month, year).equals(other.toCalendar(day, month, year)) + } + + /** + * Enforces the same formatting as expected by [[java.sql.Time]] + * @return string formatted for `java.sql.Time` + */ + def timeString: String = { + localTime.format(TimeOfDay.getFormatter) + } + + /** + * @return a string parsable by [[java.util.TimeZone]] + */ + def timeZoneString: String = { + timeZone.getID + } + + /** + * @return this [[TimeOfDay]] as [[java.sql.Time]] object, [[java.sql.Time.valueOf]] will + * throw when the string is not valid, but this is protected by [[timeString]] method. + */ + def toTime: java.sql.Time = { + java.sql.Time.valueOf(timeString) + } + + private def toCalendar(day: Int, month: Int, year: Int): Calendar = { + val cal = Calendar.getInstance(timeZone) + cal.set(year, month, day, localTime.getHour, localTime.getMinute, localTime.getSecond) + cal + } + } + + object TimeOfDay { + def now(): TimeOfDay = { + TimeOfDay(java.time.LocalTime.now(), TimeZone.getDefault) + } + + /** + * Throws when [s] is not parsable by [[java.time.LocalTime.parse]], uses default [[java.util.TimeZone]] + */ + def parseTimeString(tz: TimeZone = TimeZone.getDefault)(s: String): TimeOfDay = { + TimeOfDay(java.time.LocalTime.parse(s), tz) + } + + def fromString(tz: TimeZone)(s: String): Option[TimeOfDay] = { + val op = Try(java.time.LocalTime.parse(s)).toOption + op.map(lt => TimeOfDay(lt, tz)) + } + + def fromStrings(zoneId: String)(s: String): Option[TimeOfDay] = { + val op = Try(TimeZone.getTimeZone(zoneId)).toOption + op.map(tz => TimeOfDay.parseTimeString(tz)(s)) + } + + /** + * Formatter that enforces `HH:mm:ss` which is expected by [[java.sql.Time]] + */ + def getFormatter: java.time.format.DateTimeFormatter = { + java.time.format.DateTimeFormatter.ofPattern("HH:mm:ss") + } + } + object Time { implicit def timeOrdering: Ordering[Time] = Ordering.by(_.millis) |