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
 
90139 smeyer 2
R Under development (unstable) (2026-06-12 r90138) -- "Unsuffered Consequences"
90032 ripley 3
Copyright (C) 2026 The R Foundation for Statistical Computing
90139 smeyer 4
Platform: x86_64-pc-linux-gnu
64578 ripley 5
 
6
R is free software and comes with ABSOLUTELY NO WARRANTY.
7
You are welcome to redistribute it under certain conditions.
8
Type 'license()' or 'licence()' for distribution details.
9
 
10
R is a collaborative project with many contributors.
11
Type 'contributors()' for more information and
12
'citation()' on how to cite R or R packages in publications.
13
 
14
Type 'demo()' for some demos, 'help()' for on-line help, or
15
'help.start()' for an HTML browser interface to help.
16
Type 'q()' to quit R.
17
 
18
> ### Tests of often platform-dependent features of the POSIX[cl]t implementation.
19
> 
90032 ripley 20
> ### Expect differences, historically with 32-bit time_t and platforms
83236 ripley 21
> ### without tm_zone/tm_gmtoff.
90139 smeyer 22
> ### Also with musl (wrongly using current not historic "zone" abbreviations).
90032 ripley 23
> ### Please use the R-internal version for .Rout.save.
90139 smeyer 24
> ## IGNORE_RDIFF_BEGIN
25
> (tzCtype <- sessionInfo()[["tzcode_type"]])
26
[1] "internal"
27
> ## IGNORE_RDIFF_END
64578 ripley 28
> 
29
> z <- ISOdate(1890:1912, 1, 10, tz="UTC")
30
> ## Rome changed to CET for 1894
31
> as.POSIXlt(z, tz="Europe/Rome")
32
 [1] "1890-01-10 12:49:56 RMT" "1891-01-10 12:49:56 RMT"
33
 [3] "1892-01-10 12:49:56 RMT" "1893-01-10 12:49:56 RMT"
34
 [5] "1894-01-10 13:00:00 CET" "1895-01-10 13:00:00 CET"
35
 [7] "1896-01-10 13:00:00 CET" "1897-01-10 13:00:00 CET"
36
 [9] "1898-01-10 13:00:00 CET" "1899-01-10 13:00:00 CET"
37
[11] "1900-01-10 13:00:00 CET" "1901-01-10 13:00:00 CET"
38
[13] "1902-01-10 13:00:00 CET" "1903-01-10 13:00:00 CET"
39
[15] "1904-01-10 13:00:00 CET" "1905-01-10 13:00:00 CET"
40
[17] "1906-01-10 13:00:00 CET" "1907-01-10 13:00:00 CET"
41
[19] "1908-01-10 13:00:00 CET" "1909-01-10 13:00:00 CET"
42
[21] "1910-01-10 13:00:00 CET" "1911-01-10 13:00:00 CET"
43
[23] "1912-01-10 13:00:00 CET"
44
> ## Paris changed to PMT for 1892, WET for 1912
45
> (zz <- as.POSIXlt(z, tz="Europe/Paris"))
46
 [1] "1890-01-10 12:09:21 LMT" "1891-01-10 12:09:21 LMT"
47
 [3] "1892-01-10 12:09:21 PMT" "1893-01-10 12:09:21 PMT"
48
 [5] "1894-01-10 12:09:21 PMT" "1895-01-10 12:09:21 PMT"
49
 [7] "1896-01-10 12:09:21 PMT" "1897-01-10 12:09:21 PMT"
50
 [9] "1898-01-10 12:09:21 PMT" "1899-01-10 12:09:21 PMT"
51
[11] "1900-01-10 12:09:21 PMT" "1901-01-10 12:09:21 PMT"
52
[13] "1902-01-10 12:09:21 PMT" "1903-01-10 12:09:21 PMT"
53
[15] "1904-01-10 12:09:21 PMT" "1905-01-10 12:09:21 PMT"
54
[17] "1906-01-10 12:09:21 PMT" "1907-01-10 12:09:21 PMT"
55
[19] "1908-01-10 12:09:21 PMT" "1909-01-10 12:09:21 PMT"
56
[21] "1910-01-10 12:09:21 PMT" "1911-01-10 12:09:21 PMT"
57
[23] "1912-01-10 12:00:00 WET"
58
> strftime(zz, "%Y-%m-%d %H:%M:%S %Z")
59
 [1] "1890-01-10 12:09:21 LMT" "1891-01-10 12:09:21 LMT"
60
 [3] "1892-01-10 12:09:21 PMT" "1893-01-10 12:09:21 PMT"
61
 [5] "1894-01-10 12:09:21 PMT" "1895-01-10 12:09:21 PMT"
62
 [7] "1896-01-10 12:09:21 PMT" "1897-01-10 12:09:21 PMT"
63
 [9] "1898-01-10 12:09:21 PMT" "1899-01-10 12:09:21 PMT"
