Personal tools

Time

From HaskellWiki

(Difference between revisions)
Jump to: navigation, search
m (Absolute Time)
m
Line 1: Line 1:
 
= Time =
 
= Time =
   
The canonical time library for Haskell is the time library by Ashley Yakeley. There are several similar but different concepts associated with time and the time library keys these different concepts separated by different data types with appropriate transformations between them to keep your logic safe. However, if you are trying to use the wrong data type for the wrong task, you may find yourself frusterted with the time library.
+
The canonical time library for Haskell is the time library by Ashley Yakeley. There are several similar but different concepts associated with time and the time library keys these different concepts separated by different data types with appropriate transformations between them to keep your logic safe. However, if you are trying to use the wrong data type for the wrong task, you may find yourself frustrated with the time library.
   
 
To help avoid frustration, this guide will describe the various data types available in the time library and what concepts they represent in order help make sure you are using the right data type for the right task. The first few data types of this guide are not widely used in practice, but it is important to understand their conceptual uses before moving onto the more complex, but widely used, data types.
 
To help avoid frustration, this guide will describe the various data types available in the time library and what concepts they represent in order help make sure you are using the right data type for the right task. The first few data types of this guide are not widely used in practice, but it is important to understand their conceptual uses before moving onto the more complex, but widely used, data types.
Line 7: Line 7:
 
== AbsoluteTime ==
 
== AbsoluteTime ==
   
<tt>AbsoluteTime</tt> is found in the <tt>Data.Time.Clock.TAI</tt> module. This data type is the most appropriate type for denoting when an event occurs. AbsoluteTime simply counts the number of seconds since the TAI epoch. There are no leap seconds or timezones to worry about. You can compare two <tt>AbsoluteTime</tt>s directly to determine which one came first. You can reference time as far into the future and past as you like to within a resolution of 10^-12 seconds.
+
<tt>AbsoluteTime</tt> is found in the <tt>Data.Time.Clock.TAI</tt> module. This data type is the most appropriate type for denoting when an event occurs. AbsoluteTime simply counts the number of seconds since the TAI epoch. There are no leap seconds or timezones to worry about. You can compare two <tt>AbsoluteTime</tt>s directly to determine which one came first. You can reference time as far into the future and past as you like to within a resolution of 10<sup>-12</sup> seconds.
   
Although <tt>AbsoluteTime</tt> is most approprate for many tasks, it is rarely used in applications and you will likely never use this data type. Unless you are a particularly pioneering person, you will probably want to use <tt>UTCTime</tt> which is more widely used in practice.
+
Although <tt>AbsoluteTime</tt> is most appropriate for many tasks, it is rarely used in applications and you will likely never use this data type. Unless you are a particularly pioneering person, you will probably want to use <tt>UTCTime</tt> which is more widely used in practice.
   
 
== DiffTime ==
 
== DiffTime ==
Line 23: Line 23:
 
The problem with <tt>AbsoluteTime</tt> is that Earth's rotation rate is not constant. Over the long term, solar noon would drift over time. <tt>UniversalTime</tt> measures time by counting the number of "solar" rotations of the earth, including fractions of a rotation, of the earth since the MJD (Modifed Julian Date) epoch.
 
The problem with <tt>AbsoluteTime</tt> is that Earth's rotation rate is not constant. Over the long term, solar noon would drift over time. <tt>UniversalTime</tt> measures time by counting the number of "solar" rotations of the earth, including fractions of a rotation, of the earth since the MJD (Modifed Julian Date) epoch.
   
The variations in the Earth's rototion means that a difference in <tt>UniversialTime</tt> does not correspond to any particular amount of time. Your computer's hardware cannot track <tt>UniversalTime</tt> since it can only measure absolute durations. Converting between <tt>UniversalTime</tt> and <tt>AbsoluteTime</tt> would require a database build upon astronomical observations. No such conversion untilities are provided.
+
The variations in the Earth's rotation means that a difference in <tt>UniversialTime</tt> does not correspond to any particular amount of time. Your computer's hardware cannot track <tt>UniversalTime</tt> since it can only measure absolute durations. Converting between <tt>UniversalTime</tt> and <tt>AbsoluteTime</tt> would require a database build upon astronomical observations. No such conversion utilities are provided.
   
 
<tt>UniversalTime</tt> is almost never used in practice.
 
