我有以下实现:
val dateFormats = Seq("dd/MM/yyyy", "dd.MM.yyyy")
implicit def dateTimeCSVConverter: CsvFieldReader[DateTime] = (s: String) => Try {
val elem = dateFormats.map {
format =>
try {
Some(DateTimeFormat.forPattern(format).parseDateTime(s))
} catch {
case _: IllegalArgumentException =>
None
}
}.collectFirst {
case e if e.isDefined => e.get
}
if (elem.isDefined)
elem.get
else
throw new IllegalArgumentException(s"Unable to parse DateTime $s")
}
所以基本上我正在做的是,我正在运行我的 Seq 并尝试用不同的格式解析 DateTime。然后我收集第一个成功的,如果没有成功,我将抛出异常。
我对代码并不完全满意。有没有更好的方法让它变得更简单?我需要将异常消息传递给调用者。
最佳答案
您的代码的一个问题是它会尝试所有模式,无论日期是否已经解析。您可以使用惰性收集(例如 Stream)来解决这个问题:
def dateTimeCSVConverter(s: String) = Stream("dd/MM/yyyy", "dd.MM.yyyy")
.map(f => Try(DateTimeFormat.forPattern(format).parseDateTime(s))
.dropWhile(_.isFailure)
.headOption
更好的是 jwvh 使用 find 提出的解决方案(您不必调用 headOption
):
def dateTimeCSVConverter(s: String) = Stream("dd/MM/yyyy", "dd.MM.yyyy")
.map(f => Try(DateTimeFormat.forPattern(format).parseDateTime(s))
.find(_.isSuccess)
如果没有任何模式匹配,则返回None
。如果你想在这种情况下抛出异常,你可以使用 getOrElse
来 uwrap 选项:
...
.dropWhile(_.isFailure)
.headOption
.getOrElse(throw new IllegalArgumentException(s"Unable to parse DateTime $s"))
重要的是,当任何验证成功时,它不会进一步进行,而是立即返回解析后的日期。
关于scala - Scala 中的处理和抛出异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55872769/