diff lib/ur/datetime.ur @ 1988:abb6981a2c4c

Merge with small clean-ups
author Adam Chlipala <adam@chlipala.net>
date Tue, 18 Feb 2014 07:07:01 -0500
parents 50322ba22972
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/ur/datetime.ur	Tue Feb 18 07:07:01 2014 -0500
@@ -0,0 +1,135 @@
+datatype day_of_week = Sunday | Monday | Tuesday | Wednesday | Thursday |
+         Friday | Saturday
+
+val show_day_of_week = mkShow (fn dow => case dow of
+                                          Sunday => "Sunday"
+                                        | Monday => "Monday"
+                                        | Tuesday => "Tuesday"
+                                        | Wednesday => "Wednesday"
+                                        | Thursday => "Thursday"
+                                        | Friday => "Friday"
+                                        | Saturday => "Saturday")
+
+fun dayOfWeekToInt dow = case dow of
+                             Sunday => 0
+                           | Monday => 1
+                           | Tuesday => 2
+                           | Wednesday => 3
+                           | Thursday => 4
+                           | Friday => 5
+                           | Saturday => 6
+
+fun intToDayOfWeek i = case i of
+                           0 => Sunday
+                         | 1 => Monday
+                         | 2 => Tuesday
+                         | 3 => Wednesday
+                         | 4 => Thursday
+                         | 5 => Friday
+                         | 6 => Saturday
+                         | n => error <xml>Invalid day of week {[n]}</xml>
+
+val eq_day_of_week = mkEq (fn a b => dayOfWeekToInt a = dayOfWeekToInt b)
+
+
+datatype month = January | February | March | April | May | June | July |
+         August | September | October | November | December
+
+val show_month = mkShow (fn m => case m of
+                                     January => "January"
+                                   | February => "February"
+                                   | March => "March"
+                                   | April => "April"
+                                   | May => "May"
+                                   | June => "June"
+                                   | July => "July"
+                                   | August => "August"
+                                   | September => "September"
+                                   | October => "October"
+                                   | November => "November"
+                                   | December => "December")
+
+type t = {
+     Year : int,
+     Month : month,
+     Day : int,
+     Hour : int,
+     Minute : int,
+     Second : int
+}
+
+fun monthToInt m = case m of
+                       January => 0
+                     | February => 1
+                     | March => 2
+                     | April => 3
+                     | May => 4
+                     | June => 5
+                     | July => 6
+                     | August => 7
+                     | September => 8
+                     | October => 9
+                     | November => 10
+                     | December => 11
+
+fun intToMonth i = case i of
+                       0 => January
+                     | 1 => February
+                     | 2 => March
+                     | 3 => April
+                     | 4 => May
+                     | 5 => June
+                     | 6 => July
+                     | 7 => August
+                     | 8 => September
+                     | 9 => October
+                     | 10 => November
+                     | 11 => December
+                     | n => error <xml>Invalid month number {[n]}</xml>
+
+val eq_month = mkEq (fn a b => monthToInt a = monthToInt b)
+
+
+fun toTime dt : time = fromDatetime dt.Year (monthToInt dt.Month) dt.Day
+                                    dt.Hour dt.Minute dt.Second
+
+fun fromTime t : t = {
+    Year = datetimeYear t,
+    Month = intToMonth (datetimeMonth t),
+    Day = datetimeDay t,
+    Hour = datetimeHour t,
+    Minute = datetimeMinute t,
+    Second = datetimeSecond t
+}
+
+val ord_datetime = mkOrd { Lt = fn a b => toTime a < toTime b,
+                           Le = fn a b => toTime a <= toTime b }
+
+fun format fmt dt : string = timef fmt (toTime dt)
+
+fun dayOfWeek dt : day_of_week = intToDayOfWeek (datetimeDayOfWeek (toTime dt))
+
+val now : transaction t =
+    n <- now;
+    return (fromTime n)
+
+(* Normalize a datetime. This will convert, e.g., January 32nd into February
+   1st. *)
+
+fun normalize dt = fromTime (toTime dt)
+fun addToField [nm :: Name] [rest ::: {Type}] [[nm] ~ rest]
+               (delta : int) (r : $([nm = int] ++ rest))
+    : $([nm = int] ++ rest) =
+      (r -- nm) ++ {nm = r.nm + delta}
+
+
+(* Functions for adding to a datetime. There is no addMonths or addYears since
+   it's not clear what should be done; what's 1 month after January 31, or 1
+   year after February 29th?
+
+   These can't all be defined in terms of addSeconds because of leap seconds. *)
+
+fun addSeconds n dt = normalize (addToField [#Second] n dt)
+fun addMinutes n dt = normalize (addToField [#Minute] n dt)
+fun addHours n dt = normalize (addToField [#Hour] n dt)
+fun addDays n dt = normalize (addToField [#Day] n dt)