<tt>UniversalTime</tt> is almost never used in practice.
Line 33: Line 33:
 
It is unpredictable which days will have a leap second and a leap second table is needed to convert between <tt>AbsoluteTime</tt> and <tt>UTCTime</tt>. This conversion can only be done reliably within recent history.
 
It is unpredictable which days will have a leap second and a leap second table is needed to convert between <tt>AbsoluteTime</tt> and <tt>UTCTime</tt>. This conversion can only be done reliably within recent history.
   
<tt>UTCTime</tt> is the most popular way of referencing events in absolute time. Events occuring hundreds or years ago can be referenced with moderate precision because we may know when during a particular day they occured, even though we won't know the <tt>AbsoluteTime</tt> that they occured. Events occuring in the recent past can be converted to <tt>AbsoluteTime</tt>. Future events are usually set relatative to the day in which they are to occur, so the fact that the absolute time that they will occur at (that is exact the number seconds into the future that they will occur) is unknown often is not a problem.
+
<tt>UTCTime</tt> is the most popular way of referencing events in absolute time. Events occurring hundreds or years ago can be referenced with moderate precision because we may know when during a particular day they occurred, even though we won't know the <tt>AbsoluteTime</tt> that they occurred. Events occurring in the recent past can be converted to <tt>AbsoluteTime</tt>. Future events are usually set relative to the day in which they are to occur, so the fact that the absolute time that they will occur at (that is exact the number seconds into the future that they will occur) is unknown is often not a problem.
   
The major disavantage with <tt>UTCTime</tt> is that one cannot compute the absolute difference between two <tt>UTCTime</tt>s without first converting them to <tt>AbsoluteTime</tt>, and that requires an accurate leap second tables. To circumvent this issue, one uses <tt>NominalDiffTime</tt> instead.
+
The major disadvantage with <tt>UTCTime</tt> is that one cannot compute the absolute difference between two <tt>UTCTime</tt>s without first converting them to <tt>AbsoluteTime</tt>, and that requires an accurate leap second tables. To circumvent this issue, one uses <tt>NominalDiffTime</tt> instead.
   
 
== NominalDiffTime ==
 
== NominalDiffTime ==
   
The <tt>diffUTCTime</tt> function computes a <tt>NominalDiffTime</tt> between two <tt>UTCTimes</tt> which is the number of seconds that would have occured between two <tt>UTCTime</tt> if no leap seconds had occured between the two events. Therefore the <tt>diffUTCTime</tt> is not suitable for measuring the absolute time between two events to within a second's worth of precssion. However a <tt>NominalDiffTime</tt> is often suitable for advancing an event by a week, a day, or an hour, since one would nomially want said event to occur at the same time of day, or same minute of the hour, regarless of whether or not a leap second happens to be inserted in that duration.
+
The <tt>diffUTCTime</tt> function computes a <tt>NominalDiffTime</tt> between two <tt>UTCTimes</tt> which is the number of seconds that would have occurred between two <tt>UTCTime</tt> if no leap seconds had occurred between the two events. Therefore the <tt>diffUTCTime</tt> is not suitable for measuring the absolute time between two events to within a second's worth of precession. However a <tt>NominalDiffTime</tt> is often suitable for advancing an event by a week, a day, or an hour, since one would normally want said event to occur at the same time of day, or same minute of the hour, regardless of whether or not a leap second happens to be inserted in that duration.
   
 
<tt>NominalDiffTime</tt> is a member of the <tt>Num</tt> and <tt>Fractional</tt>, so can be generated by <tt>fromIntegral</tt> and <tt>realToFrac</tt>. <tt>NominalDiffTime</tt> is also a member of <tt>RealFrac</tt> and <tt>Real</tt> so <tt>round</tt> and <tt>realToFrac</tt> can operate on it.
 
