From 54857e80c605200f14e62c596bb943ecc296fdd0 Mon Sep 17 00:00:00 2001 From: Stewart Stewart Date: Sat, 17 Dec 2016 00:00:12 -0500 Subject: add date providing simple Date case class --- src/main/scala/xyz/driver/core/date.scala | 37 +++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 src/main/scala/xyz/driver/core/date.scala (limited to 'src/main/scala/xyz/driver/core/date.scala') diff --git a/src/main/scala/xyz/driver/core/date.scala b/src/main/scala/xyz/driver/core/date.scala new file mode 100644 index 0000000..3d38aff --- /dev/null +++ b/src/main/scala/xyz/driver/core/date.scala @@ -0,0 +1,37 @@ +package xyz.driver.core + +import java.util.Calendar + +import scalaz.{@@, Tag} + +object date { + + type Month = Int @@ Month.type + private[date] def tagMonth(value: Int): Month = Tag.of[Month.type](value) + + object Month { + val JANUARY = tagMonth(Calendar.JANUARY) + val FEBRUARY = tagMonth(Calendar.FEBRUARY) + val MARCH = tagMonth(Calendar.MARCH) + val APRIL = tagMonth(Calendar.APRIL) + val MAY = tagMonth(Calendar.MAY) + val JUNE = tagMonth(Calendar.JUNE) + val JULY = tagMonth(Calendar.JULY) + val AUGUST = tagMonth(Calendar.AUGUST) + val SEPTEMBER = tagMonth(Calendar.SEPTEMBER) + val OCTOBER = tagMonth(Calendar.OCTOBER) + val DECEMBER = tagMonth(Calendar.DECEMBER) + } + + final case class Date(year: Int, month: Month, day: Int) { + def iso8601: String = f"$year%04d-${Tag.unwrap(month) + 1}%02d-$day%02d" + } + + object Date { + def fromJavaDate(date: java.util.Date) = { + val cal = Calendar.getInstance() + cal.setTime(date) + Date(cal.get(Calendar.YEAR), tagMonth(cal.get(Calendar.MONTH)), cal.get(Calendar.DAY_OF_MONTH)) + } + } +} -- cgit v1.2.3 From 1cab0ee11c8bcee14103dbd0fb5e350241b9d260 Mon Sep 17 00:00:00 2001 From: Stewart Stewart Date: Sat, 17 Dec 2016 00:49:52 -0500 Subject: add database-date integration --- src/main/scala/xyz/driver/core/database.scala | 4 ++++ src/main/scala/xyz/driver/core/date.scala | 8 ++++++++ 2 files changed, 12 insertions(+) (limited to 'src/main/scala/xyz/driver/core/date.scala') diff --git a/src/main/scala/xyz/driver/core/database.scala b/src/main/scala/xyz/driver/core/database.scala index a82e345..ee87784 100644 --- a/src/main/scala/xyz/driver/core/database.scala +++ b/src/main/scala/xyz/driver/core/database.scala @@ -4,6 +4,7 @@ import slick.backend.DatabaseConfig import slick.dbio.{DBIOAction, NoStream} import slick.driver.JdbcProfile import xyz.driver.core.time.Time +import xyz.driver.core.date.Date import scala.concurrent.{ExecutionContext, Future} import scalaz.Monad @@ -43,6 +44,9 @@ object database { implicit def `xyz.driver.core.time.Time.columnType`: BaseColumnType[Time] = MappedColumnType.base[Time, Long](_.millis, Time(_)) + + implicit def `xyz.driver.core.time.Date.columnType`: BaseColumnType[Date] = + MappedColumnType.base[Date, java.sql.Date](_.toJavaSqlDate, Date.fromJavaDate(_)) } object ColumnTypes { diff --git a/src/main/scala/xyz/driver/core/date.scala b/src/main/scala/xyz/driver/core/date.scala index 3d38aff..05d139d 100644 --- a/src/main/scala/xyz/driver/core/date.scala +++ b/src/main/scala/xyz/driver/core/date.scala @@ -25,6 +25,14 @@ object date { final case class Date(year: Int, month: Month, day: Int) { def iso8601: String = f"$year%04d-${Tag.unwrap(month) + 1}%02d-$day%02d" + def toJavaSqlDate = new java.sql.Date(toJavaDate.getTime) + def toJavaDate: java.util.Date = { + val cal = Calendar.getInstance() + cal.set(Calendar.YEAR, year - 1900) + cal.set(Calendar.MONTH, Tag.unwrap(month)) + cal.set(Calendar.DAY_OF_MONTH, day) + cal.getTime + } } object Date { -- cgit v1.2.3 From bb7e18fe7998556086863acc0957056079363d4a Mon Sep 17 00:00:00 2001 From: Stewart Stewart Date: Sat, 17 Dec 2016 01:39:12 -0500 Subject: use core.tagging for months --- src/main/scala/xyz/driver/core/core.scala | 5 +++++ src/main/scala/xyz/driver/core/date.scala | 8 +++----- 2 files changed, 8 insertions(+), 5 deletions(-) (limited to 'src/main/scala/xyz/driver/core/date.scala') diff --git a/src/main/scala/xyz/driver/core/core.scala b/src/main/scala/xyz/driver/core/core.scala index 8ae9122..2b61689 100644 --- a/src/main/scala/xyz/driver/core/core.scala +++ b/src/main/scala/xyz/driver/core/core.scala @@ -20,6 +20,11 @@ package object core { resource.close() } } + + object tagging { + private[core] trait Tagged[+V, +Tag] + } + type @@[+V, +Tag] = V with tagging.Tagged[V, Tag] } package core { diff --git a/src/main/scala/xyz/driver/core/date.scala b/src/main/scala/xyz/driver/core/date.scala index 05d139d..b423585 100644 --- a/src/main/scala/xyz/driver/core/date.scala +++ b/src/main/scala/xyz/driver/core/date.scala @@ -2,12 +2,10 @@ package xyz.driver.core import java.util.Calendar -import scalaz.{@@, Tag} - object date { type Month = Int @@ Month.type - private[date] def tagMonth(value: Int): Month = Tag.of[Month.type](value) + private[date] def tagMonth(value: Int): Month = value.asInstanceOf[Month] object Month { val JANUARY = tagMonth(Calendar.JANUARY) @@ -24,12 +22,12 @@ object date { } final case class Date(year: Int, month: Month, day: Int) { - def iso8601: String = f"$year%04d-${Tag.unwrap(month) + 1}%02d-$day%02d" + def iso8601: String = f"$year%04d-${month + 1}%02d-$day%02d" def toJavaSqlDate = new java.sql.Date(toJavaDate.getTime) def toJavaDate: java.util.Date = { val cal = Calendar.getInstance() cal.set(Calendar.YEAR, year - 1900) - cal.set(Calendar.MONTH, Tag.unwrap(month)) + cal.set(Calendar.MONTH, month) cal.set(Calendar.DAY_OF_MONTH, day) cal.getTime } -- cgit v1.2.3 From 53d04d4255489bd5802dc91d9dbebddd206d630b Mon Sep 17 00:00:00 2001 From: Stewart Stewart Date: Sat, 17 Dec 2016 02:11:18 -0500 Subject: add json format for date (ISO) --- src/main/scala/xyz/driver/core/date.scala | 7 ++++++- src/main/scala/xyz/driver/core/json.scala | 17 +++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) (limited to 'src/main/scala/xyz/driver/core/date.scala') diff --git a/src/main/scala/xyz/driver/core/date.scala b/src/main/scala/xyz/driver/core/date.scala index b423585..0cf8986 100644 --- a/src/main/scala/xyz/driver/core/date.scala +++ b/src/main/scala/xyz/driver/core/date.scala @@ -23,7 +23,7 @@ object date { final case class Date(year: Int, month: Month, day: Int) { def iso8601: String = f"$year%04d-${month + 1}%02d-$day%02d" - def toJavaSqlDate = new java.sql.Date(toJavaDate.getTime) + def toJavaSqlDate = new java.sql.Date(toJavaDate.getTime) def toJavaDate: java.util.Date = { val cal = Calendar.getInstance() cal.set(Calendar.YEAR, year - 1900) @@ -34,6 +34,11 @@ object date { } object Date { + def parseIso(iso: String): Option[Date] = { + util.Try(iso.split("-").map(_.toInt)).toOption collect { + case Array(year, month, day) => Date(year, tagMonth(month), day) + } + } def fromJavaDate(date: java.util.Date) = { val cal = Calendar.getInstance() cal.setTime(date) diff --git a/src/main/scala/xyz/driver/core/json.scala b/src/main/scala/xyz/driver/core/json.scala index 277543b..ecd7cce 100644 --- a/src/main/scala/xyz/driver/core/json.scala +++ b/src/main/scala/xyz/driver/core/json.scala @@ -7,6 +7,7 @@ import akka.http.scaladsl.unmarshalling.Unmarshaller import spray.json.{DeserializationException, JsNumber, _} import xyz.driver.core.revision.Revision import xyz.driver.core.time.Time +import xyz.driver.core.date.Date import scala.reflect.runtime.universe._ @@ -66,6 +67,22 @@ object json { } } + implicit val dateFormat = new RootJsonFormat[Date] { + def write(date: Date) = JsObject("calendarDate" -> JsString(date.iso8601)) + + def read(value: JsValue): Date = value match { + case JsObject(fields) => + fields + .get("calendarDate") + .flatMap { + case JsString(iso) => Date.parseIso(iso) + case _ => None + } + .getOrElse(throw DeserializationException("Date expects YYYY-MM-DD")) + case _ => throw DeserializationException("Date expects YYYY-MM-DD") + } + } + def RevisionInPath[T]: PathMatcher1[Revision[T]] = PathMatcher("""[\da-fA-F]{8}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{12}""".r) flatMap { string => Some(Revision[T](string)) -- cgit v1.2.3 From 2f6a2d763732285dc1cffb0d3a435a9e9c96cbd2 Mon Sep 17 00:00:00 2001 From: Stewart Stewart Date: Mon, 19 Dec 2016 16:25:10 -0500 Subject: serialize date to json as object with three fields --- src/main/scala/xyz/driver/core/date.scala | 8 +------- src/main/scala/xyz/driver/core/json.scala | 20 ++++++-------------- 2 files changed, 7 insertions(+), 21 deletions(-) (limited to 'src/main/scala/xyz/driver/core/date.scala') diff --git a/src/main/scala/xyz/driver/core/date.scala b/src/main/scala/xyz/driver/core/date.scala index 0cf8986..b954749 100644 --- a/src/main/scala/xyz/driver/core/date.scala +++ b/src/main/scala/xyz/driver/core/date.scala @@ -5,7 +5,7 @@ import java.util.Calendar object date { type Month = Int @@ Month.type - private[date] def tagMonth(value: Int): Month = value.asInstanceOf[Month] + private[core] def tagMonth(value: Int): Month = value.asInstanceOf[Month] object Month { val JANUARY = tagMonth(Calendar.JANUARY) @@ -22,7 +22,6 @@ object date { } final case class Date(year: Int, month: Month, day: Int) { - def iso8601: String = f"$year%04d-${month + 1}%02d-$day%02d" def toJavaSqlDate = new java.sql.Date(toJavaDate.getTime) def toJavaDate: java.util.Date = { val cal = Calendar.getInstance() @@ -34,11 +33,6 @@ object date { } object Date { - def parseIso(iso: String): Option[Date] = { - util.Try(iso.split("-").map(_.toInt)).toOption collect { - case Array(year, month, day) => Date(year, tagMonth(month), day) - } - } def fromJavaDate(date: java.util.Date) = { val cal = Calendar.getInstance() cal.setTime(date) diff --git a/src/main/scala/xyz/driver/core/json.scala b/src/main/scala/xyz/driver/core/json.scala index ecd7cce..fee7341 100644 --- a/src/main/scala/xyz/driver/core/json.scala +++ b/src/main/scala/xyz/driver/core/json.scala @@ -7,7 +7,7 @@ import akka.http.scaladsl.unmarshalling.Unmarshaller import spray.json.{DeserializationException, JsNumber, _} import xyz.driver.core.revision.Revision import xyz.driver.core.time.Time -import xyz.driver.core.date.Date +import xyz.driver.core.date.Month import scala.reflect.runtime.universe._ @@ -67,19 +67,11 @@ object json { } } - implicit val dateFormat = new RootJsonFormat[Date] { - def write(date: Date) = JsObject("calendarDate" -> JsString(date.iso8601)) - - def read(value: JsValue): Date = value match { - case JsObject(fields) => - fields - .get("calendarDate") - .flatMap { - case JsString(iso) => Date.parseIso(iso) - case _ => None - } - .getOrElse(throw DeserializationException("Date expects YYYY-MM-DD")) - case _ => throw DeserializationException("Date expects YYYY-MM-DD") + implicit val dateFormat = new RootJsonFormat[Month] { + def write(month: Month) = JsNumber(month) + def read(value: JsValue): Month = value match { + case JsNumber(month) if 0 <= month && month <= 11 => date.tagMonth(month.toInt) + case _ => throw DeserializationException("Month is a 0-based number") } } -- cgit v1.2.3 From 514c334dcd3a8b98f41610709b9cafd761899778 Mon Sep 17 00:00:00 2001 From: Stewart Stewart Date: Mon, 19 Dec 2016 18:09:52 -0500 Subject: move java date helpers out of date.Date --- .../scala/xyz/driver/core/database/database.scala | 2 +- .../scala/xyz/driver/core/database/package.scala | 17 ++++++++++++++ src/main/scala/xyz/driver/core/date.scala | 26 +++++++++------------- src/main/scala/xyz/driver/core/time.scala | 2 +- 4 files changed, 29 insertions(+), 18 deletions(-) (limited to 'src/main/scala/xyz/driver/core/date.scala') diff --git a/src/main/scala/xyz/driver/core/database/database.scala b/src/main/scala/xyz/driver/core/database/database.scala index 3db9c9e..a8aec63 100644 --- a/src/main/scala/xyz/driver/core/database/database.scala +++ b/src/main/scala/xyz/driver/core/database/database.scala @@ -39,7 +39,7 @@ package database { MappedColumnType.base[Time, Long](_.millis, Time(_)) implicit def `xyz.driver.core.time.Date.columnType`: BaseColumnType[Date] = - MappedColumnType.base[Date, java.sql.Date](_.toJavaSqlDate, Date.fromJavaDate(_)) + MappedColumnType.base[Date, java.sql.Date](dateToSqlDate(_), sqlDateToDate(_)) } object ColumnTypes { diff --git a/src/main/scala/xyz/driver/core/database/package.scala b/src/main/scala/xyz/driver/core/database/package.scala index a664cff..295e556 100644 --- a/src/main/scala/xyz/driver/core/database/package.scala +++ b/src/main/scala/xyz/driver/core/database/package.scala @@ -1,8 +1,25 @@ +package xyz.driver.core + +import java.sql.{Date => SqlDate} +import java.util.Calendar + +import date.{Date, javaDateToDate} import slick.dbio.{DBIOAction, NoStream} + package object database { type Schema = { def create: DBIOAction[Unit, NoStream, slick.dbio.Effect.Schema] def drop: DBIOAction[Unit, NoStream, slick.dbio.Effect.Schema] } + + private[database] def sqlDateToDate(date: SqlDate): Date = javaDateToDate(date) + + private[database] def dateToSqlDate(date: Date): SqlDate = { + val cal = Calendar.getInstance() + cal.set(Calendar.YEAR, date.year - 1900) + cal.set(Calendar.MONTH, date.month) + cal.set(Calendar.DAY_OF_MONTH, date.day) + new SqlDate(cal.getTime.getTime) + } } diff --git a/src/main/scala/xyz/driver/core/date.scala b/src/main/scala/xyz/driver/core/date.scala index b954749..476cd13 100644 --- a/src/main/scala/xyz/driver/core/date.scala +++ b/src/main/scala/xyz/driver/core/date.scala @@ -21,22 +21,16 @@ object date { val DECEMBER = tagMonth(Calendar.DECEMBER) } - final case class Date(year: Int, month: Month, day: Int) { - def toJavaSqlDate = new java.sql.Date(toJavaDate.getTime) - def toJavaDate: java.util.Date = { - val cal = Calendar.getInstance() - cal.set(Calendar.YEAR, year - 1900) - cal.set(Calendar.MONTH, month) - cal.set(Calendar.DAY_OF_MONTH, day) - cal.getTime - } - } + final case class Date(year: Int, month: Month, day: Int) - object Date { - def fromJavaDate(date: java.util.Date) = { - val cal = Calendar.getInstance() - cal.setTime(date) - Date(cal.get(Calendar.YEAR), tagMonth(cal.get(Calendar.MONTH)), cal.get(Calendar.DAY_OF_MONTH)) - } + private[core] def javaDateToDate(javaDate: java.util.Date): Date = { + val cal = Calendar.getInstance() + cal.setTime(javaDate) + Date( + cal.get(Calendar.YEAR), + date.tagMonth(cal.get(Calendar.MONTH)), + cal.get(Calendar.DAY_OF_MONTH)) } + + } diff --git a/src/main/scala/xyz/driver/core/time.scala b/src/main/scala/xyz/driver/core/time.scala index 9d3f655..6d76939 100644 --- a/src/main/scala/xyz/driver/core/time.scala +++ b/src/main/scala/xyz/driver/core/time.scala @@ -27,7 +27,7 @@ object time { def advanceBy(duration: Duration): Time = Time(millis + duration.toMillis) - def toDate: date.Date = date.Date.fromJavaDate(new java.util.Date(millis)) + def toDate: date.Date = date.javaDateToDate(new java.util.Date(millis)) } final case class TimeRange(start: Time, end: Time) { -- cgit v1.2.3 From d63fd7ef92b67dec5ea72f26d73d56cec676bd82 Mon Sep 17 00:00:00 2001 From: Stewart Stewart Date: Mon, 19 Dec 2016 18:43:07 -0500 Subject: scalafmt --- src/main/scala/xyz/driver/core/database/package.scala | 1 - src/main/scala/xyz/driver/core/date.scala | 6 +----- src/main/scala/xyz/driver/core/json.scala | 2 +- 3 files changed, 2 insertions(+), 7 deletions(-) (limited to 'src/main/scala/xyz/driver/core/date.scala') diff --git a/src/main/scala/xyz/driver/core/database/package.scala b/src/main/scala/xyz/driver/core/database/package.scala index 295e556..2041b85 100644 --- a/src/main/scala/xyz/driver/core/database/package.scala +++ b/src/main/scala/xyz/driver/core/database/package.scala @@ -6,7 +6,6 @@ import java.util.Calendar import date.{Date, javaDateToDate} import slick.dbio.{DBIOAction, NoStream} - package object database { type Schema = { def create: DBIOAction[Unit, NoStream, slick.dbio.Effect.Schema] diff --git a/src/main/scala/xyz/driver/core/date.scala b/src/main/scala/xyz/driver/core/date.scala index 476cd13..437729f 100644 --- a/src/main/scala/xyz/driver/core/date.scala +++ b/src/main/scala/xyz/driver/core/date.scala @@ -26,11 +26,7 @@ object date { private[core] def javaDateToDate(javaDate: java.util.Date): Date = { val cal = Calendar.getInstance() cal.setTime(javaDate) - Date( - cal.get(Calendar.YEAR), - date.tagMonth(cal.get(Calendar.MONTH)), - cal.get(Calendar.DAY_OF_MONTH)) + Date(cal.get(Calendar.YEAR), date.tagMonth(cal.get(Calendar.MONTH)), cal.get(Calendar.DAY_OF_MONTH)) } - } diff --git a/src/main/scala/xyz/driver/core/json.scala b/src/main/scala/xyz/driver/core/json.scala index fee7341..c51e855 100644 --- a/src/main/scala/xyz/driver/core/json.scala +++ b/src/main/scala/xyz/driver/core/json.scala @@ -71,7 +71,7 @@ object json { def write(month: Month) = JsNumber(month) def read(value: JsValue): Month = value match { case JsNumber(month) if 0 <= month && month <= 11 => date.tagMonth(month.toInt) - case _ => throw DeserializationException("Month is a 0-based number") + case _ => throw DeserializationException("Month is a 0-based number") } } -- cgit v1.2.3 From f0a5e41ec45d2420ba7173e156806f81701f9796 Mon Sep 17 00:00:00 2001 From: Stewart Stewart Date: Tue, 20 Dec 2016 01:39:16 -0500 Subject: fix Time#toDate and sqlDateToDate --- src/main/scala/xyz/driver/core/database/package.scala | 10 ++++++++-- src/main/scala/xyz/driver/core/date.scala | 7 ------- src/main/scala/xyz/driver/core/time.scala | 4 ++-- 3 files changed, 10 insertions(+), 11 deletions(-) (limited to 'src/main/scala/xyz/driver/core/date.scala') diff --git a/src/main/scala/xyz/driver/core/database/package.scala b/src/main/scala/xyz/driver/core/database/package.scala index 7d9aecb..c88260b 100644 --- a/src/main/scala/xyz/driver/core/database/package.scala +++ b/src/main/scala/xyz/driver/core/database/package.scala @@ -3,7 +3,7 @@ package xyz.driver.core import java.sql.{Date => SqlDate} import java.util.Calendar -import date.{Date, javaDateToDate} +import date.Date import slick.dbio.{DBIOAction, NoStream} package object database { @@ -13,7 +13,13 @@ package object database { def drop: DBIOAction[Unit, NoStream, slick.dbio.Effect.Schema] } - private[database] def sqlDateToDate(date: SqlDate): Date = javaDateToDate(date) + private[database] def sqlDateToDate(sqlDate: SqlDate): Date = { + // NOTE: SQL date does not have a time component, so this date + // should only be interpreted in the running JVMs timezone. + val cal = Calendar.getInstance() + cal.setTime(sqlDate) + Date(cal.get(Calendar.YEAR), date.tagMonth(cal.get(Calendar.MONTH)), cal.get(Calendar.DAY_OF_MONTH)) + } private[database] def dateToSqlDate(date: Date): SqlDate = { val cal = Calendar.getInstance() diff --git a/src/main/scala/xyz/driver/core/date.scala b/src/main/scala/xyz/driver/core/date.scala index 437729f..ab19074 100644 --- a/src/main/scala/xyz/driver/core/date.scala +++ b/src/main/scala/xyz/driver/core/date.scala @@ -22,11 +22,4 @@ object date { } final case class Date(year: Int, month: Month, day: Int) - - private[core] def javaDateToDate(javaDate: java.util.Date): Date = { - val cal = Calendar.getInstance() - cal.setTime(javaDate) - Date(cal.get(Calendar.YEAR), date.tagMonth(cal.get(Calendar.MONTH)), cal.get(Calendar.DAY_OF_MONTH)) - } - } diff --git a/src/main/scala/xyz/driver/core/time.scala b/src/main/scala/xyz/driver/core/time.scala index 5dc16a0..cbb86ed 100644 --- a/src/main/scala/xyz/driver/core/time.scala +++ b/src/main/scala/xyz/driver/core/time.scala @@ -28,9 +28,9 @@ object time { def advanceBy(duration: Duration): Time = Time(millis + duration.toMillis) def toDate(timezone: TimeZone): date.Date = { - val cal = java.util.Calendar.getInstance(timezone) + val cal = Calendar.getInstance(timezone) cal.setTimeInMillis(millis) - date.javaDateToDate(cal.getTime()) + date.Date(cal.get(Calendar.YEAR), date.tagMonth(cal.get(Calendar.MONTH)), cal.get(Calendar.DAY_OF_MONTH)) } } -- cgit v1.2.3