This article explains why the mctq
package uses
Duration
instead of Period
(objects from the
lubridate package) as the
default object for time spans.
Duration
versus Period
objectsThe lubridate
package offers three types of objects for storing and manipulating time
spans: Duration
,
Period
,
and Interval
.
To understand the difference between Duration
and
Period
objects you must first remember that the timeline is
not always consistent, as it can have irregularities caused by, for
example, leap years, DST (Daylight Saving Time), or leap seconds. That’s
when Period
objects differ from Duration
objects.
Duration
objects represent time spans by their exact number of seconds. That is,
a Duration
object of 1 hour will always represent a 1-hour
time span, even with possible timeline irregularities.
<- lubridate::ymd_hms("2020-01-01 10:00:00", tz = "America/New_York")
start
+ lubridate::duration(1, units = "hour")
start #> [1] "2020-01-01 11:00:00 EST"
Period
objects work a little bit differently. They are a special type of object
developed by the lubridate
team that represents “human
units”, ignoring possible timeline irregularities. That is to say that 1
day as Period
can have different time spans when looking to
a timeline after an irregular event.
To illustrate this behavior, take the case of a DST event, starting at 2016-03-13 01:00:00 EST.
<- lubridate::ymd_hms("2016-03-13 01:00:00", tz = "America/New_York")
start
+ lubridate::duration(1, units = "hour")
start #> [1] "2016-03-13 03:00:00 EDT"
+ lubridate::period(1, units = "hour")
start #> [1] NA
You might ask: why the result is NA
when adding 1 hour
as a Period
object? That’s because Period
objects ignore time irregularities. When the DST starts at
01:00:00
the timeline “jumps” to 03:00:00
, so
the period from 02:00:00
to 02:59:59
doesn’t
exist.
base: 2016-03-13 01:00:00, tz = "America/New_York"
DST + 1 hour
-----|---------------| |---------------|----->
01:00 NA 03:00 04:00
From the `Duration` perspective: base + 1 hour = 2016-03-13 03:00:00
|-------------------------------|---------------|
1 hour 1 hour
From the `Period` perspective: base + 1 hour = NA
|---------------|---------------|---------------|
1 hour 1 hour 1 hour
Period
objects are useful when you need to consider the
human units of time. For example:
<- lubridate::ymd_hms("2016-03-13 01:00:00", tz = "America/New_York")
start
+ lubridate::duration(1, units = "day")
start #> [1] "2016-03-14 02:00:00 EDT"
+ lubridate::period(1, units = "day")
start #> [1] "2016-03-14 01:00:00 EDT"
In this case, 1 day
, by human standards, represents the
same time of day
of the next day. But, considering the DST
event, that 1 day
has a time span of 23 hours.
You can learn more about lubridate
time
span objects in the Dates and
times chapter from Wickham & Grolemund’s book “R for Data
Science”.
At first glance you might think that, since MCTQ was made for human respondents, the best representation for time spans would be the one that better represents “human units”, right? That would be fine if we were talking about a time span in a timeline irregularity context, but MCTQ doesn’t deal with this scenario.
When using MCTQ, the interest is to measure the exact time span
between one local time to another. By ignoring irregularities in the
timeline, Periods
produce a fluctuating time span, hence
Period
objects are not compatible with other time spans
like objects (e.g., hms
).
::parse_hm("10:00") + lubridate::period(1, units = "hours")
hms
#> Error: Incompatible classes: <hms> + <Period>
In summary, Period
objects were made considering a very
specific context that doesn’t apply to MCTQ. That’s why
Duration
objects are the default object for time spans.