What’s New Date & Time Computation

Nick Lariviere, Wolfram Research

Join the Conversation #WolframTechConf

Overview

Concepts and definitions

DateObject as a constructor & container

DateObject date representation

Granularity

CalendarType

TimeZone

TimeSystem

More future projects

Concepts and definitions

Time is the indefinite mono-dimensional physical quantity that expresses past, present and future progress and events. We typically think of time in terms of dates(like “today is October 18th, 2018”) and durations(like “5 minutes”). In examining aspects of time conceptually, it may be useful to compare them to analogous elements of physical space.

Comparison of Time and Space constituent elements

Style[Grid[{
Style[#,Bold]&/@{ "Space","Time","Wolfram Language"},
{"Position","Date","DateObject"}, 
{"Distance","Duration","Quantity"}, 
{"Projection","Calendar","CalendarType"}, 
{"Datum","Time System","TBD"}
},Dividers->{All,{True,True,False}},Alignment->Left,Frame->True],
20]

DateObject as a constructor & container

DateObject is the canonical representation of dates in the Wolfram Language, and acts both as a constructor and a container.

As a constructor

DateObject can be used to construct a date expression(with no arguments otherwise specified, it will return the current instant in time):

DateObject[]

It can also construct a date expression using other date representations in the Wolfram Language, including date strings, date lists, and absolute time specifications:

DateObject/@{"Wed 17 Oct 2018 15:24:06",{2018,10,17,15,24,6.370177`7.556726487214414},3.748778646370185`*^9}

DateObject can also be used to modify existing dates to construct other moments, such as by changing the granularity of the date:

DateObject[(DateObject["Wed 17 Oct 2018 15:24:36""GMT"-5.`, DateObject[{2018,10,17,15,24,36.292353`8.31239010576097},"Instant","Gregorian",-5.`]]),"Day"]

As a container

DateObject also acts as a container expression, carrying it’s payload of information to be interpreted by other functions in the Wolfram Language.

(DateObject["Thu 18 Oct 2018 13:00:01""CDT", DateObject[{2018,10,18,13,0,1},"Instant","Gregorian","America/Chicago"]])["Properties"]

DateValue[(DateObject["Thu 18 Oct 2018 13:00:01""CDT", DateObject[{2018,10,18,13,0,1},"Instant","Gregorian","America/Chicago"]]),"TimeZone"]

LeapYearQ[(DateObject["Thu 18 Oct 2018 13:00:01""CDT", DateObject[{2018,10,18,13,0,1},"Instant","Gregorian","America/Chicago"]])]

Anatomy of DateObject:

DateObject(currently) contains 4 principal elements that constitute a date in the language:

All 4 of these elements are necessary to fully resolve a date to a given moment in time.

DateObjectQ predicate

Because DateObject is both a constructor and a container, it’s possible for an expression to appear with head DateObject, but not represent a valid date. In such cases the DateObjectQ predicate can be used to test the validity of a given expression:

DateObjectQ[Now]

DateObjectQ[DateObject[foo]]

DateObjectQ["Wed 14 Oct 2018 13:16:49"]

DateObject date representation

The first argument of DateObject is the representational expression for the date associated with the calendar of the date object. Typically this is a list of one or more elements, but in principal may take any number of different forms depending on the calendar associated with the date. The representation is fundamentally tied to the calendar associated with the date.

First[DateObject[]]

DateList[]

DateObject[0,CalendarType->"AbsoluteTime"]//InputForm

Date representations in WL

DateList - a 6-element list specifying year, month, day, hour, minute, and second

DateList[]

AbsoluteTime - a numeric value giving the number of seconds since midnight, January 1, 1900 in your local time zone

AbsoluteTime[]

DateString - a string containing different date string elements

DateString[]

JulianDate - a numeric value giving the number of days since noon GMT on November 24, 4714 BCE

JulianDate[]

UnixTime - a numeric value giving the number of seconds since midnight GMT on January 1, 1970

UnixTime[]

SiderealTime* - a mixed-radix quantity giving the right ascension of the local meridian for a given date and location

SiderealTime[]

Granularity

TimelinePlot[{
DateObject[{2000,6,1}],
DateObject[{2000,8,4}],
DateObject[{2000,2,4}],
Interval[{DateObject[{2000,9}],DateObject[{2000,10}]}],
Interval[{DateObject[{2000,3}],DateObject[{2000,4}]}],Interval[{DateObject[{2000}], DateObject[{2001}]}]}]//Image

Calendar granularity represents a calendar object including and beyond a single instant in time. This representation of calendar object described and determines it’s algebra, and allows a flexible framework for describing dates of varying resolution all within the same object(as opposed to having dedicated objects to represent a given year, or month, or day). Granularity is fundamentally tied to the calendar associated with a date, and can be either a canonical(such as ‘year’) or derived(such as ‘quarter’) granularities.

Now[[2]]

Today[[2]]

available granularities

Currently supported granularity specifications(based on the Gregorian calendar) include:

Grid[
{#,DateObject[Now,#]}& /@ {"Millennium","MillenniumBeginning01","Century","CenturyBeginning01","Decade","Year","Quarter","Month","Week","WeekBeginningSunday","Day","Hour","Minute","Second","Instant"},Alignment->Left
]

additional convenience constructors

The Wolfram Language also includes three convenience constructors to generate dates of a given granularity, CurrentDate, NextDate, and PreviousDate:

CurrentDate["Month"]

NextDate["Year"]

These offset functions also accept a reference date for the offset to use:

PreviousDate[(DateObject["Day: ""Wed 3 Apr 2013", DateObject[{2013,4,3},"Day","Gregorian",-5.`]]),"Week"]