64
[11] "1900-01-10 12:09:21 PMT" "1901-01-10 12:09:21 PMT"
65
[13] "1902-01-10 12:09:21 PMT" "1903-01-10 12:09:21 PMT"
66
[15] "1904-01-10 12:09:21 PMT" "1905-01-10 12:09:21 PMT"
67
[17] "1906-01-10 12:09:21 PMT" "1907-01-10 12:09:21 PMT"
68
[19] "1908-01-10 12:09:21 PMT" "1909-01-10 12:09:21 PMT"
69
[21] "1910-01-10 12:09:21 PMT" "1911-01-10 12:09:21 PMT"
70
[23] "1912-01-10 12:00:00 WET"
83227 ripley 71
> ## The offset was really +00:09:21 until 1911, then +00:00
64578 ripley 72
> ## Many platforms will give the current offset, +0100
73
> strftime(zz, "%Y-%m-%d %H:%M:%S %z")
74
 [1] "1890-01-10 12:09:21 +0009" "1891-01-10 12:09:21 +0009"
75
 [3] "1892-01-10 12:09:21 +0009" "1893-01-10 12:09:21 +0009"
76
 [5] "1894-01-10 12:09:21 +0009" "1895-01-10 12:09:21 +0009"
77
 [7] "1896-01-10 12:09:21 +0009" "1897-01-10 12:09:21 +0009"
78
 [9] "1898-01-10 12:09:21 +0009" "1899-01-10 12:09:21 +0009"
79
[11] "1900-01-10 12:09:21 +0009" "1901-01-10 12:09:21 +0009"
80
[13] "1902-01-10 12:09:21 +0009" "1903-01-10 12:09:21 +0009"
81
[15] "1904-01-10 12:09:21 +0009" "1905-01-10 12:09:21 +0009"
82
[17] "1906-01-10 12:09:21 +0009" "1907-01-10 12:09:21 +0009"
83
[19] "1908-01-10 12:09:21 +0009" "1909-01-10 12:09:21 +0009"
84
[21] "1910-01-10 12:09:21 +0009" "1911-01-10 12:09:21 +0009"
85
[23] "1912-01-10 12:00:00 +0000"
86
> 
87
> ## Some platforms give details of the latest conversion.
88
> z <- ISOdate(c(seq(1890, 1940, 5), 1941:1946, 1950), 1, 10, tz="UTC")
89
> as.POSIXlt(z, tz="Europe/Paris")
90
 [1] "1890-01-10 12:09:21 LMT"  "1895-01-10 12:09:21 PMT" 
91
 [3] "1900-01-10 12:09:21 PMT"  "1905-01-10 12:09:21 PMT" 
92
 [5] "1910-01-10 12:09:21 PMT"  "1915-01-10 12:00:00 WET" 
93
 [7] "1920-01-10 12:00:00 WET"  "1925-01-10 12:00:00 WET" 
94
 [9] "1930-01-10 12:00:00 WET"  "1935-01-10 12:00:00 WET" 
95
[11] "1940-01-10 12:00:00 WET"  "1941-01-10 14:00:00 CEST"
96
[13] "1942-01-10 14:00:00 CEST" "1943-01-10 13:00:00 CET" 
97
[15] "1944-01-10 13:00:00 CET"  "1945-01-10 13:00:00 WEST"
98
[17] "1946-01-10 13:00:00 CET"  "1950-01-10 13:00:00 CET" 
99
> for(i in seq_along(z)) print(as.POSIXlt(z[i], tz="Europe/Paris"))
100
[1] "1890-01-10 12:09:21 LMT"
101
[1] "1895-01-10 12:09:21 PMT"
102
[1] "1900-01-10 12:09:21 PMT"
103
[1] "1905-01-10 12:09:21 PMT"
104
[1] "1910-01-10 12:09:21 PMT"
105
[1] "1915-01-10 12:00:00 WET"
106
[1] "1920-01-10 12:00:00 WET"
107
[1] "1925-01-10 12:00:00 WET"
108
[1] "1930-01-10 12:00:00 WET"
109
[1] "1935-01-10 12:00:00 WET"
110
[1] "1940-01-10 12:00:00 WET"
111
[1] "1941-01-10 14:00:00 CEST"
112
[1] "1942-01-10 14:00:00 CEST"
113
[1] "1943-01-10 13:00:00 CET"
114
[1] "1944-01-10 13:00:00 CET"
115
[1] "1945-01-10 13:00:00 WEST"
116
[1] "1946-01-10 13:00:00 CET"
117
[1] "1950-01-10 13:00:00 CET"
83236 ripley 118
> ## use pf %z needs tm_gmtoff
64578 ripley 119
> for(i in seq_along(z))
120
+     print(strftime(as.POSIXlt(z[i], tz="Europe/Paris"), "%Y-%m-%d %H:%M:%S %z"))
121
[1] "1890-01-10 12:09:21 +0009"
122
[1] "1895-01-10 12:09:21 +0009"
123
[1] "1900-01-10 12:09:21 +0009"
124
[1] "1905-01-10 12:09:21 +0009"
125
[1] "1910-01-10 12:09:21 +0009"
126
[1] "1915-01-10 12:00:00 +0000"
127
[1] "1920-01-10 12:00:00 +0000"
128
[1] "1925-01-10 12:00:00 +0000"
129
[1] "1930-01-10 12:00:00 +0000"
130
[1] "1935-01-10 12:00:00 +0000"
131
[1] "1940-01-10 12:00:00 +0000"
132
[1] "1941-01-10 14:00:00 +0200"
133
[1] "1942-01-10 14:00:00 +0200"
134
[1] "1943-01-10 13:00:00 +0100"
135
[1] "1944-01-10 13:00:00 +0100"
136
[1] "1945-01-10 13:00:00 +0100"
137
[1] "1946-01-10 13:00:00 +0100"
138
[1] "1950-01-10 13:00:00 +0100"
139
> 
140
> strptime("1920-12-27 08:18:23", "%Y-%m-%d %H:%M:%S", tz="Europe/Paris")
141
[1] "1920-12-27 08:18:23 WET"
142
> 
64585 ripley 143
> ## check %V etc
144
> 
145
> d <- expand.grid(day = 1:7, year = 2000:2010)
146
> z1 <- with(d, ISOdate(year, 1, day))
147
> d <- expand.grid(day = 25:31, year = 2000:2010)
148
> z2 <- with(d, ISOdate(year, 12, day))
149
> z <- sort(c(z1, z2))
79324 kalibera 150
> strftime(z, "%G %g %W %U %u %V %W %w", tz="Europe/Paris")
64585 ripley 151
  [1] "1999 99 00 00 6 52 00 6" "1999 99 00 01 7 52 00 0"
