-
Notifications
You must be signed in to change notification settings - Fork 0
/
timezones.Rmd
134 lines (107 loc) · 4.79 KB
/
timezones.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
---
title: "Exkurs Zeitzonen (in German)"
author: "Hauke Sonnenberg"
date: "`r Sys.Date()`"
output: rmarkdown::html_vignette
vignette: >
%\VignetteIndexEntry{Exkurs Zeitzonen (in German)}
%\VignetteEngine{knitr::rmarkdown}
%\VignetteEncoding{UTF-8}
---
```{r setup, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>"
)
```
`POSIXct`-Objekte haben eine Zeitzone als Attribut gespeichert:
```{r}
now <- as.POSIXct("2019-04-08 12:34:56")
attributes(now)
```
Wenn, wie hier, keine Zeitzone angegeben ist (`tzone = ""`) , wird diejenige
angenommen, die auf dem Rechner eingestellt ist. Diese kann wie folgt ermittelt
werden:
```{r}
Sys.timezone()
```
Das sollte bei Ihnen die Zeitzone "Europe/Berlin" sein. In dieser Zeitzone gibt
es (noch, die EU hat die Abschaffung der Zeitumstellung beschlossen, oder?) eine
Umstellung zwischen Sommer- und Winterzeit und umgekehrt. Erst vor kurzem,
am 31.03.2019, wurde die Uhr wieder von Winterzeit (bzw. Normalzeit) auf
Sommerzeit umgestellt. Wie sieht das in R aus?
```{r}
(before_switch <- as.POSIXct("2019-03-31 01:59:00"))
# eine Minute spaeter...
before_switch + 60
```
Wir setzen uns mit der Variablen `before_switch` auf den Zeitpunkt, der eine
Minute vor der Zeitumstellung liegt. Geben wir den Zeitpunkt aus, so wird uns
angezeigt, dass wir uns in "CET = Central European Time" befinden. Eine Minute,
also 60 Sekunden später ist es bereits 03:00 Uhr, da die Uhr um 02:00 auf 03:00
vorgestellt wird. Es wird angezeigt, dass wir uns nun in "CEST = Central
European Summer Time" befinden.
**Achtung**: Wenn ein Zeitstempel angegeben wird, der in der gegebenen Zeitzone
nicht exisitert, passieren unerwartete Dinge. Das muss
unbedingt beachtet werden, wenn mit Zeitreihen gearbeitet wird! Zum Beispiel
existieren in der Zeitzone "Europe/Berlin" diejenigen Zeitstempel nicht, die am
Tag der Umstellung auf Sommerzeit in der Stunde zwischen zwei und drei Uhr
morgens liegen (genauer die Zeitstempel zwischen 02:00:01 und 02:59:59). Zum
Beispiel gibt es an diesem Tag nicht die Uhrzeit "halb drei":
```{r}
(non_existing_time <- as.POSIXct("2019-03-31 02:30:00"))
```
Welche Zeit wird hier angezeigt? Das scheint vom Betriebssystem abzuhängen! Auf
meinem Ubuntu-Rechner wird die Uhrzeit um eine Stunde zurückgesetzt und es wird
"2019-03-31 01:30:00 CET" angezeigt. In Windows hingegen würde die Uhrzeit
einfach "abgeschnitten", also intern auf "00:00:00" gesetzt und entsprechend
"2019-03-31 CET" angezeigt.
Um die Zeitumstellung zu unterbinden "zwinge" ich R gerne dazu, die Zeitzone
"UTC" (Coordinated Universal Time) zu verwenden. Dazu:
```{r}
(before_switch <- as.POSIXct("2019-03-31 01:59:00", tz = "UTC"))
# eine Minute spaeter...
(after_switch <- before_switch + 60)
```
Die Zeitzone ist und bleibt "UTC". Das Attribut "tzone" ist entsprechend auf
"UTC" gesetzt.
```{r}
attributes(before_switch)
attributes(after_switch)
```
Ich habe sehr lange gebraucht, bis ich herausgefunden habe, wie ich in R
angeben kann, dass ich zwar in Berlin bin, aber keine Umstellung von
Sommer- auf Winterzeit vornehme. Wir versuchen zum Beispiel unsere Messgeräte so
einzustellen, dass sie den Zeitstempel immer in Normalzeit (Winterzeit)
aufzeichnen und die Uhr weder vor- noch zurückstellen. Wir tun dies, um zu
vermeiden, dass doppelte Zeitstempel, nämlich in der Stunde, in der die Uhr
von Sommer- auf Winterzeit zurückgestellt wird, aufgezeichnet werden.
Der entscheidende Hinweis findet sich in der Hilfe zu "timezones":
```{r eval = FALSE}
help("timezones")
```
> "Most platforms support time zones of the form Etc/GMT+n and Etc/GMT-n
> (possibly also without prefix Etc/), which assume a fixed offset from UTC
> (hence no DST). Contrary to some expectations (but consistent with names such
> as PST8PDT), negative offsets are times ahead of (east of) UTC, positive
> offsets are times behind (west of) UTC."
Um also R mitzuteilen, dass wir in Berlin durchgängig in Winterzeit messen,
müssen wir die Zeitzone auf "Etc/GMT-1" stellen.
```{r}
(before_switch_normal <- as.POSIXct("2019-03-31 01:59:00", tz = "Etc/GMT-1"))
(after_switch_normal <- before_switch_normal + 60)
```
Um diese zwei Zeitpunkte nun wieder in der Zeitzone "Europe/Berlin" anzeigen zu lassen, nutzen wir die `format()` Funktion:
```{r}
format(before_switch_normal, tz = "Europe/Berlin")
format(after_switch_normal, tz = "Europe/Berlin")
```
Nanu, die Angaben "CET" bzw. "CEST" werden nun nicht mehr angegeben, wie das
oben noch der Fall war. Das liegt daran, dass die `format()` Funktion diesen
Zusatz standardmäßig nicht anzeigt. Wir können die Anzeige wieder erreichen,
indem wir (hier nur temporär) das Attribut "tzone" mit Hilfe der Funktion
`structure()` wieder auf "Europe/Berlin" setzen:
```{r}
structure(before_switch_normal, tzone = "Europe/Berlin")
structure(after_switch_normal, tzone = "Europe/Berlin")
```