The R Project SVN R

Rev

Rev 90134 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
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')