152
  [3] "2000 00 01 01 1 01 01 1" "2000 00 01 01 2 01 01 2"
153
  [5] "2000 00 01 01 3 01 01 3" "2000 00 01 01 4 01 01 4"
154
  [7] "2000 00 01 01 5 01 01 5" "2000 00 52 52 1 52 52 1"
155
  [9] "2000 00 52 52 2 52 52 2" "2000 00 52 52 3 52 52 3"
156
 [11] "2000 00 52 52 4 52 52 4" "2000 00 52 52 5 52 52 5"
157
 [13] "2000 00 52 52 6 52 52 6" "2000 00 52 53 7 52 52 0"
158
 [15] "2001 01 01 00 1 01 01 1" "2001 01 01 00 2 01 01 2"
159
 [17] "2001 01 01 00 3 01 01 3" "2001 01 01 00 4 01 01 4"
160
 [19] "2001 01 01 00 5 01 01 5" "2001 01 01 00 6 01 01 6"
161
 [21] "2001 01 01 01 7 01 01 0" "2001 01 52 51 2 52 52 2"
162
 [23] "2001 01 52 51 3 52 52 3" "2001 01 52 51 4 52 52 4"
163
 [25] "2001 01 52 51 5 52 52 5" "2001 01 52 51 6 52 52 6"
164
 [27] "2001 01 52 52 7 52 52 0" "2002 02 53 52 1 01 53 1"
165
 [29] "2002 02 00 00 2 01 00 2" "2002 02 00 00 3 01 00 3"
166
 [31] "2002 02 00 00 4 01 00 4" "2002 02 00 00 5 01 00 5"
167
 [33] "2002 02 00 00 6 01 00 6" "2002 02 00 01 7 01 00 0"
168
 [35] "2002 02 01 01 1 02 01 1" "2002 02 51 51 3 52 51 3"
169
 [37] "2002 02 51 51 4 52 51 4" "2002 02 51 51 5 52 51 5"
170
 [39] "2002 02 51 51 6 52 51 6" "2002 02 51 52 7 52 51 0"
171
 [41] "2003 03 52 52 1 01 52 1" "2003 03 52 52 2 01 52 2"
172
 [43] "2003 03 00 00 3 01 00 3" "2003 03 00 00 4 01 00 4"
173
 [45] "2003 03 00 00 5 01 00 5" "2003 03 00 00 6 01 00 6"
174
 [47] "2003 03 00 01 7 01 00 0" "2003 03 01 01 1 02 01 1"
175
 [49] "2003 03 01 01 2 02 01 2" "2003 03 51 51 4 52 51 4"
176
 [51] "2003 03 51 51 5 52 51 5" "2003 03 51 51 6 52 51 6"
177
 [53] "2003 03 51 52 7 52 51 0" "2004 04 52 52 1 01 52 1"
178
 [55] "2004 04 52 52 2 01 52 2" "2004 04 52 52 3 01 52 3"
179
 [57] "2004 04 00 00 4 01 00 4" "2004 04 00 00 5 01 00 5"
180
 [59] "2004 04 00 00 6 01 00 6" "2004 04 00 01 7 01 00 0"
181
 [61] "2004 04 01 01 1 02 01 1" "2004 04 01 01 2 02 01 2"
182
 [63] "2004 04 01 01 3 02 01 3" "2004 04 51 51 6 52 51 6"
183
 [65] "2004 04 51 52 7 52 51 0" "2004 04 52 52 1 53 52 1"
184
 [67] "2004 04 52 52 2 53 52 2" "2004 04 52 52 3 53 52 3"
