src/Pure/General/date.scala
author wenzelm
Wed, 05 Oct 2016 22:07:36 +0200
changeset 64060 f3fa0bb3f666
parent 64059 365d367d2b45
child 64094 629558a1ecf5
permissions -rw-r--r--
tuned signature;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
64056
0edc966bee55 more date and time operations from Java 8;
wenzelm
parents:
diff changeset
     1
/*  Title:      Pure/General/date.scala
0edc966bee55 more date and time operations from Java 8;
wenzelm
parents:
diff changeset
     2
    Author:     Makarius
0edc966bee55 more date and time operations from Java 8;
wenzelm
parents:
diff changeset
     3
0edc966bee55 more date and time operations from Java 8;
wenzelm
parents:
diff changeset
     4
Date and time, with time zone.
0edc966bee55 more date and time operations from Java 8;
wenzelm
parents:
diff changeset
     5
*/
0edc966bee55 more date and time operations from Java 8;
wenzelm
parents:
diff changeset
     6
0edc966bee55 more date and time operations from Java 8;
wenzelm
parents:
diff changeset
     7
package isabelle
0edc966bee55 more date and time operations from Java 8;
wenzelm
parents:
diff changeset
     8
0edc966bee55 more date and time operations from Java 8;
wenzelm
parents:
diff changeset
     9
64057
fd73e0019605 more operations;
wenzelm
parents: 64056
diff changeset
    10
import java.time.{Instant, ZonedDateTime, ZoneId}
64056
0edc966bee55 more date and time operations from Java 8;
wenzelm
parents:
diff changeset
    11
import java.time.format.{DateTimeFormatter, DateTimeParseException}
64059
365d367d2b45 more flexibile formatting;
wenzelm
parents: 64057
diff changeset
    12
import java.time.temporal.TemporalAccessor
365d367d2b45 more flexibile formatting;
wenzelm
parents: 64057
diff changeset
    13
365d367d2b45 more flexibile formatting;
wenzelm
parents: 64057
diff changeset
    14
import scala.annotation.tailrec
64056
0edc966bee55 more date and time operations from Java 8;
wenzelm
parents:
diff changeset
    15
0edc966bee55 more date and time operations from Java 8;
wenzelm
parents:
diff changeset
    16
0edc966bee55 more date and time operations from Java 8;
wenzelm
parents:
diff changeset
    17
