我有以下问题:我获得的数据中的日期列包含由于夏令时而不存在的日期.(例如2015-03-29 02:00在中欧时间不存在,因为时钟从01:59直接设置为03:00因为DST在这一天生效)
是否有一种简单可靠的方法来确定日期在夏令时方面是否有效?
由于datetime类的属性,这并非易事.
# 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
Run Code Online (Sandbox Code Playgroud)
所以我想到的最简单的方法是检查对象的isdst字段POSIXlt,帮助POSIXt描述如下文件:
isdst
夏令时标志.如果有效则为正数,否则为零,如果未知则为负数.
是否isdst仅-1在日期因dst更改而无效时才检查字段保存,还是由于-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"
Run Code Online (Sandbox Code Playgroud)
的值似乎与平台相关,为获得可靠的as.POSIXct(test)方法增加了一层复杂性。在我的 Windows 机器上(R 3.3.1),生成,正如 OP 所报告的那样。但是,在我的 Linux 平台(相同的 R 版本)上,我得到以下信息:as.POSIXct(test)NA
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"
Run Code Online (Sandbox Code Playgroud)
我们可以依赖的一件事不是 的实际值 ,而是它与无效日期/时间时的as.POSIXct(test)值不同:testtest
(as.character(test) == as.character(as.POSIXct(test))) %in% TRUE
# TRUE FALSE TRUE
Run Code Online (Sandbox Code Playgroud)
我不确定这as.character是否绝对必要,但我将其包含在内只是为了确保我们不会与 POSIX 对象的任何其他奇怪行为发生冲突。