185
 [69] "2004 04 52 52 4 53 52 4" "2004 04 52 52 5 53 52 5"
186
 [71] "2004 04 00 00 6 53 00 6" "2004 04 00 01 7 53 00 0"
187
 [73] "2005 05 01 01 1 01 01 1" "2005 05 01 01 2 01 01 2"
188
 [75] "2005 05 01 01 3 01 01 3" "2005 05 01 01 4 01 01 4"
189
 [77] "2005 05 01 01 5 01 01 5" "2005 05 51 52 7 51 51 0"
190
 [79] "2005 05 52 52 1 52 52 1" "2005 05 52 52 2 52 52 2"
191
 [81] "2005 05 52 52 3 52 52 3" "2005 05 52 52 4 52 52 4"
192
 [83] "2005 05 52 52 5 52 52 5" "2005 05 52 52 6 52 52 6"
193
 [85] "2005 05 00 01 7 52 00 0" "2006 06 01 01 1 01 01 1"
194
 [87] "2006 06 01 01 2 01 01 2" "2006 06 01 01 3 01 01 3"
195
 [89] "2006 06 01 01 4 01 01 4" "2006 06 01 01 5 01 01 5"
196
 [91] "2006 06 01 01 6 01 01 6" "2006 06 52 52 1 52 52 1"
197
 [93] "2006 06 52 52 2 52 52 2" "2006 06 52 52 3 52 52 3"
198
 [95] "2006 06 52 52 4 52 52 4" "2006 06 52 52 5 52 52 5"
199
 [97] "2006 06 52 52 6 52 52 6" "2006 06 52 53 7 52 52 0"
200
 [99] "2007 07 01 00 1 01 01 1" "2007 07 01 00 2 01 01 2"
201
[101] "2007 07 01 00 3 01 01 3" "2007 07 01 00 4 01 01 4"
202
[103] "2007 07 01 00 5 01 01 5" "2007 07 01 00 6 01 01 6"
203
[105] "2007 07 01 01 7 01 01 0" "2007 07 52 51 2 52 52 2"
204
[107] "2007 07 52 51 3 52 52 3" "2007 07 52 51 4 52 52 4"
205
[109] "2007 07 52 51 5 52 52 5" "2007 07 52 51 6 52 52 6"
206
[111] "2007 07 52 52 7 52 52 0" "2008 08 53 52 1 01 53 1"
207
[113] "2008 08 00 00 2 01 00 2" "2008 08 00 00 3 01 00 3"
208
[115] "2008 08 00 00 4 01 00 4" "2008 08 00 00 5 01 00 5"
209
[117] "2008 08 00 00 6 01 00 6" "2008 08 00 01 7 01 00 0"
210
[119] "2008 08 01 01 1 02 01 1" "2008 08 51 51 4 52 51 4"
211
[121] "2008 08 51 51 5 52 51 5" "2008 08 51 51 6 52 51 6"
212
[123] "2008 08 51 52 7 52 51 0" "2009 09 52 52 1 01 52 1"
213
[125] "2009 09 52 52 2 01 52 2" "2009 09 52 52 3 01 52 3"
214
[127] "2009 09 00 00 4 01 00 4" "2009 09 00 00 5 01 00 5"
215
[129] "2009 09 00 00 6 01 00 6" "2009 09 00 01 7 01 00 0"
216
[131] "2009 09 01 01 1 02 01 1" "2009 09 01 01 2 02 01 2"
217
[133] "2009 09 01 01 3 02 01 3" "2009 09 51 51 5 52 51 5"
218
[135] "2009 09 51 51 6 52 51 6" "2009 09 51 52 7 52 51 0"
219
[137] "2009 09 52 52 1 53 52 1" "2009 09 52 52 2 53 52 2"
220
[139] "2009 09 52 52 3 53 52 3" "2009 09 52 52 4 53 52 4"
221
[141] "2009 09 00 00 5 53 00 5" "2009 09 00 00 6 53 00 6"
222
[143] "2009 09 00 01 7 53 00 0" "2010 10 01 01 1 01 01 1"
223
[145] "2010 10 01 01 2 01 01 2" "2010 10 01 01 3 01 01 3"
224
[147] "2010 10 01 01 4 01 01 4" "2010 10 51 51 6 51 51 6"
225
[149] "2010 10 51 52 7 51 51 0" "2010 10 52 52 1 52 52 1"
226
[151] "2010 10 52 52 2 52 52 2" "2010 10 52 52 3 52 52 3"
227
[153] "2010 10 52 52 4 52 52 4" "2010 10 52 52 5 52 52 5"
228
> 
64596 ripley 229
> ## tests of earlier years.  Default format is OS-dependent, so don't test it.
64625 ripley 230
> ## ISOdate only accepts positive years.
64596 ripley 231
> z <- as.Date(ISOdate(c(0, 8, 9, 10, 11, 20, 110, 1010), 1, 10)) - 3630
83143 ripley 232
> strftime(z, "%04Y-%m-%d") # with leading zero(s), where supported
64596 ripley 233
[1] "-010-02-01" "-002-02-01" "-001-02-02" "0000-02-02" "0001-02-01"
234
[6] "0010-02-01" "0100-02-01" "1000-02-01"
83143 ripley 235
> strftime(z, "%_4Y-%m-%d") # with leading space(s), where supported
64625 ripley 236
[1] " -10-02-01" "  -2-02-01" "  -1-02-02" "   0-02-02" "   1-02-01"
237
[6] "  10-02-01" " 100-02-01" "1000-02-01"
238
> strftime(z, "%0Y-%m-%d") # without
64596 ripley 239
[1] "-10-02-01"  "-2-02-01"   "-1-02-02"   "0-02-02"    "1-02-01"   
240
[6] "10-02-01"   "100-02-01"  "1000-02-01"
241
> 
64607 ripley 242
> 
243
> ## more test of strftime
244
> x <- ISOdate(2014, 3, 10, c(7, 13))
245
> fmts <- c("%Y-%m-%d %H:%M:%S", "%F", "%A %a %b %h %e %I %j",
246
+           ## locale-dependent ones
247
+           "%X", # but the same in all English locales
248
+           "%c", "%x", "%p", "%r")
249
> for (f in fmts) print(format(x, f))
250
[1] "2014-03-10 07:00:00" "2014-03-10 13:00:00"
251
[1] "2014-03-10" "2014-03-10"
252
[1] "Monday Mon Mar Mar 10 07 069" "Monday Mon Mar Mar 10 01 069"
253
[1] "07:00:00" "13:00:00"
254
[1] "Mon Mar 10 07:00:00 2014" "Mon Mar 10 13:00:00 2014"
255
[1] "03/10/14" "03/10/14"
256
[1] "AM" "PM"
257
[1] "07:00:00 AM" "01:00:00 PM"
258
> 
83087 ripley 259
> ## Moved from reg-tests-1d.R
260
> ## as.POSIXlt(<very large Date>) gave integer overflow
261
> ## and needed C-level change for 32-bit time_t.
262
> .Machine$sizeof.time_t
263
[1] 8
264
> (z <- .Date(2^31 + 10))
265
[1] "5881580-07-22"
266
> as.POSIXlt(z)$year == 5879680L
267
[1] TRUE
268
> ## year was negative in R <= 4.2.1, even for 64-bit time_t
269
> 
83197 ripley 270
> 
271
> ## ------------- Tests of far-distant dates -----------
272
> Sys.setenv(TZ = "Europe/London")
88200 smeyer 273
> ## the pre-1902 POSIXct values will be 75s out on platforms that do not
83197 ripley 274
> ## know about UK changes prior to 1902 (in fact in 1847-12-01: see below).
275
> as.POSIXct("4000-07-01")
276
[1] "4000-07-01 BST"
277
> as.Date("4000-07-01")
278
[1] "4000-07-01"
279
> zz <- z <- as.POSIXlt("2000-07-01")
280
> unclass(z)
281
$sec
282
[1] 0
283
 
