| 64578 |
ripley |
1 |
### Tests of often platform-dependent features of the POSIX[cl]t implementation.
|
|
|
2 |
|
| 90032 |
ripley |
3 |
### Expect differences, historically with 32-bit time_t and platforms
|
| 83236 |
ripley |
4 |
### without tm_zone/tm_gmtoff.
|
| 90139 |
smeyer |
5 |
### Also with musl (wrongly using current not historic "zone" abbreviations).
|
| 90032 |
ripley |
6 |
### Please use the R-internal version for .Rout.save.
|
| 90139 |
smeyer |
7 |
## IGNORE_RDIFF_BEGIN
|
|
|
8 |
(tzCtype <- sessionInfo()[["tzcode_type"]])
|
|
|
9 |
## IGNORE_RDIFF_END
|
| 64578 |
ripley |
10 |
|
|
|
11 |
z <- ISOdate(1890:1912, 1, 10, tz="UTC")
|
|
|
12 |
## Rome changed to CET for 1894
|
|
|
13 |
as.POSIXlt(z, tz="Europe/Rome")
|
|
|
14 |
## Paris changed to PMT for 1892, WET for 1912
|
|
|
15 |
(zz <- as.POSIXlt(z, tz="Europe/Paris"))
|
|
|
16 |
strftime(zz, "%Y-%m-%d %H:%M:%S %Z")
|
| 83227 |
ripley |
17 |
## The offset was really +00:09:21 until 1911, then +00:00
|
| 64578 |
ripley |
18 |
## Many platforms will give the current offset, +0100
|
|
|
19 |
strftime(zz, "%Y-%m-%d %H:%M:%S %z")
|
|
|
20 |
|
|
|
21 |
## Some platforms give details of the latest conversion.
|
|
|
22 |
z <- ISOdate(c(seq(1890, 1940, 5), 1941:1946, 1950), 1, 10, tz="UTC")
|
|
|
23 |
as.POSIXlt(z, tz="Europe/Paris")
|
|
|
24 |
for(i in seq_along(z)) print(as.POSIXlt(z[i], tz="Europe/Paris"))
|
| 83236 |
ripley |
25 |
## use pf %z needs tm_gmtoff
|
| 64578 |
ripley |
26 |
for(i in seq_along(z))
|
|
|
27 |
print(strftime(as.POSIXlt(z[i], tz="Europe/Paris"), "%Y-%m-%d %H:%M:%S %z"))
|
|
|
28 |
|
|
|
29 |
strptime("1920-12-27 08:18:23", "%Y-%m-%d %H:%M:%S", tz="Europe/Paris")
|
| 64585 |
ripley |
30 |
|
|
|
31 |
## check %V etc
|
|
|
32 |
|
|
|
33 |
d <- expand.grid(day = 1:7, year = 2000:2010)
|
|
|
34 |
z1 <- with(d, ISOdate(year, 1, day))
|
|
|
35 |
d <- expand.grid(day = 25:31, year = 2000:2010)
|
|
|
36 |
z2 <- with(d, ISOdate(year, 12, day))
|
|
|
37 |
z <- sort(c(z1, z2))
|
| 79324 |
kalibera |
38 |
strftime(z, "%G %g %W %U %u %V %W %w", tz="Europe/Paris")
|
| 64596 |
ripley |
39 |
|
|
|
40 |
## tests of earlier years. Default format is OS-dependent, so don't test it.
|
| 64625 |
ripley |
41 |
## ISOdate only accepts positive years.
|
| 64596 |
ripley |
42 |
z <- as.Date(ISOdate(c(0, 8, 9, 10, 11, 20, 110, 1010), 1, 10)) - 3630
|
| 83143 |
ripley |
43 |
strftime(z, "%04Y-%m-%d") # with leading zero(s), where supported
|
|
|
44 |
strftime(z, "%_4Y-%m-%d") # with leading space(s), where supported
|
| 64625 |
ripley |
45 |
strftime(z, "%0Y-%m-%d") # without
|
| 64607 |
ripley |
46 |
|
|
|
47 |
|
|
|
48 |
## more test of strftime
|
|
|
49 |
x <- ISOdate(2014, 3, 10, c(7, 13))
|
|
|
50 |
fmts <- c("%Y-%m-%d %H:%M:%S", "%F", "%A %a %b %h %e %I %j",
|
|
|
51 |
## locale-dependent ones
|
|
|
52 |
"%X", # but the same in all English locales
|
|
|
53 |
"%c", "%x", "%p", "%r")
|
|
|
54 |
for (f in fmts) print(format(x, f))
|
| 83087 |
ripley |
55 |
|
|
|
56 |
## Moved from reg-tests-1d.R
|
|
|
57 |
## as.POSIXlt(<very large Date>) gave integer overflow
|
|
|
58 |
## and needed C-level change for 32-bit time_t.
|
|
|
59 |
.Machine$sizeof.time_t
|
|
|
60 |
(z <- .Date(2^31 + 10))
|
|
|
61 |
as.POSIXlt(z)$year == 5879680L
|
|
|
62 |
## year was negative in R <= 4.2.1, even for 64-bit time_t
|
| 83197 |
ripley |
63 |
|
|
|
64 |
|
|
|
65 |
## ------------- Tests of far-distant dates -----------
|
|
|
66 |
Sys.setenv(TZ = "Europe/London")
|
| 88200 |
smeyer |
67 |
## the pre-1902 POSIXct values will be 75s out on platforms that do not
|
| 83197 |
ripley |
68 |
## know about UK changes prior to 1902 (in fact in 1847-12-01: see below).
|
|
|
69 |
as.POSIXct("4000-07-01")
|
|
|
70 |
as.Date("4000-07-01")
|
|
|
71 |
zz <- z <- as.POSIXlt("2000-07-01")
|
|
|
72 |
unclass(z)
|
|
|
73 |
|
|
|
74 |
years <- c(-1e6, -1e5, -1e4, seq(-1000, 4000, by = 100), 1e4, 1e5, 1e6)
|
|
|
75 |
y <- character(length(years))
|
|
|
76 |
for(i in seq_along(years)) {
|
|
|
77 |
zz$year = years[i] - 1900
|
|
|
78 |
y[i] <- strftime(zz)
|
|
|
79 |
}
|
| 84058 |
maechler |
80 |
## IGNORE_RDIFF_BEGIN
|
| 83197 |
ripley |
81 |
y
|
| 84058 |
maechler |
82 |
## IGNORE_RDIFF_END
|
| 83197 |
ripley |
83 |
|
|
|
84 |
y <- double(length(years))
|
|
|
85 |
for(i in seq_along(years)) {
|
|
|
86 |
zz$year = years[i] - 1900
|
|
|
87 |
zz$isdst <- -1 # some are DST, some not so let the code decide
|
|
|
88 |
y[i] <- as.POSIXct(zz)
|
|
|
89 |
}
|
|
|
90 |
print(y, digits=14)
|
|
|
91 |
y <- .POSIXct(y)
|
| 84058 |
maechler |
92 |
## IGNORE_RDIFF_BEGIN
|
| 83197 |
ripley |
93 |
(y1 <- strftime(y)) # leading zeros or spaces is platform-dependant
|
| 84058 |
maechler |
94 |
## IGNORE_RDIFF_END
|
| 83197 |
ripley |
95 |
y2 <- strftime(y, "%_4Y-%m-%d") # not all platforms interpret this
|
|
|
96 |
if(y2[1] != "4Y-07-01") print(y2) else message('format "%_4Y" unsupported')
|
|
|
97 |
|
|
|
98 |
y <- double(length(years))
|
|
|
99 |
for(i in seq_along(years)) {
|
|
|
100 |
zz$year = years[i] - 1900
|
|
|
101 |
zz$isdst <- -1
|
|
|
102 |
y[i] <- as.Date(zz)
|
|
|
103 |
}
|
|
|
104 |
y
|
|
|
105 |
class(y) <- "Date"
|
| 84058 |
maechler |
106 |
## IGNORE_RDIFF_BEGIN
|
| 83197 |
ripley |
107 |
(y3 <- strftime(y))
|
| 84058 |
maechler |
108 |
## IGNORE_RDIFF_END
|
| 83197 |
ripley |
109 |
y4 <- strftime(y, "%_4Y-%m-%d")
|
|
|
110 |
stopifnot(identical(y3, y1))
|
|
|
111 |
|
|
|
112 |
zz <- as.POSIXlt("1900-07-01")
|
|
|
113 |
years <- c(1800, 1847:1848, 1899:1902)
|
|
|
114 |
y <- double(length(years))
|
|
|
115 |
for(i in seq_along(years)) {
|
|
|
116 |
zz$year = years[i] - 1900
|
|
|
117 |
zz$isdst <- -1 # some are DST, some not so let the code decide
|
|
|
118 |
y[i] <- as.POSIXct(zz)
|
|
|
119 |
}
|
|
|
120 |
print(y, digits=14)
|
|
|
121 |
.POSIXct(y)
|
|
|
122 |
|
|
|
123 |
## change of 75s in 1847
|
|
|
124 |
seq(as.POSIXlt("1847-11-24"), as.POSIXlt("1847-12-07"), by ="day")
|
|
|
125 |
|
|
|
126 |
## end of ------------- Tests of far-distant dates -----------
|
|
|
127 |
|
| 83227 |
ripley |
128 |
## Tests of %z and %Z for output.
|
| 83236 |
ripley |
129 |
## Use pf %z needs tm_gmtoff so offsets will otherwise be +0000
|
| 83227 |
ripley |
130 |
x1 <- strptime("2022-07-01", "%Y-%m-%d", tz = "UTC")
|
|
|
131 |
x2 <- strptime("2022-07-01", "%Y-%m-%d", tz = "Europe/Rome")
|
|
|
132 |
x1
|
|
|
133 |
x2
|
|
|
134 |
# RFC5322 format
|
|
|
135 |
format(x1, "%a, %d %b %Y %H:%M:%S %z")
|
| 83247 |
ripley |
136 |
# offset may not not determined: +0200 is correct
|
| 83227 |
ripley |
137 |
format(x2, "%a, %d %b %Y %H:%M:%S %z")
|
|
|
138 |
format(as.POSIXct(x2), "%a, %d %b %Y %H:%M:%S %z") # usually correct
|
|
|
139 |
format(x1, "%a, %d %b %Y %H:%M:%S %Z")
|
|
|
140 |
format(x2, "%a, %d %b %Y %H:%M:%S %Z")
|
|
|
141 |
|
| 83297 |
ripley |
142 |
## offsets not in whole hours:
|
| 83227 |
ripley |
143 |
x3 <- strptime("2022-01-01", "%Y-%m-%d", tz = "Australia/Adelaide")
|
|
|
144 |
format(as.POSIXct(x3), "%a, %d %b %Y %H:%M:%S %z") # +10h30m
|
| 90139 |
smeyer |
145 |
# Liberia does/did not have DST and, before 1972-01-07, used MMT (-44m30s)
|
| 83227 |
ripley |
146 |
x4 <- strptime("1971-01-01", "%Y-%m-%d", tz = "Africa/Monrovia")
|
| 83297 |
ripley |
147 |
y4 <- as.POSIXct(x4)
|
| 90139 |
smeyer |
148 |
lt4 <- unclass(as.POSIXlt(y4))
|
| 90134 |
maechler |
149 |
## IGNORE_RDIFF_BEGIN
|
| 90139 |
smeyer |
150 |
attr(lt4, "tzone")
|
|
|
151 |
## glibc prints an abbreviation for DST. internal and musl leave it blank.
|
| 90134 |
maechler |
152 |
## IGNORE_RDIFF_END
|
| 90139 |
smeyer |
153 |
stopifnot(identical(
|
|
|
154 |
attr(lt4, "tzone") |> trimws(), # ignore " " (internal) vs. "" (musl)
|
|
|
155 |
c("Africa/Monrovia", "GMT", if(grepl("glibc", tzCtype)) "GMT" else "")
|
|
|
156 |
))
|
|
|
157 |
str(`attr<-`(lt4, "tzone", NULL))
|
|
|
158 |
## musl wrongly gives zone="GMT" (the current, not that at the time).
|
|
|
159 |
## macOS' strftime printed gmtoff wrong as -44m.
|
|
|
160 |
format(y4, "%a, %d %b %Y %H:%M:%S %z")
|
| 90134 |
maechler |
161 |
|
| 83227 |
ripley |
162 |
## timezones in 1900 might not be supported
|
|
|
163 |
x5 <- strptime("1900-03-01", "%Y-%m-%d", tz = "Europe/Paris")
|
| 83297 |
ripley |
164 |
y5 <- as.POSIXct(x5)
|
|
|
165 |
str(unclass(as.POSIXlt(y5))) # ditto
|
|
|
166 |
format(y5, "%a, %d %b %Y %H:%M:%S %z")
|
| 89534 |
maechler |
167 |
|
|
|
168 |
cat('Time elapsed: ', proc.time(),'\n')
|