This vignette follows one value, a meeting in New York, through what zutempo does with it: building it, moving it in time, rounding it, and handing it to base R.
A meeting in New York
A zoned_date_time() is an exact moment, the wall-clock
time in a time zone, and the zone itself. It reads RFC 9557 strings,
with the zone in brackets:
meeting <- zoned_date_time("2026-03-07T09:30[America/New_York]")
meeting
#> <zutempo_zoned_date_time[1]>
#> [1] 2026-03-07T09:30:00-05:00[America/New_York]
offset(meeting)
#> [1] "-05:00"
hours_in_day(meeting)
#> [1] 24The same moment can be built from fields and a zone:
zoned_date_time(2026, 3, 7, 9, 30, time_zone = "America/New_York")
#> <zutempo_zoned_date_time[1]>
#> [1] 2026-03-07T09:30:00-05:00[America/New_York]Moving it
New York’s clocks go forward at 02:00 on Sunday 8 March. A day later and 24 hours later are different moments:
temporal_add(meeting, "P1D")
#> <zutempo_zoned_date_time[1]>
#> [1] 2026-03-08T09:30:00-04:00[America/New_York]
temporal_add(meeting, "PT24H")
#> <zutempo_zoned_date_time[1]>
#> [1] 2026-03-08T10:30:00-04:00[America/New_York]
hours_in_day(temporal_add(meeting, "P1D"))
#> [1] 23A wall-clock time can also fall in that gap.
disambiguation says which moment it means:
skipped <- plain_date_time("2026-03-08T02:30")
temporal_to_zoned_date_time(skipped, "America/New_York")
#> <zutempo_zoned_date_time[1]>
#> [1] 2026-03-08T03:30:00-04:00[America/New_York]
temporal_to_zoned_date_time(skipped, "America/New_York", disambiguation = "earlier")
#> <zutempo_zoned_date_time[1]>
#> [1] 2026-03-08T01:30:00-05:00[America/New_York]
try(temporal_to_zoned_date_time(skipped, "America/New_York", disambiguation = "reject"))
#> Error : the local time does not exist in this time zone (a clock gap) (element 1)The time between two zoned values counts in hours by default, since days need not be 24 hours long. Ask for days and they follow the calendar:
follow_up <- zoned_date_time("2026-03-09T09:30[America/New_York]")
temporal_until(meeting, follow_up)
#> <zutempo_duration[1]>
#> [1] PT47H
temporal_until(meeting, follow_up, largest_unit = "day")
#> <zutempo_duration[1]>
#> [1] P2DRounding it
late <- zoned_date_time("2026-03-07T09:47:31.25[America/New_York]")
temporal_round(late, "minute")
#> <zutempo_zoned_date_time[1]>
#> [1] 2026-03-07T09:48:00-05:00[America/New_York]
temporal_round(late, "minute", rounding_increment = 15, rounding_mode = "floor")
#> <zutempo_zoned_date_time[1]>
#> [1] 2026-03-07T09:45:00-05:00[America/New_York]
temporal_to_string(late, smallest_unit = "second")
#> [1] "2026-03-07T09:47:31-05:00[America/New_York]"Durations round too, relative to a moment when they hold days in a zone:
temporal_round(duration(hours = 47), largest_unit = "day", relative_to = meeting)
#> <zutempo_duration[1]>
#> [1] P2DThe same moment elsewhere
tokyo <- temporal_with_time_zone(meeting, "Asia/Tokyo")
tokyo
#> <zutempo_zoned_date_time[1]>
#> [1] 2026-03-07T23:30:00+09:00[Asia/Tokyo]temporal_equals() compares the zone as well as the
moment, so the two are not equal; their instants are:
temporal_equals(meeting, tokyo)
#> [1] FALSE
temporal_equals(temporal_to_instant(meeting), temporal_to_instant(tokyo))
#> [1] TRUE
zoned_date_time_compare(meeting, tokyo)
#> [1] 0Handing it to base R
as.POSIXct(meeting)
#> [1] "2026-03-07 09:30:00 EST"
as.POSIXlt(meeting)
#> [1] "2026-03-07 09:30:00 EST"
as.Date(meeting)
#> [1] "2026-03-07"And back, from a POSIXct with its
tzone:
zoned_date_time(as.POSIXct("2026-03-07 09:30:00", tz = "America/New_York"))
#> <zutempo_zoned_date_time[1]>
#> [1] 2026-03-07T09:30:00-05:00[America/New_York]A POSIXct is a double, precise to about a quarter of a
microsecond at today’s dates, where zutempo keeps nanoseconds. See
?base-r for what each conversion keeps and loses, and
?zutempo_options for the options used above.