284
$min
285
[1] 0
286
 
287
$hour
288
[1] 0
289
 
290
$mday
291
[1] 1
292
 
293
$mon
294
[1] 6
295
 
296
$year
297
[1] 100
298
 
299
$wday
300
[1] 6
301
 
302
$yday
303
[1] 182
304
 
305
$isdst
306
[1] 1
307
 
308
$zone
309
[1] "BST"
310
 
311
$gmtoff
312
[1] NA
313
 
314
attr(,"tzone")
315
[1] "Europe/London" "GMT"           "BST"          
83231 maechler 316
attr(,"balanced")
83227 ripley 317
[1] TRUE
83197 ripley 318
> 
319
> years <- c(-1e6, -1e5, -1e4, seq(-1000, 4000, by = 100), 1e4, 1e5, 1e6)
320
> y <- character(length(years))
321
> for(i in seq_along(years)) {
322
+     zz$year = years[i] - 1900
323
+     y[i] <- strftime(zz)
324
+ }
84058 maechler 325
> ## IGNORE_RDIFF_BEGIN
83197 ripley 326
> y
327
 [1] "-1000000-07-01" "-100000-07-01"  "-10000-07-01"   "-1000-07-01"   
328
 [5] "-900-07-01"     "-800-07-01"     "-700-07-01"     "-600-07-01"    
329
 [9] "-500-07-01"     "-400-07-01"     "-300-07-01"     "-200-07-01"    
