object Utility {
object Time {
implicit class Regex(sc: StringContext) {
def r = new util.matching.Regex(sc.parts.mkString, sc.parts.tail.map(_ => "x"): _*)
}
case class DTCtxt(val formatter: DateTimeFormatter, tz: DateTimeZone)
trait BaseRelativeTime { def dt: DateTime }
case class Today(val dt: DateTime) extends BaseRelativeTime
case class Yesterday(val dt: DateTime) extends BaseRelativeTime
case class Absolute(val dt: DateTime) extends BaseRelativeTime
def parseRelativeDateTime(str: String, dtCtxt: DTCtxt) = {
println(str)
val dateTimeNow = DateTime.now()
val otherDateTimeNow = dateTimeNow.toDateTime(dtCtxt.tz)
def update_hour(h: String, s: String) =
if (s == "AM") h.toInt else if(h.toInt == 12) 0 else h.toInt + 12
str match {
case r"Today, (\d\d)$h:(\d\d)$m (\w\w)$s" =>
Today(otherDateTimeNow.withTime(update_hour(h, s), m.toInt, 0, 0))
case r"Yesterday, (\d\d)$h:(\d\d)$m (\w\w)$s" =>
Yesterday(otherDateTimeNow.minusDays(1).withTime(update_hour(h, s), m.toInt, 0, 0))
case dt@_ =>
Absolute(dtCtxt.formatter.parseDateTime(dt))
}
}
def guardedParseRelativeDateTime(str: String, dtCtxt: DTCtxt) = {
if(str.isEmpty)
None
else
Some(parseRelativeDateTime(str, dtCtxt))
}
}
}
.dt
? 答案 0 :(得分:1)
可以用一粒盐,YMMV回答。
小事(一些代码审查)
案例类不需要val
,因为它已经暗示,它们将是公开的:
case class DTCtxt(formatter: DateTimeFormatter, tz: DateTimeZone)
case class Today(dt: DateTime) extends BaseRelativeTime
命名的东西:我觉得DTCtxt
有点神秘,我更喜欢一个更冗长的名字,例如:DateTimeContext
。我们通常也会使用驼峰式方法:def updateHour
DateTime.now
可以使用DateTimeZone
参数:val dateTimeNow = DateTime.now(dateTimeContext.tz)
回答您的问题
和2.不是。面向对象的方法是扩展DateTime
,但课程是最终的。另一种方法是返回一个元组,调用者可以通过以下方式提取元组:
def createDatetime(...): (DateTime, BaseRelativeTime)
val (dateTime, typ) = createDatetime(...)
我不会说这是一个更好的解决方案,但它有所不同。你可能会发现这更好。我个人喜欢你的案例类封装方法。
见prev。
hh:mm aa
与你拥有的模式相匹配 - 如果你剥离今天和昨天。例如:DateTimeFormat.forPattern("hh:mm aa").parseDateTime(timeString).toLocalTime
为了缩短它,我觉得毫无意义。如果您真的想要简短,那么只需将所有内容放在一行:)。我会努力让它更清楚。
为了使它更强大,我会使用更多JodaTime的LocalDate和LocalTime作为今天/昨天的东西。我也希望删除隐式StringContext,因为我觉得这是一个不必要的复杂化。
另外,为了使它更好用,你可以使Context隐含,所以需要声明一次。
我提出的最终代码:
case class DateTimeContext(formatter: DateTimeFormatter, tz: DateTimeZone)
sealed trait DateTimeType { def prefix: String }
case object Today extends DateTimeType { val prefix = "Today, " }
case object Yesterday extends DateTimeType { val prefix = "Yesterday, " }
case object Absolute extends DateTimeType { val prefix = "" }
def createDatetime(dateTimeString: String)(implicit dateTimeContext: DateTimeContext): (DateTime, DateTimeType) = {
val date = DateTime.now(dateTimeContext.tz).toLocalDate
val TimeFormat = DateTimeFormat.forPattern("hh:mm aa")
def parseTime(timeString: String) = TimeFormat.parseDateTime(timeString).toLocalTime
dateTimeString match {
case today if today.startsWith(Today.prefix) =>
val time = parseTime(today.stripPrefix(Today.prefix))
val dt = date.toDateTime(time, dateTimeContext.tz)
(dt, Today)
case yesterday if yesterday.startsWith(Yesterday.prefix) =>
val time = parseTime(yesterday.stripPrefix(Yesterday.prefix))
val dt = date.minusDays(1).toDateTime(time, dateTimeContext.tz)
(dt, Yesterday)
case _ =>
(dateTimeContext.formatter.parseDateTime(dateTimeString), Absolute)
}
}
致电:
implicit val dtContext = DateTimeContext(null, DateTimeZone.UTC)
val str = "Yesterday, 11:56 PM"
val (dt, typ) = createDatetime(str)
println(dt) // 2013-11-20T23:56:00.000Z
println(typ) // Yesterday
<强>结论强>
我建议您从这个答案中使用您喜欢的内容。正如我所提到的,我更喜欢案例类封装,只是想展示你可以尝试的不同方法。