<tt>NominalDiffTime</tt> is a member of the <tt>Num</tt> and <tt>Fractional</tt>, so can be generated by <tt>fromIntegral</tt> and <tt>realToFrac</tt>. <tt>NominalDiffTime</tt> is also a member of <tt>RealFrac</tt> and <tt>Real</tt> so <tt>round</tt> and <tt>realToFrac</tt> can operate on it.
Line 47: Line 47:
 
== Day ==
 
== Day ==
   
So far our data have denoted occurances of events by counting the number of days, or the number of seconds since some fixed reference epoch. However we usally tell time by using years, months, day of month, hours, minutes and seconds. The remain data types will assist with this more usual approach to telling time.
+
So far our data have denoted occurrences of events by counting the number of days, or the number of seconds since some fixed reference epoch. However we usually tell time by using years, months, day of month, hours, minutes and seconds. The remain data types will assist with this more usual approach to telling time.
   
The <tt>Day</tt> data type is an abstract way of refering to a calender date. Due to time zone issue, the <tt>Day</tt> does not necessarily refer to any particular 1-day long absolute time period.
+
The <tt>Day</tt> data type is an abstract way of referring to a calender date. Due to time zone issue, the <tt>Day</tt> does not necessarily refer to any particular 1-day long absolute time period.
   
The standard calender used to reference a date is the Gregorian calendar. The <tt>toGregorian</tt> and <tt>fromGregorian</tt> functions will construct and deconstruct a <tt>Day</tt> from the usual year-month-day format. There are other calendars, such as the Julian calendar, which are only used in unsual situations.
+
The standard calender used to reference a date is the Gregorian calendar. The <tt>toGregorian</tt> and <tt>fromGregorian</tt> functions will construct and deconstruct a <tt>Day</tt> from the usual year-month-day format. There are other calendars, such as the Julian calendar, which are only used in unusual situations.
   
 
== TimeOfDay ==
 
== TimeOfDay ==
   
<tt>TimeOfDay</tt> represents "wall-clock" time. It consists of an hour of the day, a minute of the hour, and a second of the minute, including fractions of a second upto a precession of 10-12. The seconds could go upto 61 in order to accomodate leap seconds.
+
<tt>TimeOfDay</tt> represents "wall-clock" time. It consists of an hour of the day, a minute of the hour, and a second of the minute, including fractions of a second up to a precession of 10-12. The seconds could go up to 61 in order to accommodate leap seconds.
   
 
== LocalTime ==
 
== LocalTime ==
Line 61: Line 61:
 
A <tt>Day</tt> with a <tt>TimeOfDay</tt> forms a <tt>LocalTime</tt>. This is contains the data that we normally denote time with: a year, month, day, hour, minute, and second. However it does not denote an absolute time because it contains no time zone information.
 
A <tt>Day</tt> with a <tt>TimeOfDay</tt> forms a <tt>LocalTime</tt>. This is contains the data that we normally denote time with: a year, month, day, hour, minute, and second. However it does not denote an absolute time because it contains no time zone information.
   
LocalTime is used represent date and time for printing and parsing; however it should be avoided for computation. The biggest problem with LocalTime is that, due to daylight savings time, regualarly the same time of day is repeated twice a day. This means you cannot even use LocalTimes to reliably determine the relative order of events.
+
<tt>LocalTime</tt> is used represent date and time for printing and parsing; however it should be avoided for computation. The biggest problem with <tt>LocalTime</tt> is that, due to daylight savings time, regualarly the same time of day is repeated twice a day. This means you cannot even use <tt>LocalTime</tt>s to reliably determine the relative order of events.
   
 
== TimeZone ==
 
== TimeZone ==
   
Somewhat confusingly named, a <tt>TimeZone</tt> represents an offset from UTC measured in minutes. It also contains ancilery data such as the timezone name and whether or not it is intended to be used for summer time only. Eastern Standard Time (EST) or Pacific Daylight Time (PDT) are examples of timezone that could be represented by a <tt>TimeZone</tt> value.
+
Somewhat confusingly named, a <tt>TimeZone</tt> represents an offset from UTC measured in minutes. It also contains ancillary data such as the timezone name and whether or not it is intended to be used for summer time only. Eastern Standard Time (EST) or Pacific Daylight Time (PDT) are examples of timezone that could be represented by a <tt>TimeZone</tt> value.
   
 
It does not represent the time zone of a region, such as Eastern Time, because regions often vary their offsets from UTC depending on the time of year.
 