330
[13] "-100-07-01"     "0000-07-01"     "0100-07-01"     "0200-07-01"    
331
[17] "0300-07-01"     "0400-07-01"     "0500-07-01"     "0600-07-01"    
332
[21] "0700-07-01"     "0800-07-01"     "0900-07-01"     "1000-07-01"    
333
[25] "1100-07-01"     "1200-07-01"     "1300-07-01"     "1400-07-01"    
334
[29] "1500-07-01"     "1600-07-01"     "1700-07-01"     "1800-07-01"    
335
[33] "1900-07-01"     "2000-07-01"     "2100-07-01"     "2200-07-01"    
336
[37] "2300-07-01"     "2400-07-01"     "2500-07-01"     "2600-07-01"    
337
[41] "2700-07-01"     "2800-07-01"     "2900-07-01"     "3000-07-01"    
338
[45] "3100-07-01"     "3200-07-01"     "3300-07-01"     "3400-07-01"    
339
[49] "3500-07-01"     "3600-07-01"     "3700-07-01"     "3800-07-01"    
340
[53] "3900-07-01"     "4000-07-01"     "10000-07-01"    "100000-07-01"  
341
[57] "1000000-07-01" 
84058 maechler 342
> ## IGNORE_RDIFF_END
83197 ripley 343
> 
344
> y <- double(length(years))
345
> for(i in seq_along(years)) {
346
+     zz$year = years[i] - 1900
347
+     zz$isdst <- -1 # some are DST, some not so let the code decide
348
+     y[i] <- as.POSIXct(zz)
349
+ }
350
> print(y, digits=14)
351
 [1] -31619103494325  -3217846694325   -377721014325    -93708489525
352
 [5]    -90552815925    -87397055925    -84241382325    -81085708725
353
 [9]    -77930035125    -74774275125    -71618601525    -68462927925
354
[13]    -65307254325    -62151494325    -58995820725    -55840147125
355
[17]    -52684473525    -49528713525    -46373039925    -43217366325
356
[21]    -40061692725    -36905932725    -33750259125    -30594585525
357
[25]    -27438911925    -24283151925    -21127478325    -17971804725
358
[29]    -14816131125    -11660371125     -8504697525     -5349023925
359
[33]     -2193350400       962406000      4118079600      7273753200
360
[37]     10429426800     13585186800     16740860400     19896534000
361
[41]     23052207600     26207967600     29363641200     32519314800
362
[45]     35674988400     38830748400     41986422000     45142095600
363
[49]     48297769200     51453529200     54609202800     57764876400
364
[53]     60920550000     64076310000    253418022000   3093543702000
365
[57]  31494800502000
366
> y <- .POSIXct(y)
84058 maechler 367
> ## IGNORE_RDIFF_BEGIN
83197 ripley 368
> (y1 <- strftime(y)) # leading zeros or spaces is platform-dependant
369
 [1] "-1000000-07-01" "-100000-07-01"  "-10000-07-01"   "-1000-07-01"   
370
 [5] "-900-07-01"     "-800-07-01"     "-700-07-01"     "-600-07-01"    
371
 [9] "-500-07-01"     "-400-07-01"     "-300-07-01"     "-200-07-01"    
372
[13] "-100-07-01"     "0000-07-01"     "0100-07-01"     "0200-07-01"    
373
[17] "0300-07-01"     "0400-07-01"     "0500-07-01"     "0600-07-01"    
374
[21] "0700-07-01"     "0800-07-01"     "0900-07-01"     "1000-07-01"    
375
[25] "1100-07-01"     "1200-07-01"     "1300-07-01"     "1400-07-01"    
376
[29] "1500-07-01"     "1600-07-01"     "1700-07-01"     "1800-07-01"    
377
[33] "1900-07-01"     "2000-07-01"     "2100-07-01"     "2200-07-01"    
378
[37] "2300-07-01"     "2400-07-01"     "2500-07-01"     "2600-07-01"    
379
[41] "2700-07-01"     "2800-07-01"     "2900-07-01"     "3000-07-01"    
380
[45] "3100-07-01"     "3200-07-01"     "3300-07-01"     "3400-07-01"    
381
[49] "3500-07-01"     "3600-07-01"     "3700-07-01"     "3800-07-01"    
382
[53] "3900-07-01"     "4000-07-01"     "10000-07-01"    "100000-07-01"  
383
[57] "1000000-07-01" 
84058 maechler 384
> ## IGNORE_RDIFF_END
83197 ripley 385
> y2 <- strftime(y, "%_4Y-%m-%d") # not all platforms interpret this
386
> if(y2[1] != "4Y-07-01") print(y2) else message('format "%_4Y" unsupported')
387
 [1] "-1000000-07-01" "-100000-07-01"  "-10000-07-01"   "-1000-07-01"   
388
 [5] "-900-07-01"     "-800-07-01"     "-700-07-01"     "-600-07-01"    
389
 [9] "-500-07-01"     "-400-07-01"     "-300-07-01"     "-200-07-01"    
