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

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

There is a newer version: 2.5.2
Show newest version
package skinny.util

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

import scala.util.Try

/**
 * 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: String = {
    val minutes = java.util.TimeZone.getDefault.getRawOffset / 1000 / 60
    (if (minutes >= 0) "+" else "-") + "%02d:%02d".format((math.abs(minutes) / 60), (math.abs(minutes) % 60))
  }

  /**
   * Returns "2014-01-02 03:04:05".
   */
  def toString(d: DateTime): String = d.toString("YYYY-MM-dd HH:mm:ss")
  def toString(d: LocalDate): String = d.toString("YYYY-MM-dd")
  def toString(d: LocalTime): String = d.toString("HH:mm:ss")

  /**
   * Returns "2014-01-02 03:04:05".
   */
  def nowString: String = toString(DateTime.now)

  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.matches("\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}.\\d+[+-]\\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
        )
      }
  }

  def toUnsafeDateTimeStringFromDateAndTime(
    params: Map[String, Any],
    date: String = "date",
    time: String = "time"
  ): Option[String] = {

    (params.get(date).filterNot(_.toString.isEmpty) orElse
      params.get(time).filterNot(_.toString.isEmpty)).map { _ =>
        "%s %s".format(
          params.get(date).map(_.toString).orNull,
          params.get(time).map(_.toString).orNull
        )
      }
  }

  def isLocalDateFormat(str: String): Boolean = Try(parseLocalDate(str)).isSuccess

  def isDateTimeFormat(str: String): Boolean = Try(parseDateTime(str)).isSuccess

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy