将日期字符串与 Scala 中的实际日期进行比较
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13731041/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Comparing date strings with actual dates in Scala
提问by Hyman
I'm looking for a nice way to validate and then compare a date string passed from a REST service.
我正在寻找一种很好的方法来验证然后比较从 REST 服务传递的日期字符串。
If I get 2012-12-25 (year-month-day) passed as a string, what would be an elegant way to confirm it's a valid date, and then to say that the date is in the future or in the past?
如果我将 2012-12-25(年-月-日)作为字符串传递,那么确认它是有效日期,然后说该日期是未来还是过去的优雅方式是什么?
To work with dates in Scala, one can obviously use existing Java libraries. But, working with dates in Java has always been like serving the dark side, so I don't want to drag too much of that legacy into my current coding style. Looking at the Scala Dates example on langref.org, it feels that I'll be back to coding Java if I follow this style of programming.
要在 Scala 中处理日期,显然可以使用现有的 Java 库。但是,在 Java 中处理日期总是像为阴暗面服务,所以我不想将太多的遗留问题拖入我当前的编码风格中。查看langref.org上的Scala Dates 示例,感觉如果我遵循这种编程风格,我将回到编码 Java。
采纳答案by virtualeyes
JodaTime is fine, fine, fine, don't worry about the dark side, it doesn't exist (or at least not in this particular Java library).
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")
}
Can do virtually anything date/time related with JodaTime; it's absurd how good this library is: unequivocal thumbs up.
几乎可以做任何与 JodaTime 相关的日期/时间;这个图书馆有多好真是荒谬:毫不含糊地竖起大拇指。
回答by Dominic Bou-Samra
You can do this using the standard Java SimpleDateFormat library:
你可以使用标准的 Java SimpleDateFormat 库来做到这一点:
def parseDate(value: String) = {
try {
Some(new SimpleDateFormat("yyyy-MM-dd").parse(value))
} catch {
case e: Exception => None
}
}
And then used it like so:
然后像这样使用它:
parseDate("2012-125") // None
parseDate("2012-12-05") // Some(Wed Dec 05 00:00:00 EST 2012)
Then you can have a function for testing future dates:
然后你可以有一个测试未来日期的功能:
def isFuture(value: Date) = value.after(new Date)
回答by yakshaver
Although there are some downsides to using the java date libraries such as a lack of thread safety (Why is Java's SimpleDateFormat not thread-safe?) and a hard to use API, you could use implicits to make things a little more palatable:
尽管使用 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()
}
Then you could use it like this:
然后你可以像这样使用它:
implicit val format = "yyyy-MM-dd"
"2012-12-02" isValid // true
"2012-12-02" beforeNow // ?
"2012-12-25" afterNow // ?
Or, you could use scala-time:
或者,您可以使用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(?)
With this approach, you get a Scala-friendly interface, and you don't have to create and parse a new SimpleDateFormat object or store it in a thread local to avoid threading issues.
使用这种方法,您将获得一个对 Scala 友好的界面,并且您不必创建和解析新的 SimpleDateFormat 对象或将其存储在本地线程中以避免线程问题。
回答by Odd
If you really want to avoid using any date time library at all, you can use a suitable regular expression (such as the one in this answer: https://stackoverflow.com/a/7221570/227019) to validate that the string is indeed a valid ISO 8601 formatted date, and then use the fact that such dates can be lexicographically compared to determine their temporal ordering (simply format the current date in the same format and compare it with the other date using regular string comparison).
如果您真的想完全避免使用任何日期时间库,则可以使用合适的正则表达式(例如此答案中的正则表达式:https: //stackoverflow.com/a/7221570/227019)来验证字符串是否为确实是一个有效的 ISO 8601 格式化日期,然后使用这样一个事实,即可以按字典顺序比较这些日期来确定它们的时间顺序(只需将当前日期格式化为相同的格式,并使用常规字符串比较将其与另一个日期进行比较)。