390
[13] "-100-07-01"     "   0-07-01"     " 100-07-01"     " 200-07-01"    
391
[17] " 300-07-01"     " 400-07-01"     " 500-07-01"     " 600-07-01"    
392
[21] " 700-07-01"     " 800-07-01"     " 900-07-01"     "1000-07-01"    
393
[25] "1100-07-01"     "1200-07-01"     "1300-07-01"     "1400-07-01"    
394
[29] "1500-07-01"     "1600-07-01"     "1700-07-01"     "1800-07-01"    
395
[33] "1900-07-01"     "2000-07-01"     "2100-07-01"     "2200-07-01"    
396
[37] "2300-07-01"     "2400-07-01"     "2500-07-01"     "2600-07-01"    
397
[41] "2700-07-01"     "2800-07-01"     "2900-07-01"     "3000-07-01"    
398
[45] "3100-07-01"     "3200-07-01"     "3300-07-01"     "3400-07-01"    
399
[49] "3500-07-01"     "3600-07-01"     "3700-07-01"     "3800-07-01"    
400
[53] "3900-07-01"     "4000-07-01"     "10000-07-01"    "100000-07-01"  
401
[57] "1000000-07-01" 
402
> 
403
> y <- double(length(years))
404
> for(i in seq_along(years)) {
405
+     zz$year = years[i] - 1900
406
+     zz$isdst <- -1
407
+     y[i] <- as.Date(zz)
408
+ }
409
> y
410
 [1] -365961846  -37243596   -4371771   -1084589   -1048065   -1011540
411
 [7]    -975016    -938492    -901968    -865443    -828919    -792395
412
[13]    -755871    -719346    -682822    -646298    -609774    -573249
413
[19]    -536725    -500201    -463677    -427152    -390628    -354104
414
[25]    -317580    -281055    -244531    -208007    -171483    -134958
415
[31]     -98434     -61910     -25386      11139      47663      84187
416
[37]     120711     157236     193760     230284     266808     303333
417
[43]     339857     376381     412905     449430     485954     522478
418
[49]     559002     595527     632051     668575     705099     741624
419
[55]    2933079   35804904  364523154
420
> class(y) <- "Date"
84058 maechler 421
> ## IGNORE_RDIFF_BEGIN
83197 ripley 422
> (y3 <- strftime(y))
423
 [1] "-1000000-07-01" "-100000-07-01"  "-10000-07-01"   "-1000-07-01"   
424
 [5] "-900-07-01"     "-800-07-01"     "-700-07-01"     "-600-07-01"    
425
 [9] "-500-07-01"     "-400-07-01"     "-300-07-01"     "-200-07-01"    
426
[13] "-100-07-01"     "0000-07-01"     "0100-07-01"     "0200-07-01"    
427
[17] "0300-07-01"     "0400-07-01"     "0500-07-01"     "0600-07-01"    
428
[21] "0700-07-01"     "0800-07-01"     "0900-07-01"     "1000-07-01"    
429
[25] "1100-07-01"     "1200-07-01"     "1300-07-01"     "1400-07-01"    
430
[29] "1500-07-01"     "1600-07-01"     "1700-07-01"     "1800-07-01"    
431
[33] "1900-07-01"     "2000-07-01"     "2100-07-01"     "2200-07-01"    
432
[37] "2300-07-01"     "2400-07-01"     "2500-07-01"     "2600-07-01"    
433
[41] "2700-07-01"     "2800-07-01"     "2900-07-01"     "3000-07-01"    
434
[45] "3100-07-01"     "3200-07-01"     "3300-07-01"     "3400-07-01"    
435
[49] "3500-07-01"     "3600-07-01"     "3700-07-01"     "3800-07-01"    
436
[53] "3900-07-01"     "4000-07-01"     "10000-07-01"    "100000-07-01"  
437
[57] "1000000-07-01" 
84058 maechler 438
> ## IGNORE_RDIFF_END
83197 ripley 439
> y4 <- strftime(y, "%_4Y-%m-%d")
440
> stopifnot(identical(y3, y1))
441
> 
442
> zz <- as.POSIXlt("1900-07-01")
443
> years <- c(1800, 1847:1848, 1899:1902)
444
> y <- double(length(years))
445
> for(i in seq_along(years)) {
446
+     zz$year = years[i] - 1900
447
+     zz$isdst <- -1 # some are DST, some not so let the code decide
448
+     y[i] <- as.POSIXct(zz)
449
+ }
450
> print(y, digits=14)
451
[1] -5349023925 -3865881525 -3834259200 -2224886400 -2193350400 -2161814400
452
[7] -2130278400
453
> .POSIXct(y)
454
[1] "1800-07-01 LMT" "1847-07-01 LMT" "1848-07-01 GMT" "1899-07-01 GMT"
455
[5] "1900-07-01 GMT" "1901-07-01 GMT" "1902-07-01 GMT"
456
> 
457
> ## change of 75s in 1847
458
> seq(as.POSIXlt("1847-11-24"), as.POSIXlt("1847-12-07"), by ="day")
459
 [1] "1847-11-24 00:00:00 LMT" "1847-11-25 00:00:00 LMT"
460
 [3] "1847-11-26 00:00:00 LMT" "1847-11-27 00:00:00 LMT"
461
 [5] "1847-11-28 00:00:00 LMT" "1847-11-29 00:00:00 LMT"
462
 [7] "1847-11-30 00:00:00 LMT" "1847-12-01 00:01:15 GMT"
463
 [9] "1847-12-02 00:01:15 GMT" "1847-12-03 00:01:15 GMT"