It does not represent the time zone of a region, such as Eastern Time, because regions often vary their offsets from UTC depending on the time of year.
   
The <tt>utc</tt> value is the value of the <tt>TimeZone</tt> with no offest from UTC.
+
The <tt>utc</tt> value is the value of the <tt>TimeZone</tt> with no offset from UTC.
   
 
== ZonedTime ==
 
== ZonedTime ==

Revision as of 22:23, 27 July 2013

Contents

1 Time

The canonical time library for Haskell is the time library by Ashley Yakeley. There are several similar but different concepts associated with time and the time library keys these different concepts separated by different data types with appropriate transformations between them to keep your logic safe. However, if you are trying to use the wrong data type for the wrong task, you may find yourself frustrated with the time library.

To help avoid frustration, this guide will describe the various data types available in the time library and what concepts they represent in order help make sure you are using the right data type for the right task. The first few data types of this guide are not widely used in practice, but it is important to understand their conceptual uses before moving onto the more complex, but widely used, data types.

1.1 AbsoluteTime

AbsoluteTime is found in the Data.Time.Clock.TAI module. This data type is the most appropriate type for denoting when an event occurs. AbsoluteTime simply counts the number of seconds since the TAI epoch. There are no leap seconds or timezones to worry about. You can compare two AbsoluteTimes directly to determine which one came first. You can reference time as far into the future and past as you like to within a resolution of 10-12 seconds.

Although AbsoluteTime is most appropriate for many tasks, it is rarely used in applications and you will likely never use this data type. Unless you are a particularly pioneering person, you will probably want to use UTCTime which is more widely used in practice.

1.2 DiffTime

DiffTime is used to represent an absolute duration of time measured in seconds. Subtracting two AbsoluteTimes with diffAbsoluteTime will produce a DiffTime and you can add a DiffTime to an AbsoluteTime to produce an offset AbsoluteTime.

DiffTime is a member of the Num and Fractional, so can be generated by fromIntegral and realToFrac. DiffTime is also a member of RealFrac and Real so round and realToFrac can operate on it.

Although DiffTime may be appropriate in some situations where precision differences are required, NominalDiffTime is more often used in practice.

1.3 UniversalTime

The problem with AbsoluteTime is that Earth's rotation rate is not constant. Over the long term, solar noon would drift over time. UniversalTime measures time by counting the number of "solar" rotations of the earth, including fractions of a rotation, of the earth since the MJD (Modifed Julian Date) epoch.

The variations in the Earth's rotation means that a difference in UniversialTime does not correspond to any particular amount of time. Your computer's hardware cannot track UniversalTime since it can only measure absolute durations. Converting between UniversalTime and AbsoluteTime would require a database build upon astronomical observations. No such conversion utilities are provided.

UniversalTime is almost never used in practice.

1.4 UTCTime

UTCTime measures "Coordinated Universal Time". One second of UTCTime is a constant amount of time equal to one second of AbsoluteTime. However, in order to keep "coordinated" with Universal Time, the number of seconds per day varies. Most days have 86400 seconds; however, on occasion a day will have a "leap second" mean the day will consist of 86399 or 86401 seconds. UTCTime counts the number of integers days (rotations of the earth) since the MJD epoch plus an absolute time difference up to the number of seconds that occur in that day.

It is unpredictable which days will have a leap second and a leap second table is needed to convert between AbsoluteTime and UTCTime. This conversion can only be done reliably within recent history.

UTCTime is the most popular way of referencing events in absolute time. Events occurring hundreds or years ago can be referenced with moderate precision because we may know when during a particular day they occurred, even though we won't know the AbsoluteTime that they occurred. Events occurring in the recent past can be converted to AbsoluteTime. Future events are usually set relative to the day in which they are to occur, so the fact that the absolute time that they will occur at (that is exact the number seconds into the future that they will occur) is unknown is often not a problem.

The major disadvantage with UTCTime is that one cannot compute the absolute difference between two UTCTimes without first converting them to AbsoluteTime, and that requires an accurate leap second tables. To circumvent this issue, one uses NominalDiffTime instead.

