Dates and the results of date arithmetic are exchanged throughout the world using the international standards "Data elements and interchange formats — Information interchange — Representation of dates and times" (ISO 8601:2004) assembled by the International Organization for Standardization (ISO). When accountants, actuaries and other financial services analysts use the R Statistical Environment ("R") for creating models, they have access to tried-and-true implementations of those standards through R's offering of two "objects" ("classes") to the user: POSIXt and Date. The ability of those two classes to satisfy a broad range of date/time requirements has been an important factor in R's rise in popularity as a scientific analytical tool.
However, those two objects are somewhat unsatisfactory in the financial industry for modeling two key accounting concepts: accounting date and account aging in month units.
The purpose of this paper is show how to define ISO-compliant implementations of accounting date and elapsed time in units of months in an R package.
Base R --
version r paste(R.version$major, R.version$minor, sep=".")
as of this writing --
uses two general "classes" (objects with special properties) for representing
instants in time,
POSIXct
and POSIXlt
,
modeled after the Portable Operating System Interface ("POSIX")
standards for UNIX operating systems.^[IEEE Std 1003.1,
a.k.a. "POSIX.1.",
is a standard for computer operating systems that covers
a variety of topics,
including software structures for representing time.
Much information can be found online;
see for example
http://www.opengroup.org/austin/papers/backgrounder.html.]
Historical background for these classes
can be found in the original paper "Date-Time Classes"
by Brian Ripley and Kurt Hornik.^[R News, 1/2, p. 9.
http://www.r-project.org/doc/Rnews/Rnews_2001-2.pdf]
The POSIXct
class (the "c" stands for
"calendar time")
is built around a numeric
that holds the (potentially fractional)
number of seconds since the beginning of January 1, 1970
"in the UTC time zone."^[See R's help for "DateTimeClasses".
R help on a topic can be read by invoking the function
help
at the console with the topic name in quotes, e.g., help("POSIXt")
.
A shorthand version uses the question mark alone --
?POSIXt
-- often found in the footnotes herein.]
To borrow the words of Ripley and Hornik^["Date-Time Classes"],
this representation of time "is not easily digestible" by the user.
The POSIXlt
class
is a list of a sufficient number of elements such as "year", "mon", "hour", "sec", etc.
so as to completely determine an instant of time in the user's
local time zone and
communicate that instant to the user.
Per ?POSIXlt
, the "l" stands for "local", but could also stand for "list."
In most cases the technical distinctions between the two classes
are of little concern to the user,
with the possible exception of "time zone."
Here is an example of a possible source of confusion.
Let the R variable a
represent the first instant of 1970,
which of course occurs zero seconds "after the beginning of 1970."
R requires that the 1970 "origin" be provided
because POSIXct
objects can potentially reference off of
any time point.
a <- as.POSIXct(0, origin="1970-01-01") a
To display a
at the console,
R uses a POSIXlt
object in the background.
Because the timezone was not set explicitly when a
was defined,
POSIXlt
assumes the user's local time zone
(Pacific Standard Time for this author).
That time-zone shift
between the user's definition of a
and R's regurgitation of a
's value
can be confusing.
If time-zone distinctions are not important,
that confusion can be avoided by always working in the
"UTC time zone."
it was still 8pm December 31st on the California coast,
but that was not how a
was defined so that
is not how one might expect a
to appear when printed.
The reason a
displays in local (PST) time is that R
uses the POSIXlt class at the intermediary between POSIXct
and the character representation to the user,
which, as mentioned previously, defaults to the user's local time zone.
To confirm for yourself that a
really does hold the value
"zero seconds after the beginning of 1970",
simply strip away the accoutrements surrounding a
with the unclass
function:
unclass(a)
So "under the hood" a
is simply the number 0 (zero) with a
"tzone" attribute (which R uses to drive its date/time "class" behavior).
To force R to represent a
in the UTC time zone,
one option is to
use the format
function with the tz
argument as
follows:^[Other options exist.
For a good summary, see David Smith's blog
"Converting time zones in R: tips, tricks and pitfalls,"
Revolutions, June 02, 2009,
http://blog.revolutionanalytics.com/2009/06/converting-time-zones.html.
See also the with_tz
function in the lubridate
package on CRAN:
https://cran.r-project.org/web/packages/lubridate/index.html]
format(a, tz="UTC")
In the remainder of this paper it will be assumed that the timezone is
t <- seq(0,2*pi,length=100) coords <- t(rbind(sin(t), cos(t))) plot(coords, type="l", axes=F, xlab="", ylab="", xlim=c(-1.2,1.2), ylim=c(-1.2,1.2)) a <- -3 r <- sqrt(a*a+1) t <- seq(-atan(-1/a), atan(-1/a), length=100) lines(a+r*cos(t), 0+r*sin(t), lty="dotted") lines(-(a+r*cos(t)), 0+r*sin(t), lty="dotted", col="gray") lines(0+r*sin(t), a+r*cos(t), lty="dotted", col="gray") lines(0+r*sin(t), -(a+r*cos(t)), lty="dotted", col="black") #text(0, 1, "0", pos=3) text(.2, -.1, "0", pos=1) text(0, .7, "UTC", pos=4)
The Date
class in R holds the
number of days since the beginning of January 1, 1970.
It will be important to visit a few "basic concepts" that people understand intuitively but must be defined precisely if computers are to understand too:
Definition: time interval
A time interval is "part of the time axis limited by two instants. [It] comprises all instants between the two limiting instants and, unless otherwise stated, the limiting instants themselves."^[ISO 8601 2.1.3]
Figure 1 below is a diagram of two time intervals A and B. Each includes its respective endpoints as indicated by the square brackets. A and B overlap at time point 1.
op <- par(no.readonly = TRUE) n=3 par(mar=c(1,2,1,2)) par(lend="butt") plot(c(0,n), c(0,0), col="black", type = "l", axes=F, xlim=c(0,n+.15), ylim=c(-.5, .5), xlab="", ylab="") axis(1, pos=0, labels=FALSE, tick=FALSE) arrows(x0=-.1, y0=0, x1=n+.15, length=.1) text(n+.1, 0, "t", pos = 1) axis(1, at=0:2, pos=0) axis(1, at=seq(from=0, to=2, length.out=2*24+1), tcl=par("tcl")*.5, labels=FALSE, pos=0) segments(x0=0.01, y0=0, x1=0.99, col="blue", lwd =4) text(x=0.013, y=0, "[", col="blue", font = 2, cex=2) text(x=0.987, y=0, "]", col="blue", font = 2, cex=2) text(x=0.5, y= .1, "A", col="blue") segments(x0=1.01, y0=0, x1=1.99, col="blue", lwd =4) text(x=1.013, y=0, "[", col="blue", font = 2, cex=2) text(x=1.987, y=0, "]", col="blue", font = 2, cex=2) text(x=1.5, y= .1, "B", col="blue") box("outer") par(op)
Time intervals are generally endowed with more evocative names than "A" and "B", however. For example, if Figure 1 is a diagram of the first few days of calendar year 1970, then more descriptive names for calendar days A and B would be "1970-01-01" and "1970-01-02", using ISO 8601's "complete representation" of a calendar date.^[ISO 8601:2004 4.1.2.2] Those names also apply to all time instants enclosed by the endpoints. This leads to some ambiguity in this example because midnight between January 1st and 2nd is included in both intervals. Such ambiguity can be easily avoided, however, by leaving one of the endpoints "open."
In the case of calendar days, the question is how to represent midnight.
Section 4.2.3 of ISO 8601 says that midnight between January 1st and 2nd, 1970
can be represented as either
Hour 00) 1970-01-02 00:00:00 or
Hour 24) 1970-01-01 24:00:00.
"The choice of representation ... will depend upon any association with a date,
or a time interval."^[ISO 8601:2004 4.2.3]
In the design of an experiment, it seeem natural to associate the beginning of the experiment as belonging to the first time period of the experiment. That suggests a time interval that is closed on the left and open on the right where the initiation of a time interval is included in the interval. Base R's POSIXt implementation follows the hour 00 approach.
Base R's "POSIXt" classes of objects
store time as the number of seconds that have elapsed
since the beginning of 1970.
Midnight is the first instant of a calendar day.
That is easily seen.
Here we tell R to store midnight ending January 1, 1970 in the variable a
.
R is smart enough to understand the hour 24 notation.
However, when we ask R to print that value back to us at the console,
it says that the time point represented in the variable a
is a member of the second day of January.
a <- as.POSIXct("1970-01-01 24:00:00", tz = "UTC") print(a)
Figure 2 below is an illustration of a few of the calendar days surrounding the transition from 1969 to 1970, where the endpoints of the time intervals are represented by POSIXt objects. Since hour 00 begins each day, calendar days are represented by left-closed/right-open time intervals. The endpoints are modeled by POSIXt objects.
op <- par(no.readonly = TRUE) n = 3 a <- as.POSIXct((-n:n)*60*60*24, origin = "1970-01-01 00:00:00", tz="UTC") par(mar=c(1,2,1,2)) par(lend="butt") NDaysInSecs <- 60*60*24*n RadiusOfWindow <- NDaysInSecs + 60*60*24 plot(a, y=rep(0, 2*n+1), type = "l", axes = F, ylim=c(-1, 1), xlim = c(-RadiusOfWindow, RadiusOfWindow), xlab="", ylab="") axis(1, at=a, labels=a, pos=0) arrows(x0=a[1]-60*60*24, y0=0, x1=a[2*n+1]+60*60*24, length=.1, code = 2) text(a[2*n+1]+60*60*12, 0, "t", pos = 1) segments(x0=a[1:(2*n)], y0=0, x1=a[2:(2*n+1)], col="blue", lwd =4) for (i in 1:(2*n)) text(x=a[i] + 15*60, y=0, "[", col="blue", font = 2, cex=2) for (i in 2:(2*n+1)) text(x=a[i] - 15*60, y=0, ")", col="blue", font = 2, cex=2) axis(2, pos=0, labels = FALSE, lwd.ticks=0, lty="dotted") text(0, .8, "origin =\n\"1970-01-01 00:00:00\"", pos=1) box("outer") par(op)
R's left-closed/right-open paradigm runs consistently throughout its representation of time intervals. In Figure 3 below are shown five different time intervals in increasing magnitude. Calendar day, calendar month, and calendar year are defined terms in ISO 8601:2004. "Calendar second, minute and hour" are represented in the same spirit.
Each interval has a "label" (a "mark" in 8601 terminology, also called a "name" in R)
corresponding to the instant beginning the interval.
Note that all first intervals in Fugure 4 are labeled "1970-01-01".
This is an example of R being "helpful":
if the instant corresponds to midnight, R only shows the date.^[In R,
see argument format
under help for strftime
.]
For example,
to show the full date and time for the first instant of 1970
try the format specifier "%Y-%m-%d %H:%M:%S".
FirstInstant <- as.POSIXlt(0, origin="1970-01-01", tz="UTC") format(FirstInstant, usetz=FALSE) format(FirstInstant, format = "%Y-%m-%d %H:%M:%S", usetz=FALSE)
op <- par(no.readonly = TRUE) par(mfrow=c(5,1)) par(mar=c(1,2,1,2)) par(lend="butt") xlab.y <- -.45 # second n=3 plot(c(0,n), c(0,0), col="black", type = "l", axes=F, xlim=c(0,n+.15), ylim=c(-.5, .5), xlab="", ylab="") axis(1, pos=0, labels=FALSE, tick=FALSE) text(n/2, xlab.y, "\"calendar second\" (undefined in ISO 8601:2004)") arrows(x0=-.1, y0=0, x1=n+.15, length=.1) text(n+.1, 0, "t", pos = 1) # major ticks axis(1, at=0:n, pos=0) # minor ticks axis(1, at=seq(from=0, to=n, length.out=n*10+1), tcl=par("tcl")*.5, labels=FALSE, pos=0) for (i in 1:n){ segments(x0=(i-1)+0.01, y0=0, x1=i-.01, col="blue", lwd =4) text(x=(i-1)+0.013, y=0, "[", col="blue", font = 2, cex=2) text(x=i-0.013, y=0, ")", col="blue", font = 2, cex=2) text(x=(i-.5), y= .1, col="blue", labels=format(as.POSIXct((i-1), origin="1970-01-01", tz="UTC") # , format="%Y-%m-%d %H:%M:%S" ) ) } # minute n=3 plot(c(0,n), c(0,0), col="black", type = "l", axes=F, xlim=c(0,n+.15), ylim=c(-.5, .5), xlab="", ylab="") axis(1, pos=0, labels=FALSE, tick=FALSE) text(n/2, xlab.y, "\"calendar minute\" (undefined in ISO 8601:2004)") arrows(x0=-.1, y0=0, x1=n+.15, length=.1) text(n+.1, 0, "t", pos = 1) # major ticks axis(1, at=0:n, pos=0) # minor ticks axis(1, at=seq(from=0, to=n, length.out=n*60+1), tcl=par("tcl")*.5, labels=FALSE, pos=0) for (i in 1:n){ segments(x0=(i-1)+0.01, y0=0, x1=i-.01, col="blue", lwd =4) text(x=(i-1)+0.013, y=0, "[", col="blue", font = 2, cex=2) text(x=i-0.013, y=0, ")", col="blue", font = 2, cex=2) text(x=(i-.5), y= .1, col="blue", labels=format(as.POSIXct((i-1)*60, origin="1970-01-01", tz="UTC") # , format="%Y-%m-%d %H:%M:%S" ) ) } # hour n=3 plot(c(0,n), c(0,0), col="black", type = "l", axes=F, xlim=c(0,n+.15), ylim=c(-.5, .5), xlab="", ylab="") axis(1, pos=0, labels=FALSE, tick=FALSE) text(n/2, xlab.y, "\"calendar hour\" (undefined in ISO 8601:2004)") arrows(x0=-.1, y0=0, x1=n+.15, length=.1) text(n+.1, 0, "t", pos = 1) # major ticks axis(1, at=0:n, pos=0) # minor ticks axis(1, at=seq(from=0, to=n, length.out=n*60+1), tcl=par("tcl")*.5, labels=FALSE, pos=0) for (i in 1:n){ segments(x0=(i-1)+0.01, y0=0, x1=i-.01, col="blue", lwd =4) text(x=(i-1)+0.013, y=0, "[", col="blue", font = 2, cex=2) text(x=i-0.013, y=0, ")", col="blue", font = 2, cex=2) text(x=(i-.5), y= .1, col="blue", labels=format(as.POSIXct((i-1)*60*60, origin="1970-01-01", tz="UTC") # , format="%Y-%m-%d %H:%M:%S" ) ) } # day n=3 plot(c(0,n), c(0,0), col="black", type = "l", axes=F, xlim=c(0,n+.15), ylim=c(-.5, .5), xlab="", ylab="") axis(1, pos=0, labels=FALSE, tick=FALSE) text(n/2, xlab.y, "calendar day (ISO 8601:2004 2.2.6)") arrows(x0=-.1, y0=0, x1=n+.15, length=.1) text(n+.1, 0, "t", pos = 1) # major ticks axis(1, at=0:n, pos=0) # minor ticks axis(1, at=seq(from=0, to=n, length.out=n*24+1), tcl=par("tcl")*.5, labels=FALSE, pos=0) for (i in 1:n){ segments(x0=(i-1)+0.01, y0=0, x1=i-.01, col="blue", lwd =4) text(x=(i-1)+0.013, y=0, "[", col="blue", font = 2, cex=2) text(x=i-0.013, y=0, ")", col="blue", font = 2, cex=2) text(x=(i-.5), y= .1, col="blue", labels=format(as.POSIXct((i-1)*60*60*24, origin="1970-01-01", tz="UTC") # , format="%Y-%m-%d %H:%M:%S" ) ) } # month n=3 plot(c(0,n), c(0,0), col="black", type = "l", axes=F, xlim=c(0,n+.15), ylim=c(-.5, .5), xlab="", ylab="") axis(1, pos=0, labels=FALSE, tick=FALSE) text(n/2, xlab.y, "calendar month (ISO 8601:2004 2.2.11)") arrows(x0=-.1, y0=0, x1=n+.15, length=.1) text(n+.1, 0, "t", pos = 1) # major ticks axis(1, at=0:n, pos=0) # minor ticks axis(1, at=seq(from=0, to=n, length.out=n*30+1), tcl=par("tcl")*.5, labels=FALSE, pos=0) for (i in 1:n){ segments(x0=(i-1)+0.01, y0=0, x1=i-.01, col="blue", lwd =4) text(x=(i-1)+0.013, y=0, "[", col="blue", font = 2, cex=2) text(x=i-0.013, y=0, ")", col="blue", font = 2, cex=2) text(x=(i-.5), y= .1, col="blue", labels=format(ISOdate(1970, i, 1, 0, 0, 0, tz="UTC") # , format="%Y-%m-%d %H:%M:%S" ) ) } box("outer") par(op)
Although R's choice of hour 00 is understandable and defensible, it is nevertheless arbitrary. The hour 24 choice could just as arbitrarily have been made, in which case the intervals in figure 2 would have been left-open/right-closed. Indeed, if Figure 2 were rotated around the origin, the resulting diagram would illustrate a sequence of left-open/right-closed time intervals.
op <- par(no.readonly = TRUE) par(mar=c(1,2,1,2)) par(lend="butt") NDaysInSecs <- 60*60*24*n RadiusOfWindow <- NDaysInSecs + 60*60*24 a1 <- rev(a) plot(a1, y=rep(0, length(a1)), type = "l", axes = F, ylim=c(-1, 1), xlim = c(RadiusOfWindow, -RadiusOfWindow), xlab="", ylab="") axis(1, at=a, labels=a, pos=0) arrows(x0=a[1]-60*60*24, y0=0, x1=a[2*n+1]+60*60*24, length=.1, code = 2) text(a[2*n+1]+60*60*12, 0, "t", pos = 1) segments(x0=a[1:(2*n)], y0=0, x1=a[2:(2*n+1)], col="blue", lwd =4) for (i in 1:(2*n)) text(x=a[i] + 15*60, y=0, "]", col="blue", font = 2, cex=2) for (i in 2:(2*n+1)) text(x=a[i] - 15*60, y=0, "(", col="blue", font = 2, cex=2) axis(2, pos=0, labels = FALSE, lwd.ticks=0, lty="dotted") text(0, .8, "origin =\n\"1970-01-01 00:00:00\"", pos=1) box("outer") par(op)
Labeling an interval
rotate around origin -- "dual"
"cut"
leap seconds occur at midnight beginning July 1st's UTC as necessary
format(.leap.seconds, format = "%Y-%m-%d %H:%M:%S", tz="UTC",usetz=TRUE)
? strptime
Remember that in most time zones some times do not occur and some occur twice because of transitions to/from ‘daylight saving’ (also known as ‘summer’) time. strptime does not validate such times (it does not assume a specific time zone), but conversion by as.POSIXct will do so. Conversion by strftime and formatting/printing uses OS facilities and may return nonsensical results for non-existent times at DST transitions.
?DateTimeClasses
Unfortunately, the conversion is complicated by the operation of time zones and leap seconds (26 days have been 86401 seconds long so far, the last at the time of writing being added in 2015: the times of the extra seconds are in the object .leap.seconds). The details of this are entrusted to the OS services where possible. It seems that some rare systems used to use leap seconds, but all known current platforms ignore them (as required by POSIX). This is detected and corrected for at build time, so "POSIXct" times used by R do not include leap seconds on any platform.
A few times have specific issues. First, the leap seconds are ignored, and real times such as "2005-12-31 23:59:60" are (probably) treated as the next second. However, they will never be generated by R, and are unlikely to arise as input. Second, on some OSes there is a problem in the POSIX/C99 standard with "1969-12-31 23:59:59 UTC", which is -1 in calendar time and that value is on those OSes also used as an error code. Thus as.POSIXct("1969-12-31 23:59:59", format = "%Y-%m-%d %H:%M:%S", tz = "UTC") may give NA, and hence as.POSIXct("1969-12-31 23:59:59", tz = "UTC") will give "1969-12-31 23:59:00". Other OSes (including the code used by R on Windows) report errors separately and so are able to handle that time as valid.
Fractional seconds are printed only if options("digits.secs") is set: see strftime.
A duration is the "non-negative quantity ['magnitude'] attributed to a time interval, the value of which is equal to the difference between the time points of the final instant and the initial instant of the time interval."^[ISO 8601 2.1.6]
Think of a duration as the length of the vector ("magnitude") representing a time interval. In the figure below, the magnitude of the vector is one -- second, day, month, etc. -- depending on the context.
par(mar=c(1,2,1,2)) plot(2, 0, xlim=c(0,5), ylim=c(-.5, .5), col="green", pch = 20, axes=F, xlab="", ylab="", main="duration") arrows(x0=2, y0=0, x1=3, col="green", lwd =2) box()
Under the International System of Units (SI), the base unit of duration is "seconds". Indeed, whenever a duration is expressed in units other than "seconds" that length of time is referred to as a "nominal duration."^[ISO 8601 2.1.7] Examples of nominal durations are calendar day (its length in seconds can vary depending on leap seconds and daylight/standard time shifts), calendar month (its length in seconds varies, in addition to calendar day variability, due to differing numbers of calendar days in a month), and calendar year (in addition to calendar day variability, its length can vary due to the addition of a leap day). We will see examples of this behavior in R below.
seconds
are the base unit for expressing duration.
As pertains
R,
that means ages need not rely on classes as granular as POSIXt;
the Date
class, which keeps track of calendar days,
should suffice.
When a contract specifies an inception date but no time, e.g., an insurance policy, for the event E corresponding to the financial responsibilities incepting therein, it is customary to consider those responsibilities to start at hour 00. When considering the age of the aggregation of events occurring during a time interval, financial and accounting models will "tag" those events with the same instant of inception. Two general instants can be found, particularly in the actuarial literature:
It would seem that the calculation of an age in units of "days" would be straightforward, but there are a couple of complicating factors. First, ISO 8601 defines a "day" to be the unit of time equal to exactly 24 hours. It defines a "calendar day" to be the interval of time between successive midnights. Those calendar day intervals are usually one day in length, but for two exceptions:
Leap seconds: Every once in a while a second must be added to or subtracted from Coordinated Universal Time (UTC) to realign UTC solar time (UT1).
Daylight time: Frequently the clock is adjusted by local authorities.
r 60*60*24 == 86400
r 86400*30 == 2592000
r as.Date("2015-12-01") - as.Date("2015-11-01") # Time difference of 30 days
r as.POSIXct("2015-12-01") - as.POSIXct("2015-11-01") # Time difference of 30.04167 days
r as.POSIXct("2015-12-01 00:00:00") - as.POSIXct("2015-11-01 00:00:00") # Time difference of 30.04167 days
r as.character(difftime(as.POSIXct("2015-12-01 00:00:00"),
as.POSIXct("2015-11-01 00:00:00"), units = "sec")) # Time difference of 2595600 secs
r 2595600 - 2592000 == 3600
r 3600 == 60*60 # 1 hour
Definition: Accounting Date
An accounting date is the cutoff date for reflecting events and recording amounts as paid or unpaid in a financial statement or accounting system. The accounting date is sometimes referred to as the “as of” date.^[Casualty Actuarial Society Statement of Principles Regarding Property and Casualty Unpaid Claims Estimates]
Although financial statements are always stated as of a date, say, December 31, 2015, it would be more thorough to assign a time as well, so as to identify all transactions impacting the financial statements as of that date. Some say "any particular moment on the 31st" could be used.^["it would be more accurate to write December 31, 20XX, 11:59:59, or any particular moment on the 31st." http://www.investopedia.com/university/accounting/accounting5.asp] However, payments can potentially occur up to and including midnight December 31, 2015, so if a time designator is to be used, midnight would be the most appropriate.
Another reason for the closing instant to be the end of the day is for the purposes of date arithmetic. For example, the instant closing the month of December is 31 days from the beginning of December.
The International Organization for Standardization (ISO) sets the standards for computer representation of dates and times as a string of characters.^[ISO 8601:2004, Data elements and interchange formats -- Information interchange -- Representation of dates and times, (c) ISO 2004] Regarding "midnight", the standards recognize that the instant 24:00:00 (hour 24) marking the end of one calendar day coincides with the instant 00:00:00 (hour 00) marking the start of the next calendar day. Furthermore, "the choice of [hour 24 or hour 00] will depend upon any association with a date, or a time interval. [Hour 24] representations are preferred to represent the end of a time interval."^[ISO 8601 4.2.3. Emphasis added.] The concept of the closing of the books at the end of a calendar year, calendar month or calendar day^[defined as "time intervals" by ISO 8601] suggests that hour 24 is preferred for representing an accounting date.
ISO 8601's representation of the accounting date referred to as "close of the 2015 calendar year" or "as of year end 2015" is therefore "2015-12-31 24:00:00".
On the other hand,
base
R's
implementation of the 8601 standards^[The POSIXt
classes.
In R see ?DateTimeClasses.
For additional background, see https://en.wikipedia.org/wiki/Unix_time]
stores time as the number of seconds since the beginning
of 1970,
so midnight is represented as hour 00 of the beginning of each
day.
Therefore, the representation of "as of year end 2015"
in
R
is "2016-01-01 00:00:00"
which is January 1st when
shortened to just the date.^[ISO 8601 2.1.5 recognizes that a "date" can represent
an instant in time as well as a span of time ("duration").]
However,
to refer to the
accounting date "as of year end 2015" with a label that
uses the month "January"
does not
satisfactorily communicate the
"as of December 31, 2015" accounting date concept.
It would be preferable that
R
and a user be able to communicate that
concept using a label with "December" in it
and also have that label refer to the instant
in time separating calendar years 2015 and 2016
(as.Date("2016-01-01")
in
R).
That is the purpose of the "asof" class in the mondate package.
Definition: Age
The age of event E as of accounting date A is the length of time from the occurrence of event E to hour 24 on accounting date A.
Note that units are not mentioned in the definition of age. This is because the appropriate unit will be specific to the use case. In the vast majority of accounting cases, age is measured in units of days, months or years, not seconds.
It turns out that the definitions of units days, months and years in ISO 8601 is not particularly straightforward, with complexity in proportion to the width of the unit. Due to the fundamental monthly, quarterly, and yearly accounting cycles, it is generally not productive to used data defined more granularly than "month", but even that level of granularity has its complexities.
This paper adds to that complexity with another take on "month": "emonth."
There is little ambiguity in defining elapsed time (durations) in units of days. ISO 8601 defines a R's two Date/Time classes facilitate date/time arithmetic in uits of seconds and days.
so elapsed time in units of seconds is easily combined with a POSIXt object to yield another POSIXt object unambiguously.
It is more complicated with units of months because month periods are comprised of different numbers of days. But this complication can be overcome with two key observations.
It is commonly accepted that the length of time between the beginning and end of a month is one "month".
Given any time t in any given month, there is a unique portion p, 0<=p<=1, that represents the portion of the month completed by time t. Conversely, given any portion p, the point in time of a month completed as of that portion of the month can be easily found.
Those two observations give rise to the definition of the "month-time" of an instant in time:
Definition: Month Time
The month time of time t is a real number measuring the number of months since the beginning of 1970 to time t. The fractional part of the real number represents the portion of t's month to have expired by time t.
R has two classes, POSIXlt and POSIXct
Base R follows that standard and represents an instant of time as the number of seconds that have transpired since the beginning of 1970.
It is well known that "months" are comprised of different numbers of days. Although it is widely accepted that the length of time between the beginning and end of a month is one "month", it is also recognized that month durations cannot be defined consistently in units of days. Those observations give rise to a different type of unit: "elapsed month" or "emonth".
Definition: Elapsed Month ("emonth")
The length of time between two instants in time t1 and t2 in units of "emonths" is
mondate(t2) - mondate(t1) where mondate(t) is a real number representing the number of months between the beginning of 1970 and time t.Example
mondate("1970-02-01") = 1
mondate("1971-01-01") = 12 mondate("1970-02-15 00:00:00") = 1.5 because the beginning of February 15, 1970 is halfway through February 1970. as.Date("1971-01-01") - as.Date("1971-02-01") = 10.5 emonths
Conversely, given any real number t, it is straightforward to find the time ?YYYYMMDD?HH:MM:SS.zzzzz? that is t months away from the beginning of 1970 by first counting whole months, then counting into the next month (if necessary) the number of days and seconds corresponding to that month per the fractional value of t.
Defintion: Elapsed Years
The number of elapsed years between times t1 and t2 equals the number of elapsed months divided by 12.
ABC Ins. Co. started on 1/1/2010 to write earthquake insurance in California.
As claims are made,
ABC defines the occurrence date of a claim claim to be the date of
the earthquake and stores that date in an ISO-8601 compliant object (POSIXt
).
ABC has had good luck so far -- only 20 claims have been made.
Here are their occurrence dates and their know values as of 12/31/2015:
data ?
To complete Sentence B, we need one more definition:
Definition: The age of accident year AY as of AOD is AOD - AY-01-01.
The accident year age of the 20 claims is the vector
mondate(?2015-12-31?) ? year(occurrenceDate)-01-01
http://smallbusiness.chron.com/differences-dates-between-balance-sheet-income-sheet-24881.html
"Balance Sheet Date A balance sheet often states that it is prepared as of a specific date, referred to as the balance sheet date. The balance sheet reports on a company’s financial conditions, namely the values of the company’s assets, liabilities and shareholders’ equity. Values are measured in terms of their monetary amounts at particular points in time rather than over any periods. At the end of an accounting cycle, with the accounting books closed to recording new business transactions, companies can summarize their financial conditions as of the cycle's end."
http://www.casact.org/professionalism/standards/princip/SOP-Regarding-Property-and-Casualty-Unpaid-Claims-Estimates_Final%204-22-2015.pdf
Two time standards in common use today are Universal Time ("UT1") and Coordinated Universal Time ("UTC").
UT1 is a time standard based on the rotation of the earth. It starts with mean solar time at zero degrees longitude (a.k.a., the Prime Meridian), which is the longitude on which is located the Royal Greenwich Observatory. Mean solar time, in turn, starts with "apparent" solar time, which defines a "solar day" as the time period between two "noons", where a "noon" is the moment when the sun reaches its zenith during the day. Apparent solar time is the time one would see on a sundial. It turns out that a solar day is not a constant 86,400=60x60x24 seconds in length but changes each day due to the eliptical orbit of the earth. ^[https://en.wikipedia.org/wiki/Time_standard https://en.wikipedia.org/wiki/Universal_Time#Versions] The average length of a solar day over the course of a year is called a "mean solar day." "Currently a mean solar day is about 86,400.002 SI seconds.[2]"
I asked David Madore about his CLOCK_UTC and friends website:
http://www.madore.org/~david/computers/unix-leap-seconds.html.
He answered my email on 2015-12-14 and included some references:
http://www.cl.cam.ac.uk/~mgk25/iso-time.html
This second reference at the end has a good summary of how the acronyms UTC, TAI, and ISO do not match the order of the words in English or French:
https://groups.google.com/forum/#!msg/comp.std.unix/GaIQpDHUl1U/nnlJgCfZZb8J
Here is a pretty good summary:
https://www.eecis.udel.edu/~ntp/ntpfaq/NTP-s-time.htm#Q-UTC
http://tycho.usno.navy.mil/leapsec.html
https://igscb.jpl.nasa.gov/mail/igsmail/1997/msg00096.html
Dennis McCarthy
Director of Time, U.S. Naval Observatory
https://en.wikipedia.org/wiki/Universal_Time#Versions
The rotation of the Earth is somewhat irregular, and is very gradually slowing due to tidal acceleration.
http://maia.usno.navy.mil/
The United States' contribution to the international standards is handled by the U.S. Naval Observatory:
"The IERS Rapid Service/Prediction Center is the product center of the International Earth Rotation and Reference Systems Service responsible for providing Earth orientation parameters (EOPs) on a rapid turnaround basis. This service is primarily intended for real-time users and others needing the highest quality EOP information sooner than is available in the IERS final series (Bulletin B) published by the IERS Earth Orientation Center, which is based at the Observatoire de Paris."
"This Center is an activity of the Earth Orientation (EO) Department at the U.S. Naval Observatory (USNO). The mission of the USNO includes determining the positions and motions of celestial bodies, measuring the Earth's rotation and orientation, maintaining the master clock for the U.S., and disseminating precise time (atomic and astronomical). The EO Dept. contributes to this mission by collecting suitable observations and performing data analyses to determine and predict the time-varying orientation of the terrestrial reference frame within the quasi-inertial celestial reference frame. The key parameters determined and disseminated are polar motion coordinates, Universal Time (UT1), precession, and nutation. The user community is very broadly based, the main applications involving principally high-accuracy navigation and positioning, particularly in real-time and near real-time modes."
"Contact Information: 202-762-1518 (primary); 202-550-6407 (alternate); 202-762-1444 (alternate)"
DMM: It would appear that the USNO uses JPL software. Here is a link to that software: http://ssd.jpl.nasa.gov/?planet_eph_export. Here is a website that suggests JPL is in charge of ephemeral time rather than the USNO: https://en.wikipedia.org/wiki/Newcomb%27s_Tables_of_the_Sun
Here is a USNO site that defines leap seconds: http://tycho.usno.navy.mil/leapsec.html
That site also defines
ephemeris second
"the fraction 1/31,556,925.9747 of the tropical year for 1900 January 0
at 12 hours ephemeris time."
Note that there are r prettyNum(60*60*24*365, big.mark = ",")
"seconds"
in a 365-day year, where a "day" equals 24 hours,
an "hour" equals 60 minutes, and a "minute" equals 60 seconds.
There are r prettyNum(60*60*24*366, big.mark = ",")
"seconds"
in a 366-day year (leap year).
If a leap year comes around every four years,
then there are about
prettyNum(60*60*24*365*.75 + 60*60*24*366*.25, big.mark = ",")
This definition of the ephemeris second was ratified by the Eleventh General Conference on Weights and Measures in 1960. Thus, Ephemeris Time (ET) is defined as "the measure of time that brings the observed positions of the celestial bodies into accord with the Newtonian dynamical theory of motion."^[http://tycho.usno.navy.mil/leapsec.html]
"Following several years of work, two astronomers at the U.S. Naval Observatory (USNO) and two astronomers at the National Physical Laboratory (Teddington, England) determined the relationship between the frequency of the cesium atom (the standard of time) and the ephemeris second. They determined the orbital motion of the Moon about the Earth, from which the apparent motion of the Sun could be inferred, in terms of time as measured by an atomic clock. As a result, in 1967 the Thirteenth General Conference on Weights and Measures defined the second of atomic time in the International System of Units (SI) as
the duration of 9,192,631,770 periods of the radiation corresponding to the transition between the two hyperfine levels of the ground state of the cesium 133 atom.
The ground state is defined at zero magnetic field. The second thus defined is equivalent to the ephemeris second."
http://maia.usno.navy.mil/ser7/ser7.dat
26 November 2015 Vol. XXVIII No. 048
Sample from the UT1-UTC Table
MJD x(arcsec) y(arcsec) UT1-UTC(sec) 2015 11 27 57353 0.1178 0.2540 0.13841 2015 11 28 57354 0.1163 0.2541 0.13711 2015 11 29 57355 0.1146 0.2542 0.13582 2015 11 30 57356 0.1129 0.2543 0.13449 2015 12 1 57357 0.1110 0.2542 0.13312 2015 12 2 57358 0.1092 0.2540 0.13171 2015 12 3 57359 0.1074 0.2538 0.13026
https://msdn.microsoft.com/en-us/library/ms973825.aspx
Performing date and time calculations on values that represent machine local time may not always yield the correct result. When performing calculations on time values in time-zone contexts that practice daylight savings time, you should convert values to universal time representations before performing date arithmetic calculations.
There are several advantages to performing calculations using UCT time. Chief among them is the fact that when represented in universal time, every day has a fixed length, and there are no time-zone offsets to deal with.
The recommended format strings for converting DateTime to strings are: 'yyyy'-'MM'-'dd'T'HH': 'mm': 'ss.fffffff'Z' —For UCT values 'yyyy'-'MM'-'dd'T'HH': 'mm': 'ss.fffffff'zzz' —For local values 'yyyy'-'MM'-'dd'T'HH': 'mm': 'ss.fffffff' —For abstract time values
http://www.diffen.com/difference/GMT_vs_UTC
Greenwich Mean Time (GMT) is a term originally referring to mean solar time at the Royal Observatory, Greenwich where a system was first developed around 1850 for tracking time based on the rotation of the Earth. It is now often used to refer to Coordinated Universal Time (UTC) when this is viewed as a time zone.
Strictly speaking, UTC is not a time zone but an atomic time scale which only approximates GMT in the old sense. It is also used to refer to Universal Time (UT), which is an astronomical concept that directly replaced the original GMT.
In 1970 the Coordinated Universal Time system was devised by an international advisory group of technical experts within the International Telecommunication Union (ITU). UTC is the International Atomic Time (TAI, from the French Temps atomique international) with leap seconds added at irregular intervals to compensate for the Earth's slowing rotation. Leap seconds are used to allow UTC to closely track UT1, which is the mean solar time at the Royal Observatory, Greenwich.
The ITU felt it was best to designate a single abbreviation for use in all languages in order to minimize confusion. Since unanimous agreement could not be achieved on using either the English word order, CUT (coordinated universal time), or the French word order, TUC (temps universel coordonné), the acronym UTC was chosen as a compromise.
The difference between UTC and UT1 cannot exceed 0.9 s, so if high precision is not required, the general term Universal Time (without a suffix) may be used.
In casual use, Greenwich Mean Time (GMT) is the same as UTC and UT1. Owing to the ambiguity of whether UTC or UT1 is meant, and because timekeeping laws usually refer to UTC, GMT is avoided in careful writing.
http://www.diffen.com/difference/GMT_vs_UTC
Video says "UTC ... is an offset of the prime meridian"
GMT UTC
Stands for Greenwich Mean Time Coordinated Universal Time (Abbreviated From The French Name) Refers To A Time Zone A System Of Time-Keeping Usage By Human Readable Clocks By Digitally Synchronized Clocks Measured Using Rotation Of Earth (Historically) Atomic Transition Principle (Periodic updates with astronomical time)
http://stackoverflow.com/questions/14986043/is-gmt-same-as-utc
I am running a world targeted website where people from all over the world visit. The database contains time in International Date Line West format. I am taking the user time zone using JavaScript and converting the time in the database to user's time and then showing on the page. I want to ask that is International Date Line West is correct format for world level website? Or setting to UTC or GMT will be better? And what is the difference between UTC and GMT and International Date Line West? Are these three same? Finally what time should I set onto my server that will be converted using offset of timezone of user?
If you're interested in astronomical observations, for example of satellites such as GPS, or if you want to cite a technical standard (ITU-R TF.460-6), then you might care that we use UTC and that GMT no longer has a precise definition. Otherwise you probably consider GMT to be the same thing as UTC, and also consider UT and UT1 to be the same as UTC--which technically they are not.
Also, if you're tracking computer criminals or other distributed activity, then you need to determine whether certain events at various sites may or may not have occurred before certain other events. For that purpose you will want to learn and use Network Time Protocol (NTP). That will have a much bigger effect on your understanding of time than the little differences between UTC, UT1, and UT.
"International Date Line West" is just a friendly name for a timezone where the time is defined as twelve hours less than UTC (that is, UTC-12).
https://en.wikipedia.org/wiki/Atomic_clock
An atomic clock is a clock device that uses an electronic transition frequency in the microwave, optical, or ultraviolet region[2] of the electromagnetic spectrum of atoms as a frequency standard for its timekeeping element. Atomic clocks are the most accurate time and frequency standards known, and are used as primary standards for international time distribution services, to control the wave frequency of television broadcasts, and in global navigation satellite systems such as GPS.
National standards agencies in many countries maintain a network of atomic clocks which are intercompared and kept synchronized to an accuracy of 10^(-9) seconds per day (approximately 1 part in 1014). These clocks collectively define a continuous and stable time scale, International Atomic Time (TAI). For civil time, another time scale is disseminated, Coordinated Universal Time (UTC). UTC is derived from TAI, but approximately synchronised, by using leap seconds, to UT1, which is based on actual rotation of the Earth with respect to the solar time.
https://en.wikipedia.org/wiki/Solar_time
The effect of this is that a clock running at a constant rate – e.g. completing the same number of pendulum swings in each hour – cannot follow the actual Sun; instead it follows an imaginary "mean Sun" that moves along the celestial equator at a constant rate that matches the real Sun's average rate over the year.[1] This is "mean solar time", which is still not perfectly constant from one century to the next but is close enough for most purposes. Currently a mean solar day is about 86,400.002 SI seconds.[2]
https://en.wikipedia.org/wiki/Earth's_rotation
The Earth rotates once in about 24 hours with respect to the sun and once every 23 hours, 56 minutes and 4 seconds with respect to the stars (see below). Earth's rotation is slowing slightly with time; thus, a day was shorter in the past. This is due to the tidal effects the Moon has on Earth's rotation. Atomic clocks show that a modern-day is longer by about 1.7 milliseconds than a century ago,[1] slowly increasing the rate at which UTC is adjusted by leap seconds.
http://www.timeanddate.com/time/gmt-utc-time.html
Greenwich Mean Time (GMT) is often interchanged or confused with Coordinated Universal Time (UTC). But GMT is a time zone and UTC is a time standard.
Although GMT and UTC share the same current time in practice, there is a basic difference between the two:
GMT is a time zone officially used in some European and African countries. The time can be displayed using both the 24-hour format (0 - 24) or the 12-hour format (1 - 12 am/pm). UTC is not a time zone, but a time standard that is the basis for civil time and time zones worldwide. This means that no country or territory officially uses UTC as a local time.
Universal time
https://en.wikipedia.org/wiki/Universal_Time#Versions
Universal Time (UT) is a time standard based on Earth's rotation. It is a modern continuation of Greenwich Mean Time (GMT), i.e., the mean solar time on the Prime Meridian at Greenwich. In fact, the expression "Universal Time" is ambiguous (when accuracy of better than a few seconds is required), as there are several versions of it, the most commonly used being Coordinated Universal Time (UTC) and UT1 (see below).[1] All of these versions of UT, except for UTC, are based on Earth's rotation relative to distant celestial objects (stars and quasars), but with a scaling factor and other adjustments to make them closer to solar time. UTC is based on International Atomic Time, with leap seconds added to keep it within 0.9 second of UT1.
Versions There are several versions of Universal Time:
UT0 is Universal Time determined at an observatory by observing the diurnal motion of stars or extragalactic radio sources, and also from ranging observations of the Moon and artificial Earth satellites. The location of the observatory is considered to have fixed coordinates in a terrestrial reference frame (such as the International Terrestrial Reference Frame) but the position of the rotational axis of the Earth wanders over the surface of the Earth; this is known as polar motion. UT0 does not contain any correction for polar motion. The difference between UT0 and UT1 is on the order of a few tens of milliseconds. The designation UT0 is no longer in common use.[11] UT1 is the principal form of Universal Time. While conceptually it is mean solar time at 0° longitude, precise measurements of the Sun are difficult. Hence, it is computed from observations of distant quasars using long baseline interferometry, laser ranging of the Moon and artificial satellites, as well as the determination of GPS satellite orbits. UT1 is the same everywhere on Earth, and is proportional to the rotation angle of the Earth with respect to distant quasars, specifically, the International Celestial Reference Frame (ICRF), neglecting some small adjustments. The observations allow the determination of a measure of the Earth's angle with respect to the ICRF, called the Earth Rotation Angle (ERA, which serves as a modern replacement for Greenwich Mean Sidereal Time). UT1 is required to follow the relationship ERA = 2pi(0.7790572732640 + 1.00273781191135448Tu) radians where Tu = (Julian UT1 date - 2451545.0)[12]
UTC (Coordinated Universal Time) is an atomic timescale that approximates UT1. It is the international standard on which civil time is based. It ticks SI seconds, in step with TAI. It usually has 86,400 SI seconds per day but is kept within 0.9 seconds of UT1 by the introduction of occasional intercalary leap seconds. As of 2015, these leaps have always been positive (the days which contained a leap second were 86,401 seconds long). Whenever a level of accuracy better than one second is not required, UTC can be used as an approximation of UT1. The difference between UT1 and UTC is known as DUT1.[15]
https://commons.wikimedia.org/wiki/File:World_Time_Zones_Map.png
By TimeZonesBoy (US Central Intelligence Agency) [Public domain], via Wikimedia Commons (Attribution not legally required)
David Smith's blog "Converting time zones in R: tips, tricks and pitfalls," Revolutions, June 02, 2009 http://blog.revolutionanalytics.com/2009/06/converting-time-zones.html
Lubridate
Grolemund, Garrett and Hadley Wickham,
"Dates and Times Made Easy with lubridate",
Journal of Statistical Software,
April 2011, Volume 40, Issue 3.
Today is r format(Sys.Date(), format = "%B %d, %Y")
Ripley, Brian D. and Kurt Hornik, "Date-Time Classes", R News, Vol. 1/2, June 2001. [https://www.r-project.org/doc/Rnews/Rnews_2001-2.pdf]
POSIX.1
http://www.opengroup.org/austin/papers/backgrounder.html
http://www.opengroup.org/austin/papers/posix_faq.html
From ?strptime References
The POSIX 1003.1 standard, which is in some respects stricter than ISO 8601.
See LC_TIME in Base Definitions: Detailed ToC
file:///Users/danielmurphy/Downloads/susv4tc1/basedefs/toc.html
See folder susv4tc1 in mondate vignettes folder
file:///Users/danielmurphy/Downloads/susv4tc1/basedefs/V1_chap07.html#tag_07_03_05
Here's a pretty good paper about dates, Lubridate, Chron: http://biostat.mc.vanderbilt.edu/wiki/pub/Main/ColeBeck/datestimes.pdf
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.