我正在寻找一种很好的方法来验证,然后比较从REST服务传递的日期字符串。
如果我将2012-12-25(年 - 月 - 日)作为字符串传递,那将是一种优雅的方式来确认它是一个有效的日期,然后说明日期是在将来还是在过去?
要在Scala中使用日期,显然可以使用现有的Java库。但是,使用Java中的日期一直就像服务于黑暗面,所以我不想将太多的遗产拖到我当前的编码风格中。看看Scala Dates example on langref.org,如果我遵循这种编程方式,我会觉得我将重新编写Java。
答案 0 :(得分: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相关的日期/时间;这个图书馆有多好,这是荒谬的:明确的赞许。
答案 1 :(得分:3)
您可以使用标准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)
答案 2 :(得分:1)
尽管使用java日期库存在一些缺点,例如缺乏线程安全性(Why is Java's SimpleDateFormat not thread-safe?)和难以使用的API,但您可以使用implicits使事情变得更加可口:
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对象,也不必将其存储在本地线程中以避免线程问题。
答案 3 :(得分:1)
如果你真的想完全避免使用任何日期时间库,你可以使用合适的正则表达式(例如本答案中的那个:https://stackoverflow.com/a/7221570/227019)来验证字符串确实是有效的ISO 8601格式化日期,然后使用这样的事实,即可以按字典顺序对这些日期进行比较,以确定它们的时间顺序(只需使用相同格式格式化当前日期,并使用常规字符串比较将其与其他日期进行比较)。