All Downloads are FREE. Search and download functionalities are using the official Maven repository.

skinny.util.DateTimeUtil.scala Maven / Gradle / Ivy

The newest version!
package skinny.util

import scala.language.implicitConversions
import skinny.ParamType
import org.joda.time._

/**
 * DateTime utility.
 */
object DateTimeUtil {

  /**
   * The ISO8601 standard date format.
   */
  //val ISO_DATE_TIME_FORMAT = "%04d-%02d-%02dT%02d:%02d:%02d%s"
  val ISO_DATE_TIME_FORMAT = "%s-%s-%sT%s:%s:%s%s"

  /**
   * Returns current timezone value (e.g. +09:00).
   */
  def currentTimeZone = {
    val minutes = java.util.TimeZone.getDefault.getRawOffset / 1000 / 60
    (if (minutes >= 0) "+" else "-") + "%02d:%02d".format((math.abs(minutes) / 60), (math.abs(minutes) % 60))
  }

  private case class ZeroPaddingString(s:String) {
    def to04d: String = {
      try "%04d".format(s.toInt)
      catch { case e: NumberFormatException => s }
    }
    def to02d: String = {
      try "%02d".format(s.toInt)
      catch { case e: NumberFormatException => s }
    }
  }
  private implicit def fromStringToZeroPadding(s: String): ZeroPaddingString = ZeroPaddingString(s)

  /**
   * Converts string value to ISO8601 date format if possible.
   * @param s string value
   * @param paramType DateTime/LocalDate/LocalTime
   * @return ISO8601 data format string value
   */
  def toISODateTimeFormat(s: String, paramType: ParamType): String = {
    val str = s.replaceAll("/", "-")
    if (str.matches("\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}")) {
      val timeZone = "([+-]\\d{2}:\\d{2})".r.findFirstIn(s).getOrElse(currentTimeZone)
      str + timeZone
    } else if (str.matches("\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}[+-]\\d{2}:\\d{2}")) {
      str
    } else if (str.matches("\\d{4}-\\d{2}-\\d{2}\\s+\\d{2}:\\d{2}:\\d{2}[+-]\\d{2}:\\d{2}")) {
      str.replaceFirst("\\s+", "T")
    } else {
      str.split("[-:\\s/]").toList match {
        case year :: month :: day :: hour :: minute :: second :: zoneHour :: zoneMinute :: _ =>
          val timeZone = "([+-]\\d{2}:\\d{2})".r.findFirstIn(str).getOrElse(currentTimeZone)
          ISO_DATE_TIME_FORMAT.format(year.to04d, month.to02d, day.to02d, hour.to02d, minute.to02d, second.to02d, timeZone)
        case year :: month :: day :: hour :: minute :: second :: _ =>
          ISO_DATE_TIME_FORMAT.format(year.to04d, month.to02d, day.to02d, hour.to02d, minute.to02d, second.to02d, currentTimeZone)
        case year :: month :: day :: hour :: minute :: _ =>
          ISO_DATE_TIME_FORMAT.format(year.to04d, month.to02d, day.to02d, hour.to02d, minute.to02d, "00", currentTimeZone)
        case year :: month :: day :: _ if paramType == ParamType.LocalDate =>
          ISO_DATE_TIME_FORMAT.format(year.to04d, month.to02d, day.to02d, "00", "00", "00", currentTimeZone)
        case hour :: minute :: second :: _ if paramType == ParamType.LocalTime =>
          ISO_DATE_TIME_FORMAT.format("1970", "01", "01", hour.to02d, minute.to02d, second.to02d, currentTimeZone)
        case hour :: minute :: _ if paramType == ParamType.LocalTime =>
          ISO_DATE_TIME_FORMAT.format("1970", "01", "01", hour.to02d, minute.to02d, "00", currentTimeZone)
        case _ => str
      }
    }
  }

  def parseDateTime(s: String): DateTime = DateTime.parse(toISODateTimeFormat(s, ParamType.DateTime))

  def parseLocalDate(s: String): LocalDate = DateTime.parse(toISODateTimeFormat(s, ParamType.LocalDate)).toLocalDate

  def parseLocalTime(s: String): LocalTime = DateTime.parse(toISODateTimeFormat(s, ParamType.LocalTime)).toLocalTime