1.5 NominalDiffTime

The diffUTCTime function computes a NominalDiffTime between two UTCTimes which is the number of seconds that would have occurred between two UTCTime if no leap seconds had occurred between the two events. Therefore the diffUTCTime is not suitable for measuring the absolute time between two events to within a second's worth of precession. However a NominalDiffTime is often suitable for advancing an event by a week, a day, or an hour, since one would normally want said event to occur at the same time of day, or same minute of the hour, regardless of whether or not a leap second happens to be inserted in that duration.

NominalDiffTime is a member of the Num and Fractional, so can be generated by fromIntegral and realToFrac. NominalDiffTime is also a member of RealFrac and Real so round and realToFrac can operate on it.

NominialDiffTime is regularly used. In fact, POSIXTime the NominalDiffTime since the UNIX epoch of Jan 1st, 1970, UTC.

1.6 Day

So far our data have denoted occurrences of events by counting the number of days, or the number of seconds since some fixed reference epoch. However we usually tell time by using years, months, day of month, hours, minutes and seconds. The remain data types will assist with this more usual approach to telling time.

The Day data type is an abstract way of referring to a calender date. Due to time zone issue, the Day does not necessarily refer to any particular 1-day long absolute time period.

The standard calender used to reference a date is the Gregorian calendar. The toGregorian and fromGregorian functions will construct and deconstruct a Day from the usual year-month-day format. There are other calendars, such as the Julian calendar, which are only used in unusual situations.

1.7 TimeOfDay

TimeOfDay represents "wall-clock" time. It consists of an hour of the day, a minute of the hour, and a second of the minute, including fractions of a second up to a precession of 10-12. The seconds could go up to 61 in order to accommodate leap seconds.

1.8 LocalTime

A Day with a TimeOfDay forms a LocalTime. This is contains the data that we normally denote time with: a year, month, day, hour, minute, and second. However it does not denote an absolute time because it contains no time zone information.

LocalTime is used represent date and time for printing and parsing; however it should be avoided for computation. The biggest problem with LocalTime is that, due to daylight savings time, regualarly the same time of day is repeated twice a day. This means you cannot even use LocalTimes to reliably determine the relative order of events.

1.9 TimeZone

Somewhat confusingly named, a TimeZone represents an offset from UTC measured in minutes. It also contains ancillary data such as the timezone name and whether or not it is intended to be used for summer time only. Eastern Standard Time (EST) or Pacific Daylight Time (PDT) are examples of timezone that could be represented by a TimeZone value.

It does not represent the time zone of a region, such as Eastern Time, because regions often vary their offsets from UTC depending on the time of year.

The utc value is the value of the TimeZone with no offset from UTC.

1.10 ZonedTime

A ZonedTime is a LocalTime together with a TimeZone. This does refer to a specific event in absolute time and can be converted to a UTCTime with the zoneTimeToUTC function, and could be further converted into a AbsoluteTime if one has a leap second table.

There are, of course, many different ZonedTime values corresponding to the same absolute, UTCTime. Given a TimeZone one can create a ZonedTime with that TimeZone by using the utcToZonedTime function.

ZoneTime is a common stop when converting common year-month-day-hour-minute-second human time format and an absolute UTCTime time.

1.11 TimeZoneSeries

Almost nothing in the time library deals with regional time zones such as "Eastern Time" or "Pacific time" For that we need to reach out to the timezone-series and timezone-olson packages. The difficulty with regional time zones is, like leap seconds, that they are unpredicable and subject to be changed.

A TimeZoneSeries is a series of TimeZones, that is offsets from UTC, along with the absolute times where those TimeZones are in effect. This is a suitable structure for defining a regional time zone. The functions in the timezone-olson package will allow you to create a TimeZoneSeries from an Olson time zone database file.

1.12 getTimeZone

There there is one set of functions in the time library that does deal with regional time zones. The getTimeZone function will compute the timezone for a given, absolute, UTCTime, but only the local region as set by the TZ environment variable. The getCurrentTimeZone, getZonedTime, and utcToLocalZonedTime are functions derived from getTimeZone.