NextDate["WeekendDay"]

Get the last weekday before thanksgiving:

PreviousDate[LinguisticAssistant,"Weekday"]

comparisons

DateObject expressions support ordering using comparisons, accounting for granularity:

Today<Tomorrow

Now==Today

containment

DateWithinQ and DateOverlapsQ can be used to check for full or partial containment of one granular date within another:

DateWithinQ[Today,Now]

DateWithinQ[CurrentDate["Week"],NextDate["Sunday"]]

DateWithinQ[CurrentDate["Week"],NextDate["Monday"]]

DateWithinQ[(DateObject["Month: ""Oct 2018", DateObject[{2018,10},"Month","Gregorian",-5.`]]),(DateObject["Week beginning: ""Mon 29 Oct 2018", DateObject[{2018,10,29},"Week","Gregorian",-5.`]])]

DateOverlapsQ[(DateObject["Month: ""Oct 2018", DateObject[{2018,10},"Month","Gregorian",-5.`]]),(DateObject["Week beginning: ""Mon 29 Oct 2018", DateObject[{2018,10,29},"Week","Gregorian",-5.`]])]

DateOverlapsQ[Today,Tomorrow]

CalendarType

Grid[With[{d=DateObject[CalendarType->#]},{#,DateString[d], First[d]}]&/@{"Gregorian","Jewish","Islamic","ISOWeek","ISOOrdinal","Julian","JulianDate","AbsoluteTime","UnixTime"},Alignment->Left,Dividers->All]

The calendar associated with a date provides a scheme by which to interpret the date representation provided in the first argument. A calendar must principally have a standard notation, normalization scheme, and epoch conversion function(a method to convert to/from a common reference date, commonly either the JulianDate epoch, or January 1st  1 CE). The Wolfram Language includes 6 primary calendar types: Gregorian(Default), Jewish(Hebrew), Islamic(Um Al’Qura), ISOWeek(ISO-8601 week day), ISOOrdinal(ISO-8601 year day), and Julian, with more coming in future versions.

Grid[{#,DateObject[Today,CalendarType->#]}&/@{"Gregorian","Jewish","Islamic","ISOWeek","ISOOrdinal","Julian"},Alignment->Left]

In the near future there will also be support for various ‘numeric’ and ‘split’ calendars:

Grid[{#,DateObject[Now,CalendarType->#],First[DateObject[Now,CalendarType->#]]}&/@{"AbsoluteTime","JulianDate","UnixTime","SplitAbsoluteTime","SplitJulianDate","SplitUnixTime"},Alignment->Left]

Other calendars types

Japanese Gengo  - extension of Gregorian calendar including period names

{"Heisei", 30, 10, 18}

Mesoamerican Long Count - (modified)vigesimal calendar using 5 - 9 base-20 steps( and 18 for ‘tun’)

{13,0,5,16,7}

Lunisolar - includes both moon phase and solar year(tropical or sidereal)

{2145,9,9}

TimeZone

GeoGraphics[Prepend[{RandomColor[],Polygon[#]}&/@{(Entity["America/Boise", Entity["TimeZone","America/Boise"], "Entity[\"TimeZone\", \"America/Boise\"]", "time zone"]),(Entity["America/Chicago", Entity["TimeZone","America/Chicago"], "Entity[\"TimeZone\", \"America/Chicago\"]", "time zone"]),(Entity["America/Denver", Entity["TimeZone","America/Denver"], "Entity[\"TimeZone\", \"America/Denver\"]", "time zone"]),(Entity["America/Detroit", Entity["TimeZone","America/Detroit"], "Entity[\"TimeZone\", \"America/Detroit\"]", "time zone"]),(Entity["America/Indiana/Indianapolis", Entity["TimeZone","America/Indiana/Indianapolis"], "Entity[\"TimeZone\", \"America/Indiana/Indianapolis\"]", "time zone"]),(Entity["America/Indiana/Knox", Entity["TimeZone","America/Indiana/Knox"], "Entity[\"TimeZone\", \"America/Indiana/Knox\"]", "time zone"]),(Entity["America/Indiana/Marengo", Entity["TimeZone","America/Indiana/Marengo"], "Entity[\"TimeZone\", \"America/Indiana/Marengo\"]", "time zone"]),(Entity["America/Indiana/Petersburg", Entity["TimeZone","America/Indiana/Petersburg"], "Entity[\"TimeZone\", \"America/Indiana/Petersburg\"]", "time zone"]),(Entity["America/Indiana/Tell_City", Entity["TimeZone","America/Indiana/Tell_City"], "Entity[\"TimeZone\", \"America/Indiana/Tell_City\"]", "time zone"]),(Entity["America/Indiana/Vevay", Entity["TimeZone","America/Indiana/Vevay"], "Entity[\"TimeZone\", \"America/Indiana/Vevay\"]", "time zone"]),(Entity["America/Indiana/Vincennes", Entity["TimeZone","America/Indiana/Vincennes"], "Entity[\"TimeZone\", \"America/Indiana/Vincennes\"]", "time zone"]),(Entity["America/Indiana/Winamac", Entity["TimeZone","America/Indiana/Winamac"], "Entity[\"TimeZone\", \"America/Indiana/Winamac\"]", "time zone"]),(Entity["America/Kentucky/Louisville", Entity["TimeZone","America/Kentucky/Louisville"], "Entity[\"TimeZone\", \"America/Kentucky/Louisville\"]", "time zone"]),(Entity["America/Kentucky/Monticello", Entity["TimeZone","America/Kentucky/Monticello"], "Entity[\"TimeZone\", \"America/Kentucky/Monticello\"]", "time zone"]),(Entity["America/Los_Angeles", Entity["TimeZone","America/Los_Angeles"], "Entity[\"TimeZone\", \"America/Los_Angeles\"]", "time zone"]),(Entity["America/Menominee", Entity["TimeZone","America/Menominee"], "Entity[\"TimeZone\", \"America/Menominee\"]", "time zone"]),(Entity["America/New_York", Entity["TimeZone","America/New_York"], "Entity[\"TimeZone\", \"America/New_York\"]", "time zone"]),(Entity["America/North_Dakota/Beulah", Entity["TimeZone","America/North_Dakota/Beulah"], "Entity[\"TimeZone\", \"America/North_Dakota/Beulah\"]", "time zone"]),(Entity["America/North_Dakota/Center", Entity["TimeZone","America/North_Dakota/Center"], "Entity[\"TimeZone\", \"America/North_Dakota/Center\"]", "time zone"]),(Entity["America/North_Dakota/New_Salem", Entity["TimeZone","America/North_Dakota/New_Salem"], "Entity[\"TimeZone\", \"America/North_Dakota/New_Salem\"]", "time zone"]),(Entity["America/Phoenix", Entity["TimeZone","America/Phoenix"], "Entity[\"TimeZone\", \"America/Phoenix\"]", "time zone"])},EdgeForm[Black]],GeoRange->{{23.5,49.5},Automatic},GeoProjection->"Mercator",ImageSize->Large]//Image

Time zones represent a region on earth that observe a uniform synchronized time. The Wolfram Language supports 4 different input types for the TimeZone option: Numeric offset, Time Zone ID/Entity, location Entity, and None.

Numeric offset from GMT:

A real or integer, or rational value that’s a number of hours offset from GMT. There are currently 38 official numeric time zone offsets observed across the globe, though WL supports arbitrary offsets as well:

DateObject[Now,TimeZone -> -5]

DateObject[Now,TimeZone -> 6.78]

The Wolfram Engine initializes it’s local time zone using information from the operating system, and your $TimeZone is used as the default time zone value when not otherwise specified:

$TimeZone

Time zone ID

Sometimes also called “internet time zones” these are the time zone identifiers associated with a geographic or legislative region that determines the physical and temporal boundaries associated with a time zone’s offset from GMT. There are currently 470 recognized time zone identifiers corresponding to different geographic regions.

DateObject[Now,TimeZone -> "America/Chicago"]

$TimeZoneEntity

Length[EntityList["TimeZone"]]

Location Entity

Any entity with a “Position” property may be used as a TimeZone specification, where the underlying time zone ID can be fetched from the Wolfram Knowledgebase.

DateObject[Now,TimeZone -> (Entity["Bismarck", Entity["City",{"Bismarck","NorthDakota","UnitedStates"}], "Entity[\"City\", {\"Bismarck\", \"NorthDakota\", \"UnitedStates\"}]", "city"])]

LocalTimeZone[(Entity["Bismarck", Entity["City",{"Bismarck","NorthDakota","UnitedStates"}], "Entity[\"City\", {\"Bismarck\", \"NorthDakota\", \"UnitedStates\"}]", "city"])]

None

TimeZone -> None does not immediately instantiate a TimeZone value in the DateObject, but instead defers determination of the time zone up to the point where it’s required to resolve the date.

DateObject[Now,TimeZone -> None]

Automatic

TimeZone -> Automatic is also supported, which indicates that the time zone should automatically be inherited from it’s argument, and otherwise default to $TimeZone.

DateObject[Now,TimeZone -> Automatic]

Upcoming notation: {id, offset}

TimeZone -> {"America/Chicago", -5}

Both Time Zone ID and numeric offset notations are insufficient to fully specify a moment for all dates within a calendar year because the numeric offset cannot appropriately handle Daylight Saving Time, and the Time Zone ID alone cannot uniquely identify the period of time immediately preceding and following the end of daylight saving time(or in the case of some parts of Australia, the onset thereof). For example:

offset=$TimeZoneEntity["NextDSTShift"];

Column[{offset,Grid[Join[{{"TimeZone","diff 0", "diff -1", "diff -2"}},With[{converted=TimeZoneConvert[offset,#]},{#,offset-converted,offset-(converted-Quantity[1,"Hours"]),offset-(converted-Quantity[2,"Hours"])}]&/@{"GMT","America/Chicago"}
],Alignment -> Left, Frame ->True, Dividers->All]
}]

onset=$TimeZoneEntity["PreviousDSTShift"];

Column[{onset,Grid[Join[{{"TimeZone","diff 0", "diff + 1", "diff + 2"}},With[{converted=TimeZoneConvert[onset,#]},{#,onset-converted,onset-(converted+Quantity[1,"Hours"]),onset-(converted+Quantity[2,"Hours"])}]&/@{"GMT","America/Chicago"}
],Alignment -> Left, Frame ->True, Dividers->All]
}]

TimeSystem

Sometimes called “time standards,” these are specifications about how we measure time. Early time systems were based simply on solar time, which failed to account for irregularities in the earth’s rotation(and in particular it’s continual slowing), and were subsequently replaced by systems that utilized ephemeris time, based on planetary motions. Since the 70s modern time systems are typically based on atomic clocks or very-long-baseline interferometry(VLBI) measurements, and since the 90s also typically account for relativistic corrections. A time system may use any unit as it’s basis, but most systems use either a solar day or SI second(which is based on cycles of a Caesium atomic clock) as their base unit.

In practice, the primary impact of time systems has to do with the method by which leap seconds are accounted for.

International Atomic Time(TIA) is defined retrospectively using a collection of atomic clocks, attempting to match proper time on the geoid.

Coordinated Universal Time(UTC) is an approximation of UT1(which is the principal form of Universal Time).

Geocentric Coordinate Time(TCG) is coordinate time system that represents a clock at rest outside Earth’s gravity well, but which follows it’s same motion.

Global Positioning System Time(GPST) used by GPS systems is not tied to the earth’s rotation and doesn’t account for leap seconds.

Time system support is slated for a future version of the Wolfram Language, and is an important supporting element for many features related to astronomical calculations we hope to include in the language.

Additional Future Features and Functions

Temporal Logic - modal logic concerned with representing and reasoning about time.

Date Intervals - extended periods of time

Recurring Dates - criteria regarding calendar elements, useful in scheduling

Date Arrays - Efficient storage and manipulation of large collections of dates