  def toDateString(
    params: Map[String, Any],
    year: String = "year",
    month: String = "month",
    day: String = "day"): Option[String] = {

    try {
      (params.get(year).filterNot(_.toString.isEmpty) orElse
        params.get(month).filterNot(_.toString.isEmpty) orElse
        params.get(day).filterNot(_.toString.isEmpty)).map { _ =>
        "%04d-%02d-%02d".format(
          params.get(year).map(_.toString.toInt).orNull,
          params.get(month).map(_.toString.toInt).orNull,
          params.get(day).map(_.toString.toInt).orNull
        )
      }
    } catch { case e: NumberFormatException => None }
  }

  def toUnsafeDateString(
    params: Map[String, Any],
    year: String = "year",
    month: String = "month",
    day: String = "day"): Option[String] = {

    (params.get(year).filterNot(_.toString.isEmpty) orElse
      params.get(month).filterNot(_.toString.isEmpty) orElse
      params.get(day).filterNot(_.toString.isEmpty)).map { t =>
      "%s-%s-%s".format(
        params.get(year).map(_.toString.to04d).orNull,
        params.get(month).map(_.toString.to02d).orNull,
        params.get(day).map(_.toString.to02d).orNull
      )
    }
  }

  def toTimeString(
    params: Map[String, Any],
    hour: String = "hour",
    minute: String = "minute",
    second: String = "second"): Option[String] = {

    try {
      (params.get(hour).filterNot(_.toString.isEmpty) orElse
        params.get(minute).filterNot(_.toString.isEmpty) orElse
        params.get(second).filterNot(_.toString.isEmpty)).map { _ =>
        "1970-01-01 %02d:%02d:%02d".format(
          params.get(hour).map(_.toString.toInt).orNull,
          params.get(minute).map(_.toString.toInt).orNull,
          params.get(second).map(_.toString.toInt).orNull
        )
      }
    } catch { case e: NumberFormatException => None }
  }

  def toUnsafeTimeString(
    params: Map[String, Any],
    hour: String = "hour",
    minute: String = "minute",
    second: String = "second"): Option[String] = {

    (params.get(hour).filterNot(_.toString.isEmpty) orElse
      params.get(minute).filterNot(_.toString.isEmpty) orElse
      params.get(second).filterNot(_.toString.isEmpty)).map { _ =>
      "1970-01-01 %s:%s:%s".format(
        params.get(hour).map(_.toString.to02d).orNull,
        params.get(minute).map(_.toString.to02d).orNull,
        params.get(second).map(_.toString.to02d).orNull
      )
    }
  }

  def toDateTimeString(
    params: Map[String, Any],
    year: String = "year",
    month: String = "month",
    day: String = "day",
    hour: String = "hour",
    minute: String = "minute",
    second: String = "second"): Option[String] = {

    try {
      (params.get(year).filterNot(_.toString.isEmpty) orElse
        params.get(month).filterNot(_.toString.isEmpty) orElse
        params.get(day).filterNot(_.toString.isEmpty) orElse
        params.get(hour).filterNot(_.toString.isEmpty) orElse
        params.get(minute).filterNot(_.toString.isEmpty) orElse
        params.get(second).filterNot(_.toString.isEmpty)).map { _ =>
        "%04d-%02d-%02d %02d:%02d:%02d".format(
          params.get(year).map(_.toString.toInt).orNull,
          params.get(month).map(_.toString.toInt).orNull,
          params.get(day).map(_.toString.toInt).orNull,
          params.get(hour).map(_.toString.toInt).orNull,
          params.get(minute).map(_.toString.toInt).orNull,
          params.get(second).map(_.toString.toInt).orNull
        )
      }
    } catch { case e: NumberFormatException => None }
  }

  def toUnsafeDateTimeString(
    params: Map[String, Any],
    year: String = "year",
    month: String = "month",
    day: String = "day",
    hour: String = "hour",
    minute: String = "minute",
    second: String = "second"): Option[String] = {

    (params.get(year).filterNot(_.toString.isEmpty) orElse
      params.get(month).filterNot(_.toString.isEmpty) orElse
      params.get(day).filterNot(_.toString.isEmpty) orElse
      params.get(hour).filterNot(_.toString.isEmpty) orElse
      params.get(minute).filterNot(_.toString.isEmpty) orElse
      params.get(second).filterNot(_.toString.isEmpty)).map { _ =>
      "%s-%s-%s %s:%s:%s".format(
        params.get(year).map(_.toString.to04d).orNull,
        params.get(month).map(_.toString.to02d).orNull,
        params.get(day).map(_.toString.to02d).orNull,
        params.get(hour).map(_.toString.to02d).orNull,
        params.get(minute).map(_.toString.to02d).orNull,
        params.get(second).map(_.toString.to02d).orNull
      )
    }
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy