The management of time and holidays can prove crucial in applications that rely on historical data. A typical example is the aggregation of a data set recorded in different time zones and under different daylight saving time rules. Besides the time zone conversion function, which is well supported by default classes in R, one might need functions to handle special days or holidays. In this respect, the package timeDate enhances default date-time classes in R and brings new functionalities to time zone management and the creation of holiday calendars.
1Chronological data sets recorded in different time zones play an important role in industrial applications. For example, in financial applications, it is common to aggregate time series that have been recorded in financial centers with different daylight saving time (DST) rules and time zones.
R includes different classes to represent dates and time. The class that
holds particular interest for us is the "POSIXct"
one. It internally
records timestamps as the number of seconds from “1970-01-01 UTC”, where
UTC stands for universal time coordinated. Moreover, it supports the DST
and time zone functions by using the rules provided by the operating
system (OS). However, at the time
timeDate
((Würtz and Y. Chalabi with contribution from M. Maechler, J.W. Byers, and others 2011))—formerly known as
fCalendar—was first
released, the implementation of the DST function was not consistent
across OSs. Back then, the main purpose of the package was to have DST
rules directly available to bring consistency over OSs. Today, DST
support by OSs is not a problematic question as it used to be. As we
will show later, the "timeDate"
class is based on the "POSIXct"
one.
Both classes hence share common functionalities. However, the
timeDate package has
some additional functionalities, which we will emphasize in this note.
For related date-time classes in R, see (Ripley and K. Hornik 2001) and
(Grothendieck and T. Petzoldt 2004).
Another problem commonly faced in managing time and dates is the midnight standard. Indeed, the problem can be handled in different ways depending on the standard in use. For example, the standard C library does not allow for the “midnight” standard in the format “24:00:00” ((Bateman 2000)). However, the timeDate package supports this format.
Moreover, timeDate includes functions for calendar manipulations, business days, weekends, and public and ecclesiastical holidays. One can handle day count conventions and rolling business conventions. Such periods can pertain to, for example, the last working day of the month. The below examples illustrate this point.
In the remaining part of this note, we first present the structure of
the "timeDate"
class. Then, we explain the creation of "timeDate"
objects. The use of financial centers with DST rules is described next.
Thereafter, we explain the management of holidays. Finally, operations
on "timeDate"
objects such as mathematical operations, rounding,
subsetting, and coercions are discussed. Throughout this note, we
provide many examples to illustrate the functionalities of the package.
"timeDate"
classThe "timeDate"
S4
class is composed of a "POSIXct"
object that is
always in Greenwich Mean Time (GMT) and of a financial center that keeps
track of DST. We use the term financial center to denote geographical
locations. This terminology stems from the main application of the
Rmetrics packages. However, this denomination should not stop
programmers from using the package in other fields. By default, the
local financial center is set to GMT. The default setting can be changed
via setRmetricsOptions(myFinCenter = ....)
. The formal S4
class is
defined as
> showClass("timeDate")
"timeDate" [package "timeDate"]
Class
:
Slots
: Data format FinCenter
Name: POSIXct character character Class
where the slot Data
contains the timestamps in the POSIXct
class,
format
is the format typically applied to Data
, and FinCenter
is
the financial center.
Note: we use the abbreviation GMT equivalently to UTC, the universal time coordinated.
"timeDate"
object creationThere are different ways to generate a "timeDate"
object. It can be
generated using either timeDate()
, timeSequence()
, or
timeCalendar()
.
The function timeDate()
creates a "timeDate"
object from scratch. It
requires a character vector of timestamps and optional arguments to
specify the format of this vector and the financial center. The
financial center can be specified, as mentioned, via
setRmetricsOptions()
or (more cleanly) with the argument FinCenter
.
By default, it is set to GMT2.
In the following, we illustrate the creation of "timeDate"
objects as
well as the method used to convert timestamps from different time zones.
We first create character vectors of two timestamps with the default financial center (GMT):
> Dates <- c("2009-09-28","2010-01-15")
> Times <- c( "23:12:55", "10:34:02")
> charvec <- paste(Dates, Times)
> getRmetricsOption("myFinCenter")
myFinCenter "GMT"
> timeDate(charvec)
GMT1] [2009-09-28 23:12:55] [2010-01-15 10:34:02] [
As a second step, we set the local financial center to Zurich and create
a "timeDate"
object.
> setRmetricsOptions(myFinCenter = "Zurich")
> timeDate(charvec)
Zurich1] [2009-09-28 23:12:55] [2010-01-15 10:34:02] [
The third example shows how the timestamps can be conveniently converted
into different time zones; charvec
is recorded in Tokyo and
subsequently converted to our local center, i.e., Zurich (see above):
> timeDate(charvec, zone = "Tokyo")
Zurich1] [2009-09-28 16:12:55] [2010-01-15 02:34:02] [
or converted from Zurich to New York:
> timeDate(charvec, zone = "Zurich",
+ FinCenter = "NewYork")
NewYork1] [2009-09-28 17:12:55] [2010-01-15 04:34:02] [
It is also possible to use the function finCenter()
to view or modify
the local center:
> td <- timeDate(charvec, zone = "Zurich",
+ FinCenter = "NewYork")
> finCenter(td)
1] "NewYork" [
> finCenter(td) <- "Zurich"
> td
Zurich1] [2009-09-28 23:12:55] [2010-01-15 10:34:02] [
If the format of charvec
is not specified,
timeDate uses an
automated date-time format identifier called whichFormat()
that
supports common date-time formats.
> whichFormat(charvec)
1] "%Y-%m-%d %H:%M:%S" [
The function timeSequence()
creates a "timeDate"
object representing
an equidistant sequence of points in time. You can specify the range of
dates with the arguments from
and to
. If from
is missing,
length.out
defines the length of the sequence. In the case of a
monthly sequence, you can define specific rules. For example, you can
generate the sequence with the last days of the month or with the last
or n-th Friday of every month. This can be of particular interest in
financial applications.
Let us first reset the financial center to an international environment:
> setRmetricsOptions(myFinCenter = "GMT")
> # 'timeDate' is now in the financial center "GMT"
> timeDate(charvec)
GMT1] [2009-09-28 23:12:55] [2010-01-15 10:34:02] [
A sequence of days or months can be created as follows:
> # first three days in January 2010,
> timeSequence(from = "2010-01-01",
+ to = "2010-01-03", by = "day")
GMT1] [2010-01-01] [2010-01-02] [2010-01-03] [
> # first 3 months in 2010:
> timeSequence(from = "2010-01-01",
+ to = "2010-03-31", by = "month")
GMT1] [2010-01-01] [2010-02-01] [2010-03-01] [
The function timeCalendar()
creates "timeDate"
objects from calendar
atoms. You can specify values or vectors of equal length denoting year,
month, day, hour, minute, and seconds as integers. For example, the
monthly calendar of the current year or a specific calendar in a given
time zone can be created as follows:
> timeCalendar()
GMT1] [2011-01-01] [2011-02-01] [2011-03-01]
[4] [2011-04-01] [2011-05-01] [2011-06-01]
[7] [2011-07-01] [2011-08-01] [2011-09-01]
[10] [2011-10-01] [2011-11-01] [2011-12-01] [
The following represents the first four days of January recorded in Tokyo at local time “16:00” and converted to the financial center Zurich:
> timeCalendar(2010, m=1, d=1:4, h=16,
+ zone = "Tokyo", FinCenter = "Zurich")
Zurich1] [2010-01-01 08:00:00] [2010-01-02 08:00:00]
[3] [2010-01-03 08:00:00] [2010-01-04 08:00:00] [
The "timeDate"
printing format is designed in accordance with the
(ISO-8601 1988) standard. It uses the 24-hour clock format. Dates are expressed
in the “%Y-%m-%d” format while time-dates are stated in the “%Y-%m-%d
%H:%M:%S” format. A special case in the 24-hour clock system is the
representation of midnight. It can be equivalently represented by
“00:00” and “24:00”. The former is usually used to denote the beginning
of the day whereas the latter denotes the end. timeDate
supports the
midnight standard as described by the (ISO-8601 1988) standard as illustrated
here:
> timeDate(ch <- "2010-01-31 24:00:00")
GMT1] [2010-02-01] [
Note, following the revision of this paper, the R source has been amended in May 2011 to also allow “24:00” time specifications, such that a midnight standard will be part of standard R.
As mentioned earlier, the global financial center can be set with the
function setRmetricsOptions()
and accessed with the function
getRmetricsOption()
. Its default value is set to “GMT
”:
> getRmetricsOption("myFinCenter")
myFinCenter "GMT"
> # change to Zurich:
> setRmetricsOptions(myFinCenter = "Zurich")
From now on, all dates and times are handled in accordance with the Central European time zone and the DST rule for Zurich. Note that setting the financial center to a continent/city that lies outside the time zone used by your OS does not change any of the time settings or environment variables of your computer.
There are almost 400 financial centers supported thanks to the Olson
database. They can be accessed by the function listFinCenter()
, and
partial lists can be extracted through the use of regular expressions.
> # first few financial centers:
> head(listFinCenter())
1] "Africa/Abidjan" "Africa/Accra"
[3] "Africa/Addis_Ababa" "Africa/Algiers"
[5] "Africa/Asmara" "Africa/Bamako" [
> # European centers starting with A or B:
> listFinCenter("Europe/[AB].*") # -> nine
1] "Europe/Amsterdam" "Europe/Andorra"
[3] "Europe/Athens" "Europe/Belgrade"
[5] "Europe/Berlin" "Europe/Bratislava"
[7] "Europe/Brussels" "Europe/Bucharest"
[9] "Europe/Budapest" [
Each financial center has an associated function that returns its DST
rules in the form of a "data.frame"
. These functions share the name of
their financial center, e.g., Zurich()
.
> Zurich()[64:67, ]
Zurich offSet isdst TimeZone64 2010-03-28 01:00:00 7200 1 CEST
65 2010-10-31 01:00:00 3600 0 CET
66 2011-03-27 01:00:00 7200 1 CEST
67 2011-10-30 01:00:00 3600 0 CET
numeric64 1269738000
65 1288486800
66 1301187600
67 1319936400
The returned "data.frame"
shows when the clock was changed in Zurich,
the offset in seconds with respect to GMT, a flag that tells us if DST
is in effect or not, the time zone abbreviation, and the number of
seconds since “1970-01-01” in GMT. The reader interested in the history
of DST is referred to (Bartky and E. Harrison 1979).
Note new centers can be easily added as long as their associated
functions return a "data.frame"
with the same structure as described
above.
Holidays are usually grouped by their origins. The first category, as the etymology suggests, is based on religious origin. For example, the ecclesiastical calendars of Christian churches are based on cycles of movable and immovable feasts. Christmas, December 25, is the principal immovable feast, whereas Easter is the principal movable feast. Most of the other dates are movable feasts that are determined with respect to Easter, (Montes 1996). A second category of holidays is secular holidays, which denotes days that are celebrated internationally and in different cultures, such as Labor Day. Another category of holidays includes days that are relative to natural events. For example, the dates can be related to astronomical events such as cycles of the moon or the equinox. Moreover, there are also country-specific national holidays.
The calculation of holidays might prove tedious in some circumstances. Indeed, the estimation of the Easter date is a complex procedure with different algorithms involved in its computation. The algorithm implemented in the package is the one of Oudin (1940) as quoted in (Seidelmann (Editor) 1992). This approach is valid for any Gregorian calendar year. Further details about holiday calculation can be found in (Tøndering 2008).
The dates of Easter for the next five years can be calculated with
> thisYear <- getRmetricsOption("currentYear")
> Easter(thisYear:(thisYear+5))
Zurich1] [2011-04-24] [2012-04-08] [2013-03-31]
[4] [2014-04-20] [2015-04-05] [2016-03-27] [
The timeDate package
includes functions for bank holidays in Canada, France, Germany, Great
Britain, Italy, Japan3, Switzerland, and the US. These holidays can
be grouped in calendars. At the moment, the package provides functions
for the New York stock exchange, holidayNYSE()
; for the North American
Reliability Council, holidayNERC()
4; for the Toronto stock exchange
holidayTSX()
, and for Zurich, holidayZURICH()
. Other calendars can
be easily implemented given that the package already provides many
holidays functions. A list of all holidays is provided in the appendix.
It is possible to construct tests for weekdays, weekends, business days,
and holidays with the functions isWeekday()
, isWeekend()
,
isBizday()
and isHoliday()
, respectively.
Let us take a sequence of dates around Easter:
> Easter(2010)
Zurich1] [2010-04-04] [
> (tS <- timeSequence(Easter(2010, -2),
+ Easter(2010, +3)))
Zurich1] [2010-04-02] [2010-04-03] [2010-04-04]
[4] [2010-04-05] [2010-04-06] [2010-04-07] [
We can now extract the weekdays or business days according to a holiday calendar.
> (tS1 <- tS[isWeekday(tS)])
Zurich1] [2010-04-02] [2010-04-05] [2010-04-06]
[4] [2010-04-07] [
> (tS2 <- tS[isBizday(tS, holidayZURICH(2010))])
Zurich1] [2010-04-06] [2010-04-07] [
> dayOfWeek(tS2)
2010-04-06 2010-04-07
"Tue" "Wed"
Thank to the comments of one of the referees, we have added a new
argument, wday
, in the functions isWeekend()
, isWeekday()
,
isBizday()
and isHoliday()
that can be used to specify which days
should be considered as business days. This is important when using
calendars in Islamic countries or in Israel. By default, wday
specifies the weekdays as Monday to Friday.
As mentioned earlier, holidays often refer to a specific date or event. It is therefore crucial to have functions to compute: the first day in a given month, the last day in a given month and year, a given day before or after a date, the n-th occurrences of a day in a specified year/month, or a given last day for a specified year/month. We have summarized these functions in a table in the appendix.
In the following, we demonstrate how to retrieve the last day in each quarter or the second Sunday of each month. Note that days are numbered from 0 to 6 where 0 corresponds to Sunday and 6 to Saturday.
> charvec <- c("2011-03-01", "2011-04-01")
> # Last day in quarter
> timeLastDayInQuarter(charvec)
Zurich1] [2011-03-31] [2011-06-30] [
> # Second Sunday of each month:
> timeNthNdayInMonth(charvec, nday = 0, nth = 2)
Zurich1] [2011-03-13] [2011-04-10] [
> # Closest Friday that occurred before:
> timeNdayOnOrBefore(charvec, nday = 5)
Zurich1] [2011-02-25] [2011-04-01] [
"timeDate"
objectsJust like the other date-time classes in R, the "timeDate"
class
supports common operations. It allows for mathematical operations such
as addition, subtraction, and comparisons to be performed. Moreover,
methods for the generic functions to concatenate, replicate, sort,
re-sample, unify, revert, or lag are available as the well known calls
c()
, rep()
, sort()
, sample()
, unique()
, rev()
, and diff()
,
respectively. We spare the reader superfluous examples of functions that
are common to other date-time classes. In the rest of the section, we
emphasize methods that are not available for other classes or are not
strictly identical. The reader is referred to the ebook “Chronological
Objects with Rmetrics” (Würtz, Y. Chalabi and A. Ellis 2010) for more examples.
The timeDate package
has different functions to subset a timeDate
object. The usual
function [
extracts or replaces subsets of "timeDate"
objects as
expected. However, the package provides some additional functions. For
example, the function window()
extracts a sequence from a starting and
ending point. The functions start()
and end()
extract the first and
last timestamps, respectively.
The package provides both S3
and S4
methods to coerce to and from
"timeDate"
objects. Below, we list the S4
coercion methods
available. The equivalent S3
methods as.*
are also provided,
although the mixing of S4
classes and S3
methods is discouraged.
Note that information can be lost in the coercion process if the
destination class does not support the same functionality.
> showMethods("coerce", class = "timeDate")
: coerce (package methods)
Function="ANY", to="timeDate"
from="Date", to="timeDate"
from="POSIXt", to="timeDate"
from="timeDate", to="Date"
from="timeDate", to="POSIXct"
from="timeDate", to="POSIXlt"
from="timeDate", to="character"
from="timeDate", to="data.frame"
from="timeDate", to="list"
from="timeDate", to="numeric" from
We would like to point out a particular difference between the
as.numeric
methods of "timeDate"
and "POSIXct"
classes. Indeed,
the as.numeric-timeDate
method returns the time in minutes, in
contrast to as.numeric.POSIXct
, which returns the results in seconds.
However, the as.numeric-timeDate
method has an additional argument,
unit
, to select other units. These include seconds, hours, days, and
weeks.
The concatenation c()
method for "timeDate"
objects takes care of
the different financial centers of the object to be concatenated. In
such cases, all timestamps are transformed to the financial center of
the first "timeDate"
object. This feature is now also supported by R’s
"POSIXct"
class. However, it was not available in previous versions of
the class.
> ZH <- timeDate("2010-01-01 16:00", zone = "GMT",
+ FinCenter = "Zurich")
> NY <- timeDate("2010-01-01 18:00", zone = "GMT",
+ FinCenter = "NewYork")
> c(ZH, NY)
Zurich1] [2010-01-01 17:00:00] [2010-01-01 19:00:00] [
> c(NY, ZH)
NewYork1] [2010-01-01 13:00:00] [2010-01-01 11:00:00] [
The rounding and truncation methods have similar functionalities to
those of their counterparts in other date-time classes. However, the
default unit
argument is not the same.
The timeDate package offers functions for calendar manipulations for business days, weekends, and public and ecclesiastical holidays that are of interest in financial applications as well as in other fields. Moreover, the Financial Center concept facilitates the mixing of data collected in different time zones and the manipulation of data recorded in the same time zone but with different DST rules.
We thank the anonymous referees and the editor for their valuable comments as well as all R users and developers who have helped us to improve the timeDate package.
> toLatex(sessionInfo())
R version 2.13.0 (2011-04-13), x86_64-apple-darwin10.7.0
Locale: C ...
Base packages: base, datasets, grDevices, graphics, methods, stats, utils
Other packages: timeDate 2130.93
1. Special dates | |
---|---|
timeFirstDayInMonth |
First day in a given month |
timeLastDayInMonth |
Last day in a given month |
timeFirstDayInQuarter |
First day in a given quarter |
timeLastDayInQuarter |
Last day in a given quarter |
timeNdayOnOrAfter |
Day "on-or-after" n-days |
timeNdayOnOrBefore |
Day "on-or-before" n-days |
timeNthNdayInMonth |
N-th occurrence of a n-day in month |
timeLastNdayInMonth |
Last n-day in month |
2. List of holidays | |
---|---|
Advent1st |
JPBunkaNoHi |
Advent2nd |
JPChildrensDay |
Advent3rd |
JPComingOfAgeDay |
Advent4th |
JPConstitutionDay |
AllSaints |
JPEmperorsBirthday |
AllSouls |
JPGantan |
Annunciation |
JPGreeneryDay |
Ascension |
JPHealthandSportsDay |
AshWednesday |
JPKeirouNOhi |
AssumptionOfMary |
JPKenkokuKinenNoHi |
BirthOfVirginMary |
JPKenpouKinenBi |
BoxingDay |
JPKinrouKanshaNoHi |
CACanadaDay |
JPKodomoNoHi |
CACivicProvincialHoliday |
JPKokuminNoKyujitu |
CALabourDay |
JPMarineDay |
CAThanksgivingDay |
JPMidoriNoHi |
CAVictoriaDay |
JPNatFoundationDay |
CHAscension |
JPNationHoliday |
CHBerchtoldsDay |
JPNationalCultureDay |
CHConfederationDay |
JPNewYearsDay |
CHKnabenschiessen |
JPRespectForTheAgedDay |
CHSechselaeuten |
JPSeijinNoHi |
CaRemembranceDay |
JPShuubunNoHi |
CelebrationOfHolyCross |
JPTaiikuNoHi |
ChristTheKing |
JPTennouTanjyouBi |
ChristmasDay |
JPThanksgivingDay |
ChristmasEve |
JPUmiNoHi |
CorpusChristi |
LaborDay |
DEAscension |
MassOfArchangels |
DEChristmasEve |
NewYearsDay |
DECorpusChristi |
PalmSunday |
DEGermanUnity |
Pentecost |
DENewYearsEve |
PentecostMonday |
Easter |
PresentationOfLord |
EasterMonday |
Quinquagesima |
EasterSunday |
RogationSunday |
Epiphany |
Septuagesima |
FRAllSaints |
SolemnityOfMary |
FRArmisticeDay |
TransfigurationOfLord |
FRAscension |
TrinitySunday |
FRAssumptionVirginMary |
USCPulaskisBirthday |
FRBastilleDay |
USChristmasDay |
FRFetDeLaVictoire1945 |
USColumbusDay |
GBBankHoliday |
USDecorationMemorialDay |
GBMayDay |
USElectionDay |
GBMilleniumDay |
USGoodFriday |
GBSummerBankHoliday |
USInaugurationDay |
GoodFriday |
USIndependenceDay |
ITAllSaints |
USLaborDay |
ITAssumptionOfVirginMary |
USLincolnsBirthday |
ITEpiphany |
USMLKingsBirthday |
ITImmaculateConception |
USMemorialDay |
ITLiberationDay |
USNewYearsDay |
ITStAmrose |
USPresidentsDay |
JPAutumnalEquinox |
USThanksgivingDay |
JPBankHolidayDec31 |
USVeteransDay |
JPBankHolidayJan2 |
USWashingtonsBirthday |
JPBankHolidayJan3 |
This article is converted from a Legacy LaTeX article using the texor package. The pdf version is the official version. To report a problem with the html, refer to CONTRIBUTE on the R Journal homepage.
Text and figures are licensed under Creative Commons Attribution CC BY 4.0. The figures that have been reused from other sources don't fall under this license and can be recognized by a note in their caption: "Figure from ...".
For attribution, please cite this work as
Chalabi, et al., "Rmetrics - timeDate Package", The R Journal, 2011
BibTeX citation
@article{RJ-2011-001, author = {Chalabi, Yohan and Mächler, Martin and Würtz, Diethelm}, title = {Rmetrics - timeDate Package}, journal = {The R Journal}, year = {2011}, note = {https://rjournal.github.io/}, volume = {3}, issue = {1}, issn = {2073-4859}, pages = {19-24} }