【问题标题】:Scala - Convert a string to a timestampScala - 将字符串转换为时间戳
【发布时间】:2016-11-30 03:25:45
【问题描述】:

我正在使用 PostgreSQL 和 PlayFramework,我需要将 Option[String] 转换为 Timestamp 以执行我的查询。

我的Option[String] 是该格式的日期:2016/07/26

并且时间戳的格式是:2016-07-26

我知道我可以将to_stimetamp(myDate, 'YYYY-MM-DD') 添加到我的查询中,但我不想使用它(实际上我不知道我以后会使用 MySQL 还是 PostgreSQL,因为 MySQL 中不存在该函数)

那我该怎么办?

【问题讨论】:

  • 时间戳的类型也是字符串还是自定义类?如果前者你可以只是例如def format(opt: Option[String]): String = { val str = opt getOrElse "some/default/date" str.split('/') mkString("-") }
  • 你是在问如何在 scala 中做到这一点?
  • 是的,我想问在 scala 中我该怎么做,最后我希望我的查询可以与 PostgreSQL 和 MySQL 一起使用,所以我需要在启动查询之前“在 Scala”中转换它跨度>

标签: postgresql scala playframework-2.0


【解决方案1】:

这是时间戳文字的隐式转换。

import java.sql.Timestamp
import java.time.Instant

object util {
  implicit class StringTimeConversions(sc: StringContext) {
    def t(args: Any*): Timestamp =
      Timestamp.from(Instant.parse(sc.s(args:_*)))
  }
}

import util._
val time: Timestamp = t"2007-01-01T00:00:00.00Z"

【讨论】:

  • 为什么Any* 有一个*;并且可以像这样使用它:t("the string values")
  • 在阅读StringContext 类文档字符串后,我对如何使用扩展方法t 有了更多了解。它具有将 json 字符串解析为 json 对象的示例。但我仍然不确定为什么 Any* 是 args 类型。
  • 注意:尽量不要使用java.sql.Timestamp(旧的legacy类型),而是使用新的,见stackoverflow.com/questions/42766674/…
【解决方案2】:
 import org.joda.time.DateTime
 import org.joda.time.format.DateTimeFormat
 import scala.util.Try

 object Test extends App {
   val sourceFormat = DateTimeFormat.forPattern("yyyy/MM/dd")
   val targetFormat = DateTimeFormat.forPattern("yyyy-MM-dd")

   def parse(str: String): Option[DateTime] = {
     Try(DateTime.parse(str, sourceFormat)).toOption
   }

   val input = "2015/07/11"
   val maybeDate = parse(input)
   println(maybeDate.map(_.toString(targetFormat)))
   // Some("2015-07-11")
 }

parse 方法与预先计算的DateTimeFormat 一起使用也会更有效,否则每次都会验证格式。如果您调用toString,内部也会尝试再次从String 重建DateTimeFormat,这是低效的。

与其他答案不同,我建议您永远不要使用 DateTime.parse("2016/07/26"),例如不要传递 String 参数,因为没有内部格式缓存。

更多Option.map 不会捕获DateTime.parse 可能引发的错误,因此如果您只使用Option,如果字符串无法解析,而不是正确解析,它将在运行时出现错误返回一个None。使用Try 可以解决这个问题。

【讨论】:

  • "toOption" 好像不是 org.joda.time.DateTime 的成员
  • toOption 呼叫在Try,确保您正在复制所有内容。我已经为 scala.util.Try 添加了顶级导入,希望能清除所有内容。
  • 我在我的查询中尝试了它,但它不起作用,这是我的查询:SQL("""select id from intervalle_date where date_debut={date_debut}""".stripMargin).on( 'date_debut -> startDateParsed.map(_.toString(targetFormat))).as(scalar[Long].singleOpt) 错误是:[PSQLException:错误:运算符不存在:日期 = 字符变化]
  • 嗨@Clement.Cvl 这看起来不一样,老实说,我不知道您使用的是哪个 SQL 库。可以粘贴生成的 SQL 字符串吗?
【解决方案3】:

如果您使用的是 joda DateTime,那么您可以简单地调用 parse 方法,如下所示:

DateTime.parse("2016/07/26")

如果字符串包含在 Option 中,那么您可以简单地使用:

val d = Option("2016/07/26")
d.map(dt => DateTime.parse(d))

否则,如果您使用的是 java.util.Date,那么您可以像这样使用 SimpleDateFormat:

val f = new java.text.SimpleDateFormat("yyyy-MM-dd")
f.parse("2016/07/26")

【讨论】:

    【解决方案4】:

    使用java.time.ZonedDateTime。定义您自己的格式并解析时间戳。

    首先需要imports

    import java.time.ZonedDateTime
    import java.time.format.DateTimeFormatter
    

    以下代码将返回 ZonedDateTime,这是一种更通用的格式 -

    
            val tsFormat = "yyyy-MM-dd'T'HH:mm:ssz"
            val formatter = DateTimeFormatter.ofPattern(tsFormat)
            // sample date 2021-05-07T00:00:00+00:00
            val startTs = ZonedDateTime.parse(dateString, formatter)
    
    

    【讨论】:

      【解决方案5】:

      只需使用 Timestamp.valueOf 和 String.replaceAll 来修复斜线。您还需要添加时间(只需将其固定为午夜,或任何您想要的时间):

      Timestamp.valueOf("2015/06/08".replaceAll("/", "-") + " 00:00:00")
      

      【讨论】:

        猜你喜欢
        • 2020-11-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-29
        • 2013-09-25
        • 2021-09-08
        相关资源
        最近更新 更多