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.
start <- lubridate::ymd_hms("2020-01-01 10:00:00", tz = "America/New_York")
start + lubridate::duration(1, units = "hour")
#> [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.
start <- lubridate::ymd_hms("2016-03-13 01:00:00", tz = "America/New_York")
start + lubridate::duration(1, units = "hour")
#> [1] "2016-03-13 03:00:00 EDT"
start + lubridate::period(1, units = "hour")
#> [1] NAYou 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:
start <- lubridate::ymd_hms("2016-03-13 01:00:00", tz = "America/New_York")
start + lubridate::duration(1, units = "day")
#> [1] "2016-03-14 02:00:00 EDT"
start + lubridate::period(1, units = "day")
#> [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).
hms::parse_hm("10:00") + lubridate::period(1, units = "hours")
#> 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.