我有一个方法如下:
def checkDateFormat(dateStr: String): Any = {
val dateFormats = List(
"yyyy/MM/dd",
"MM/dd/yyyy",
"MMM dd, yyyy",
"dd MMM yyyy",
"yyyy-MM-dd"
)
dateFormats.foreach(format => {
try {
val date = new SimpleDateFormat(format).parse(dateStr)
return format
}
catch {
case e: Exception => {
println("Exception")
/* do nothing */
}
}
})
return
}
这里,我试图识别输入字符串的日期格式。我的方法是迭代所有dateFormats
并尝试使用SimpleDateFormat
解析字符串。如果它被正确解析,那么我返回格式,否则我让catch
块处理它。这种方法适用于大多数情况,除非我尝试解析:
val inputStr = "02/02/2017"
val dateFormat = checkDateFormat(inputStr)
在这种情况下,出于某种原因,inputStr
解析yyyy/MM/dd
而不是由catch
处理(我希望它由MM/dd/yyyy
解析)。我是否应该以不同的方式解析这些字符串(例如,仅通过正则表达式模式匹配),还是有另一种方法可以正确解析示例?
编辑:我不想使用regex
,因为我想在dateFormats
中添加更多格式,这会很乏味,但如果没有其他选项,我会对此持开放态度
答案 0 :(得分:1)
这是编写此函数的更简单方法:
def checkDateFormat(dateStr: String): Option[String] = {
val dateFormats = List(
"yyyy/MM/dd",
"MM/dd/yyyy",
"MMM dd, yyyy",
"dd MMM yyyy",
"yyyy-MM-dd"
)
def validFormat(df: String) =
Try{new SimpleDateFormat(df).parse(dateStr)}.isSuccess
dateFormats.find(validFormat)
}
使用find
表示只要找到工作格式,就会立即返回。
如果您想要实际日期,请尝试以下方法:
def parseDate(dateStr: String): Option[Date] = {
dateFormats
.view
.map(df => Try{new SimpleDateFormat(df).parse(dateStr)})
.find(_.isSuccess)
.flatMap(_.toOption)
}
在这种情况下,使用view
可确保在找到有效格式后立即停止解析。
答案 1 :(得分:0)
来自java docs:
对于解析,如果模式字母的数量大于2,则无论数字位数如何,都按字面解释年份。所以使用模式" MM / dd / yyyy"," 01/11/12"解析到公元12年1月11日
在这种情况下,它被解释为第2AD年:
@ new SimpleDateFormat("YYYY/MM/dd").parse(inputStr)
res8: java.util.Date = Sun Jan 01 00:00:00 PST 2
一种选择是在进行这些测试之前进行正则表达式模式匹配。
答案 2 :(得分:0)
我建议使用更可靠的java.time
API并将try-catch
替换为Try
,如下所示:
def checkDateFormat(dateStr: String): String = {
import java.time.LocalDate
import java.time.format.DateTimeFormatter
import scala.util.Try
val dateFormats = List(
"yyyy/MM/dd",
"MM/dd/yyyy",
"MMM dd, yyyy",
"dd MMM yyyy",
"yyyy-MM-dd"
)
dateFormats.dropWhile( format =>
Try( LocalDate.parse(dateStr, DateTimeFormatter.ofPattern(format)) ).isFailure
).
headOption match {
case Some(fmt) => fmt
case None => "No Match!"
}
}
checkDateFormat("2018/05/21")
// res1: String = yyyy/MM/dd
checkDateFormat("05/21/2018")
// res2: String = MM/dd/yyyy
checkDateFormat("May 21, 2018")
// res3: String = MMM dd, yyyy
checkDateFormat("2018 05 21")
// res4: String = No Match!