我遇到以下问题:我获取的数据中的日期列包含由于夏令时而不存在的日期。 (例如2015-03-29 02:00在中欧时间不存在,因为时钟从01:59直接设置为03:00,因为DST在这一天生效)
是否有一种简单可靠的方法来确定日期在夏令时方面是否有效?
由于日期时间类的属性,这并非易事。
# generating the invalid time as POSIXlt object
test <- strptime("2015-03-29 02:00", format="%Y-%m-%d %H:%M", tz="CET")
# the object seems to represent something at least partially reasonable, notice the missing timezone specification though
test
# [1] "2015-03-29 02:00:00"
# strangely enough this object is regarded as NA by is.na
is.na(test)
# [1] TRUE
# which is no surprise if you consider:
is.na.POSIXlt
# function (x)
# is.na(as.POSIXct(x))
as.POSIXct(test)
# [1] NA
# inspecting the interior of my POSIXlt object:
unlist(test)
# sec min hour mday mon year wday yday isdst zone gmtoff
# "0" "0" "2" "29" "2" "115" "0" "87" "-1" "" NA
所以我想到的最简单的方法是检查isdst
对象的POSIXlt
字段,POSIXt
的帮助描述了如下字段:
isdst
夏令时标志。如果有效则为正数,否则为零, 如果不知道就会消极。
正在检查isdst
字段保存,因为dst-changes导致日期无效,或者-1
由于某些其他原因,该字段仅为-1
?
有关版本,平台和区域设置的信息
R.version
# _
# platform x86_64-w64-mingw32
# arch x86_64
# os mingw32
# system x86_64, mingw32
# status
# major 3
# minor 3.1
# year 2016
# month 06
# day 21
# svn rev 70800
# language R
# version.string R version 3.3.1 (2016-06-21)
# nickname Bug in Your Hair
Sys.getlocale()
# [1] "LC_COLLATE=German_Austria.1252;LC_CTYPE=German_Austria.1252;LC_MONETARY=German_Austria.1252;LC_NUMERIC=C;LC_TIME=English_United States.1252"
答案 0 :(得分:1)
手册说strptime
不会验证特定时区是否存在时间,因为转换为夏令时(?strptime
)。另外,手册说as.POSIXct
进行了这种验证,因此在手册之后,应该检查生成的POSIXct对象的NA(?asPOSIXct
),这将识别不存在的时间,如问题示例所示。但是,对于在时区(?asPOSIXct
)中存在两次的时间,结果是特定于操作系统的:
请记住,在大多数时区中,某些时候不会发生,有些时间会因为“夏令时”(也称为“夏季”)时间的过渡而发生两次。
strptime
不会验证此类时间(它不会假定特定时区),但as.POSIXct
转换将会这样做。
和
一个问题是在转入和转出DST时会发生什么,例如在英国
as.POSIXct(strptime("2011-03-27 01:30:00", "%Y-%m-%d %H:%M:%S"))
as.POSIXct(strptime("2010-10-31 01:30:00", "%Y-%m-%d %H:%M:%S"))
分别无效(时钟在格林尼治标准时间凌晨1点到2点BST前进)并且不明确(时钟在BST 2:00返回到格林尼治标准时间1点)。在这种情况下发生的事情是特定于操作系统的:一个应该预期第一个是'NA',但第二个可以被解释为BST或GMT(并且常见操作系统给出两个可能的值)。
答案 1 :(得分:1)
as.POSIXct(test)
的值似乎与平台有关,为获得可靠方法增加了一层复杂性。在我的Windows机器上,(R 3.3.1),as.POSIXct(test)
产生NA
,也由OP报告。但是,在我的Linux平台(相同的R版本)上,我得到以下内容:
times = c ("2015-03-29 01:00",
"2015-03-29 02:00",
"2015-03-29 03:00")
test <- strptime(times, format="%Y-%m-%d %H:%M", tz="CET")
test
#[1] "2015-03-29 01:00:00 CET" "2015-03-29 02:00:00 CEST" "2015-03-29 03:00:00 CEST"
as.POSIXct(test)
#[1] "2015-03-29 01:00:00 CET" "2015-03-29 01:00:00 CET" "2015-03-29 03:00:00 CEST"
as.character(test)
#[1] "2015-03-29 01:00:00" "2015-03-29 02:00:00" "2015-03-29 03:00:00"
as.character(as.POSIXct(test))
#[1] "2015-03-29 01:00:00" "2015-03-29 01:00:00" "2015-03-29 03:00:00"
我们可以依赖的一件事不是as.POSIXct(test)
的实际价值,而是当test
是无效的日期/时间时它会与test
不同:
(as.character(test) == as.character(as.POSIXct(test))) %in% TRUE
# TRUE FALSE TRUE
我不确定as.character
是否在这里是绝对必要的,但我包括它只是为了确保我们不会违反POSIX对象的任何其他奇怪行为。