464
[11] "1847-12-04 00:01:15 GMT" "1847-12-05 00:01:15 GMT"
465
[13] "1847-12-06 00:01:15 GMT"
466
> 
467
> ## end of ------------- Tests of far-distant dates -----------
468
> 
83227 ripley 469
> ## Tests of %z and %Z for output.
83236 ripley 470
> ## Use pf %z needs tm_gmtoff so offsets will otherwise be +0000
83227 ripley 471
> x1 <- strptime("2022-07-01", "%Y-%m-%d", tz = "UTC")
472
> x2 <- strptime("2022-07-01", "%Y-%m-%d", tz = "Europe/Rome")
473
> x1
474
[1] "2022-07-01 UTC"
475
> x2
476
[1] "2022-07-01 CEST"
477
> # RFC5322 format
478
> format(x1, "%a, %d %b %Y %H:%M:%S %z")
479
[1] "Fri, 01 Jul 2022 00:00:00 +0000"
83247 ripley 480
> # offset may not not determined: +0200 is correct
83227 ripley 481
> format(x2, "%a, %d %b %Y %H:%M:%S %z")
482
[1] "Fri, 01 Jul 2022 00:00:00 +0200"
483
> format(as.POSIXct(x2), "%a, %d %b %Y %H:%M:%S %z") # usually correct
484
[1] "Fri, 01 Jul 2022 00:00:00 +0200"
485
> format(x1, "%a, %d %b %Y %H:%M:%S %Z")
486
[1] "Fri, 01 Jul 2022 00:00:00 UTC"
487
> format(x2, "%a, %d %b %Y %H:%M:%S %Z")
488
[1] "Fri, 01 Jul 2022 00:00:00 CEST"
83197 ripley 489
> 
83297 ripley 490
> ## offsets not in whole hours:
83227 ripley 491
> x3 <- strptime("2022-01-01", "%Y-%m-%d", tz = "Australia/Adelaide")
492
> format(as.POSIXct(x3), "%a, %d %b %Y %H:%M:%S %z") # +10h30m
493
[1] "Sat, 01 Jan 2022 00:00:00 +1030"
90139 smeyer 494
> # Liberia does/did not have DST and, before 1972-01-07, used MMT (-44m30s)
83227 ripley 495
> x4 <- strptime("1971-01-01", "%Y-%m-%d", tz = "Africa/Monrovia")
83297 ripley 496
> y4 <- as.POSIXct(x4)
90139 smeyer 497
> lt4 <- unclass(as.POSIXlt(y4))
90134 maechler 498
> ## IGNORE_RDIFF_BEGIN
90139 smeyer 499
> attr(lt4, "tzone")
500
[1] "Africa/Monrovia" "GMT"             "   "            
501
> ## glibc prints an abbreviation for DST. internal and musl leave it blank.
502
> ## IGNORE_RDIFF_END
503
> stopifnot(identical(
504
+     attr(lt4, "tzone") |> trimws(), # ignore "   " (internal) vs. "" (musl)
505
+     c("Africa/Monrovia", "GMT", if(grepl("glibc", tzCtype)) "GMT" else "")
506
+ ))
507
> str(`attr<-`(lt4, "tzone", NULL))
83297 ripley 508
List of 11
509
 $ sec   : num 0
510
 $ min   : int 0
511
 $ hour  : int 0
512
 $ mday  : int 1
513
 $ mon   : int 0
514
 $ year  : int 71
515
 $ wday  : int 5
516
 $ yday  : int 0
517
 $ isdst : int 0
518
 $ zone  : chr "MMT"
519
 $ gmtoff: int -2670
520
 - attr(*, "balanced")= logi TRUE
90139 smeyer 521
> ## musl wrongly gives zone="GMT" (the current, not that at the time).
522
> ## macOS' strftime printed gmtoff wrong as -44m.
90032 ripley 523
> format(y4, "%a, %d %b %Y %H:%M:%S %z")
83227 ripley 524
[1] "Fri, 01 Jan 1971 00:00:00 -0044"
90139 smeyer 525
> 
83227 ripley 526
> ## timezones in 1900 might not be supported
527
> x5 <- strptime("1900-03-01", "%Y-%m-%d", tz = "Europe/Paris")
83297 ripley 528
> y5 <- as.POSIXct(x5)
529
> str(unclass(as.POSIXlt(y5))) # ditto
530
List of 11
531
 $ sec   : num 0
532
 $ min   : int 0
533
 $ hour  : int 0
534
 $ mday  : int 1
535
 $ mon   : int 2
536
 $ year  : int 0
537
 $ wday  : int 4
538
 $ yday  : int 59
539
 $ isdst : int 0
540
 $ zone  : chr "PMT"
541
 $ gmtoff: int 561
542
 - attr(*, "tzone")= chr [1:3] "Europe/Paris" "CET" "CEST"
543
 - attr(*, "balanced")= logi TRUE
544
> format(y5, "%a, %d %b %Y %H:%M:%S %z")
83227 ripley 545
[1] "Thu, 01 Mar 1900 00:00:00 +0009"
546
> 
89613 smeyer 547
> cat('Time elapsed: ', proc.time(),'\n')
90139 smeyer 548
Time elapsed:  0.158 0.027 0.187 0.002 0.003 
89613 smeyer 549
>