object Date
0edc966bee55 more date and time operations from Java 8;
wenzelm
parents:
diff changeset
    18
{
0edc966bee55 more date and time operations from Java 8;
wenzelm
parents:
diff changeset
    19
  /* format */
0edc966bee55 more date and time operations from Java 8;
wenzelm
parents:
diff changeset
    20
0edc966bee55 more date and time operations from Java 8;
wenzelm
parents:
diff changeset
    21
  object Format
0edc966bee55 more date and time operations from Java 8;
wenzelm
parents:
diff changeset
    22
  {
64060
f3fa0bb3f666 tuned signature;
wenzelm
parents: 64059
diff changeset
    23
    def make(fmts: List[DateTimeFormatter], filter: String => String = s => s): Format =
64059
365d367d2b45 more flexibile formatting;
wenzelm
parents: 64057
diff changeset
    24
    {
365d367d2b45 more flexibile formatting;
wenzelm
parents: 64057
diff changeset
    25
      require(fmts.nonEmpty)
365d367d2b45 more flexibile formatting;
wenzelm
parents: 64057
diff changeset
    26
365d367d2b45 more flexibile formatting;
wenzelm
parents: 64057
diff changeset
    27
      @tailrec def parse_first(
365d367d2b45 more flexibile formatting;
wenzelm
parents: 64057
diff changeset
    28
        last_exn: Option[Throwable], fs: List[DateTimeFormatter], str: String): TemporalAccessor =
365d367d2b45 more flexibile formatting;
wenzelm
parents: 64057
diff changeset
    29
      {
365d367d2b45 more flexibile formatting;
wenzelm
parents: 64057
diff changeset
    30
        fs match {
365d367d2b45 more flexibile formatting;
wenzelm
parents: 64057
diff changeset
    31
          case Nil => throw last_exn.get
365d367d2b45 more flexibile formatting;
wenzelm
parents: 64057
diff changeset
    32
          case f :: rest =>
365d367d2b45 more flexibile formatting;
wenzelm
parents: 64057
diff changeset
    33
            try { ZonedDateTime.from(f.parse(str)) }
365d367d2b45 more flexibile formatting;
wenzelm
parents: 64057
diff changeset
    34
            catch { case exn: DateTimeParseException => parse_first(Some(exn), rest, str) }
365d367d2b45 more flexibile formatting;
wenzelm
parents: 64057
diff changeset
    35
        }
365d367d2b45 more flexibile formatting;
wenzelm
parents: 64057
diff changeset
    36
      }
64056
0edc966bee55 more date and time operations from Java 8;
wenzelm
parents:
diff changeset
    37
      new Format {
64059
365d367d2b45 more flexibile formatting;
wenzelm
parents: 64057
diff changeset
    38
        def apply(date: Date): String = fmts.head.format(date.rep)
365d367d2b45 more flexibile formatting;
wenzelm
parents: 64057
diff changeset
    39
        def parse(str: String): Date =
64060
f3fa0bb3f666 tuned signature;
wenzelm
parents: 64059
diff changeset
    40
          new Date(ZonedDateTime.from(parse_first(None, fmts, filter(str))))
64056
0edc966bee55 more date and time operations from Java 8;
wenzelm
parents:
diff changeset
    41
      }
64059
365d367d2b45 more flexibile formatting;
wenzelm
parents: 64057
diff changeset
    42
    }
64056
0edc966bee55 more date and time operations from Java 8;
wenzelm
parents:
diff changeset
    43
64060
f3fa0bb3f666 tuned signature;
wenzelm
parents: 64059
diff changeset
    44
    def make_patterns(patterns: List[String], filter: String => String = s => s): Format =
f3fa0bb3f666 tuned signature;
wenzelm
parents: 64059
diff changeset
    45
      make(patterns.toList.map(DateTimeFormatter.ofPattern(_)), filter)
f3fa0bb3f666 tuned signature;
wenzelm
parents: 64059
diff changeset
    46
64059
365d367d2b45 more flexibile formatting;
wenzelm
parents: 64057
diff changeset
    47
    def apply(patterns: String*): Format =
365d367d2b45 more flexibile formatting;
wenzelm
parents: 64057
diff changeset
    48
      make(patterns.toList.map(DateTimeFormatter.ofPattern(_)))
64056
0edc966bee55 more date and time operations from Java 8;
wenzelm
parents:
diff changeset
    49
0edc966bee55 more date and time operations from Java 8;
wenzelm
parents:
diff changeset
    50
    val default: Format = apply("dd-MMM-uuuu HH:mm:ss xx")
64057
fd73e0019605 more operations;
wenzelm
parents: 64056
diff changeset
    51
    val date: Format = apply("dd-MMM-uuuu")
fd73e0019605 more operations;
wenzelm
parents: 64056
diff changeset
    52
    val time: Format = apply("HH:mm:ss")
64056
0edc966bee55 more date and time operations from Java 8;
wenzelm
parents:
diff changeset
    53
  }
0edc966bee55 more date and time operations from Java 8;
wenzelm
parents:
diff changeset
    54
0edc966bee55 more date and time operations from Java 8;
wenzelm
parents:
diff changeset
    55
  abstract class Format private
0edc966bee55 more date and time operations from Java 8;
wenzelm
parents:
diff changeset
    56
  {
0edc966bee55 more date and time operations from Java 8;
wenzelm
parents:
diff changeset
    57
    def apply(date: Date): String
0edc966bee55 more date and time operations from Java 8;
wenzelm
parents:
diff changeset
    58
    def parse(str: String): Date
0edc966bee55 more date and time operations from Java 8;
wenzelm
parents:
diff changeset
    59
    def unapply(str: String): Option[Date] =
0edc966bee55 more date and time operations from Java 8;
wenzelm
parents:
diff changeset
    60
      try { Some(parse(str)) }
0edc966bee55 more date and time operations from Java 8;
wenzelm
parents:
diff changeset
    61
      catch { case _: DateTimeParseException => None }
0edc966bee55 more date and time operations from Java 8;
wenzelm
parents:
diff changeset
    62
  }
64057
fd73e0019605 more operations;
wenzelm
parents: 64056
diff changeset
    63
fd73e0019605 more operations;
wenzelm
parents: 64056
diff changeset
    64
fd73e0019605 more operations;
wenzelm
parents: 64056
diff changeset
    65
  /* date operations */
fd73e0019605 more operations;
wenzelm
parents: 64056
diff changeset
    66
fd73e0019605 more operations;
wenzelm
parents: 64056
diff changeset
    67
  def timezone(): ZoneId = ZoneId.systemDefault
fd73e0019605 more operations;
wenzelm
parents: 64056
diff changeset
    68
fd73e0019605 more operations;
wenzelm
parents: 64056
diff changeset
    69
  def now(zone: ZoneId = timezone()): Date = new Date(ZonedDateTime.now(zone))
fd73e0019605 more operations;
wenzelm
parents: 64056
diff changeset
    70
fd73e0019605 more operations;
wenzelm
parents: 64056
diff changeset
    71
  def apply(t: Time, zone: ZoneId = timezone()): Date =
fd73e0019605 more operations;
wenzelm
parents: 64056
diff changeset
    72
    new Date(ZonedDateTime.ofInstant(t.instant, zone))
64056
0edc966bee55 more date and time operations from Java 8;
wenzelm
parents:
diff changeset
    73
}
0edc966bee55 more date and time operations from Java 8;
wenzelm
parents:
diff changeset
    74
64059
365d367d2b45 more flexibile formatting;
wenzelm
parents: 64057
diff changeset
    75
sealed case class Date(rep: ZonedDateTime)
64056
0edc966bee55 more date and time operations from Java 8;
wenzelm
parents:
diff changeset
    76
{
64057
fd73e0019605 more operations;
wenzelm
parents: 64056
diff changeset
    77
  def time: Time = Time.instant(Instant.from(rep))
fd73e0019605 more operations;
wenzelm
parents: 64056
diff changeset
    78
  def timezone: ZoneId = rep.getZone
fd73e0019605 more operations;
wenzelm
parents: 64056
diff changeset
    79
fd73e0019605 more operations;
wenzelm
parents: 64056
diff changeset
    80
  def format(fmt: Date.Format = Date.Format.default): String = fmt(this)
fd73e0019605 more operations;
wenzelm
parents: 64056
diff changeset
    81
  override def toString: String = format()
64056
0edc966bee55 more date and time operations from Java 8;
wenzelm
parents:
diff changeset
    82
}