Skip to content
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

java8 date apis #111

Closed
fwbrasil opened this issue Jan 22, 2016 · 15 comments
Closed

java8 date apis #111

fwbrasil opened this issue Jan 22, 2016 · 15 comments

Comments

@fwbrasil
Copy link
Collaborator

Quill currently using java.util.Date

@godenji
Copy link
Contributor

godenji commented Mar 16, 2016

+1 using JodaTime currently and would like to remove the external dep (since java 8 date api is based on JodaTime)

@lvicentesanchez
Copy link
Contributor

are we aiming to only support Java8? For me it's a +1 but I would like to hear the opinion of others.

@fwbrasil
Copy link
Collaborator Author

+1 to Java 8 only

@lvicentesanchez
Copy link
Contributor

@fwbrasil btw... I noticed you removed -Ybackend:GenBCode, was it related to #267?

@fwbrasil
Copy link
Collaborator Author

@lvicentesanchez no, I've removed it because eclipse doesn't like it.

@ksilin
Copy link
Contributor

ksilin commented Apr 5, 2016

@godenji do you happen to have a working example of joda DateTime with Quill?

I try to provide the encoding with

implicit val decodeDateTime: MappedEncoding[String, DateTime] = mappedEncoding[String, DateTime](new DateTime(_))
implicit val encodeDateTime: MappedEncoding[DateTime, String] = mappedEncoding[DateTime, String](_.toString)

but still get the following error:

com.datastax.driver.core.exceptions.CodecNotFoundException: Codec not found for requested operation: [timestamp <-> java.lang.String]

Looking at the code from quill-pgsql, it seems to be far more involved.

@beikern
Copy link

beikern commented Apr 5, 2016

 implicit val encodeDate = mappedEncoding[Date, DateTime](new DateTime(_))
 implicit val decodeDate = mappedEncoding[DateTime, Date](_.toDate)

This works for me, maybe I missunderstood what do you want to do :(

@ksilin
Copy link
Contributor

ksilin commented Apr 5, 2016

@beikern - hey, thanks for looking into it. Still missing something here unfortunately. Perhaps I am misunderstanding how this should be done entirely :) Full original example:

 implicit val decodeDateTime = mappedEncoding[String, DateTime](new DateTime(_))
 implicit val encodeDateTime = mappedEncoding[DateTime, String](_.toString)

 case class Simple(name: String, date: DateTime)

 val recTableCreateQuery =
        """CREATE TABLE IF NOT EXISTS test.SIMPLE (
        name text,
        date timestamp,
        PRIMARY KEY (name, date)
 ) """

 val db = source(new CassandraAsyncSourceConfig[UpperCase]("local-cass"))

 val created: Future[ResultSet] = db.execute(recTableCreateQuery, None)
 Await.result(created, 3 seconds)


 val insertQuery = quote{ s: Simple => query[Simple].insert(s) }

 val insert = db.run(insertQuery)(List(Simple("a", DateTime.now())))

Last line results in the CodecNotFoundException.

When I replace the two mappedEncoding values with the ones you provided, the code no longer compiles with Source doesn't know how to decode 'p1.date: org.joda.time.DateTime' ... db.run(insertQuery)

Perhaps you do have a more complete example?

@lvicentesanchez
Copy link
Contributor

@ksilin what @beikern posted should work. If not it's probably an issue with the implicit scoping, i.e. the source can't find the implicit. I'm going to try your snippet and come back with an alternative :)

@lvicentesanchez
Copy link
Contributor

#318 might be related to your problem @ksilin

@beikern
Copy link

beikern commented Apr 5, 2016

@ksilin

  implicit val decodeDateTime = mappedEncoding[Date, DateTime](new DateTime(_))
  implicit val encodeDateTime = mappedEncoding[DateTime, Date](_.toDate)
case class Simple(name: String, date: DateTime)

  object Simple {
    val persist = quote(query[Simple].insert)
  }

  val recTableCreateQuery =
    """CREATE TABLE IF NOT EXISTS test.SIMPLE (
        name text,
        date timestamp,
        PRIMARY KEY (name, date)
 ) """
  val db = source(new CassandraAsyncSourceConfig[SnakeCase]("local"))
  val created = db.execute(recTableCreateQuery, None)
  created.onComplete(x => db.run(Simple.persist)(List(Simple("hello gitHub!", new DateTime()))))

I've tried this now and It works as expected :) Hope it's useful to you!

@lvicentesanchez
Copy link
Contributor

@ksilin This should work

import java.time.{ LocalDateTime, ZoneId, ZoneOffset }
import java.util.Date

import io.getquill._
import io.getquill.naming.UpperCase

import scala.concurrent.ExecutionContext.Implicits.global

object Main extends App {

  implicit val decodeLocalTime = mappedEncoding[Date, LocalDateTime](date => LocalDateTime.ofInstant(date.toInstant, ZoneId.systemDefault()))
  implicit val encodeLocalTime = mappedEncoding[LocalDateTime, Date](time => new Date(time.toEpochSecond(ZoneOffset.of(ZoneId.systemDefault().getId))))

  case class Simple(name: String, date: LocalDateTime)

  val db = source(new CassandraAsyncSourceConfig[UpperCase]("local-cass"))

  val insertQuery = quote { s: Simple => query[Simple].insert(s) }

  val insert = db.run(insertQuery)(List(Simple("a", LocalDateTime.now())))
}

@ksilin
Copy link
Contributor

ksilin commented Apr 5, 2016

@beikern @lvicentesanchez

Yay, learning! Both variants work. Many thanks to both of you!

ZoneOffset.of("Europe/Berlin") refused to work with java.time.DateTimeException: Invalid ID for ZoneOffset, invalid format: Europe/Berlin, but this is not important, I will work around with instant.atZone(ZoneId.of(...)) or similar

Awesome

@ksilin
Copy link
Contributor

ksilin commented Dec 8, 2017

note for people encountering this issue: mappedEncoding is now MappedEncoding

@cornerman
Copy link

@lvicentesanchez Just stumbled over your example for LocalDateTime/Date conversion. There is a bug in the conversion, it constructs new Date with seconds, but it should be milliseconds (ZoneOffset depends on your use case):

def DateToLDT(date: Date) = LocalDateTime.ofInstant(date.toInstant, ZoneOffset.UTC)
def LDTToDate(time: LocalDateTime) = new Date(time.toInstant(ZoneOffset.UTC).toEpochMilli) // this uses toEpochMilli instead of toEpochSecond

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants