Моя лучшая рекомендация - не делать слишком много в одной области: создавать небольшие функции, которые решают одну проблему за раз. И не стесняйтесь ломать строки и называть промежуточные результаты. Я понимаю, что однострочники могут быть приятными при написании, но они могут вызвать ненужное беспокойство в глазах читателя.
В моем редакторе:
- Я исключил использование рекурсии для нормализации входных данных в пользу второго метода (в этом случае перегрузка, не стесняйтесь переименовывать его, если вы считаете, что это имеет смысл).
- Я разложил логики c, чтобы отобразить
Instant
как JString
в один метод, вызываемый дважды. - Я вычислил лог c для перехода от
LocalDateTime
или LocalDate
к Instant
в пару перегруженных методов, чтобы сохранить основной лог c немного чище от деталей - Я также использовал
camelCase
вместо snake_case
, но это личное предпочтение, пожалуйста, придерживайтесь snake_case
, если это ваше и ваше предпочтение команды .
Я также думал о том, чтобы один метод возвращал Try[JValue]
и позволял второму адресу указывать, что делать с результатом, но я думаю, что этого может быть достаточно. Оцените, так ли это на основе вашего контекста.
Кроме того, все методы здесь опубликованы c, так как это простой простой скрипт. Я бы посоветовал вам ограничить видимость таким образом, чтобы были видны только те, кого вы хотите (из того, что я вижу, я бы оставил только оригинал timeToEpoch(params)
как publi c).
Вы можете поиграйте с этим кодом здесь на Scast ie.
import java.time.format.DateTimeFormatter
import java.time.{LocalDate, LocalDateTime, ZoneId, ZoneOffset}
import org.json4s._
import scala.util.Try
def timeToEpoch(params: List[JValue]): JValue =
params match {
case List(JString(timestamp), JString(pattern)) =>
timeToEpoch(timestamp, pattern, "UTC")
case List(JString(timestamp), JString(pattern), JString(timezone)) =>
timeToEpoch(timestamp, pattern, timezone)
}
def timeToEpoch(
timestamp: String,
pattern: String,
timeZone: String
): JValue =
Try {
val formatter = DateTimeFormatter.ofPattern(pattern)
val df =
formatter.parseBest(timestamp, LocalDateTime.from _, LocalDate.from _)
df match {
case dateTime: LocalDateTime =>
formatInstant(toInstant(dateTime), ZoneId.of(timeZone))
case date: LocalDate =>
formatInstant(toInstant(date), ZoneId.of(timeZone))
case _ =>
JNothing
}
}.getOrElse(JNothing)
def toInstant(dateTime: LocalDateTime, timeZone: ZoneId): Instant = {
val offset = timeZone.getRules.getOffset(LocalDateTime.now)
val offsetAsString = String.valueOf(offset)
dateTime.toInstant(offsetAsString)
}
def toInstant(date: LocalDate, timeZone: ZoneId): Instant = {
date.atStartOfDay(timeZone).toInstant
}
def formatInstant(i: Instant): JString = {
if (res.getNano == 0)
JString(s"${res.getEpochSecond}")
else
JString(s"${res.getEpochSecond} seconds ${res.getNano} nanoseconds")
}