6

我正在寻找一种很好的方法来验证然后比较从 REST 服务传递的日期字符串。

如果我将 2012-12-25 (year-month-day) 作为字符串传递,那么确认它是有效日期然后说日期是将来还是过去的优雅方法是什么?

要在 Scala 中处理日期,显然可以使用现有的 Java 库。但是,在 Java 中处理日期一直就像是在为黑暗面服务,所以我不想将太多的遗留问题拖入我当前的编码风格中。查看langref.org上的Scala Dates 示例,感觉如果我遵循这种编程风格,我将回到 Java 编码。

4

4 回答 4

5

JodaTime 很好,很好,很好,不用担心阴暗面,它不存在(或者至少在这个特定的 Java 库中不存在)。

// "20121205".to_date
class String2Date(ymd: String) {
  def to_date = {  
    try{ Some(ymdFormat.parseDateTime(ymd)) } 
    catch { case e:Exception => None }
  }
  val ymdFormat = org.joda.time.format.DateTimeFormat.forPattern("yyyyMMdd")
}
@inline implicit final def string2Date(ymd: String) = new String2Date(ymd)

def dater(ymd: String) = {
  val other = new JodaTime
  ymd.to_date map{d=>
    if(d.isBefore other) ...
    else ...
  } getOrElse("bad date format")
}

几乎可以做任何与 JodaTime 相关的日期/时间;这个库有多好是荒谬的:毫不含糊地竖起大拇指。

于 2012-12-05T21:54:14.757 回答
4

您可以使用标准 Java SimpleDateFormat 库执行此操作:

def parseDate(value: String) = {
  try {
    Some(new SimpleDateFormat("yyyy-MM-dd").parse(value))
  } catch {
    case e: Exception => None
  }
} 

然后像这样使用它:

parseDate("2012-125")   // None
parseDate("2012-12-05") // Some(Wed Dec 05 00:00:00 EST 2012)

然后你可以有一个测试未来日期的功能:

def isFuture(value: Date) = value.after(new Date)
于 2012-12-05T20:14:26.810 回答
1

尽管使用 java 日期库有一些缺点,例如缺乏线程安全性(为什么 Java 的 SimpleDateFormat 不是线程安全的?)和难以使用的 API,但您可以使用隐式使事情变得更容易接受:

implicit def stringToDate(date: String) = new {
  def parse(implicit format: String) = parse0(date)(format)
  private def parse0(date: String)(implicit format: String) = {
    val sdf = new SimpleDateFormat(format)
    sdf.setLenient(false)
    sdf.parse(date)
  }
  def isValid(implicit format: String) = try { parse0(date)(format); true } catch { case _ => false }
  def beforeNow(implicit format: String) = parse0(date)(format) before new Date()
  def afterNow(implicit format: String) = parse0(date)(format) after new Date()
} 

然后你可以像这样使用它:

implicit val format = "yyyy-MM-dd"
"2012-12-02" isValid // true
"2012-12-02" beforeNow // ?
"2012-12-25" afterNow // ? 

或者,您可以使用scala-time

import org.joda.time.format.ISODateTimeFormat._
import org.joda.time.DateTime
for(date <- date.parseOption("2012-12-02")) yield date < new DateTime // Option(?)

使用这种方法,您可以获得一个 Scala 友好的界面,并且您不必创建和解析新的 SimpleDateFormat 对象或将其存储在本地线程中以避免线程问题。

于 2012-12-05T20:19:30.773 回答
1

如果您真的想完全避免使用任何日期时间库,您可以使用合适的正则表达式(例如此答案中的一个:https ://stackoverflow.com/a/7221570/227019 )来验证字符串是确实是一个有效的 ISO 8601 格式日期,然后使用可以按字典顺序比较这些日期的事实来确定它们的时间顺序(只需将当前日期格式化为相同格式,并使用常规字符串比较将其与其他日期进行比较)。

于 2012-12-05T21:40:40.060 回答