又是一个与日期/时间相关的问题;-)
在动手之前
由于以下组合会导致无效的时区,因此使用德国+MS Windows+R可能会存在一些混乱:
> Sys.timezone()
[1] "MST"
Warning message:
In as.POSIXlt.POSIXct(Sys.time()) : unknown timezone 'MET-1MST'
这绝对不是R的错,而是Windows的问题。这就是为什么一开始有这个问题的原因 ;-)
问题
是否有一种易于使用/替代性的、独立于操作系统的方法来通过区域设置信息查询您当前所在的国家,并查找相应的时区(格式为“<country>/<city>
”,例如德国的“Europe/Berlin
”)?
我还要补充一点,我希望解决方案不依赖于互联网资源,如在此帖子/答案中所述。
问题背景
假设您不知道如何指定您的时区。您可能听说过一些有关CET/CEST等的内容,但据我所知,在使用基本R功能时(至少在德国),这并不能让您找到正确的时区。
您可以从RHOME目录中的/share/zoneinfo/zone.tab
文件中获取可用的"<country>/<city>"
对列表。但是,为了找到与您所在的国家对应的时区,您需要知道ISO国家代码。
当然,我们通常知道我们自己的本国代码,但是让我们假设我们不知道(我想最终得到一种通用方法)。那么接下来该怎么办呢?
以下是我的“四步解决方案”,但我并不是很满意它,因为:
- 它依赖于另一个贡献包(ISOcodes)。
- 我无法测试它是否适用于其他区域设置,因为我不知道如果您在印度、俄罗斯、澳大利亚等地,信息实际上看起来如何。
有没有更好的想法?而且,如果您所在的国家不是德国,那么希望您能运行此程序并发布您的区域设置信息Sys.getlocale()
。
步骤1:获取区域设置信息
loc <- strsplit(unlist(strsplit(Sys.getlocale(), split=";")), split="=")
foo <- function(x) {
out <- list(x[2])
names(out) <- x[1]
out
}
loc <- sapply(loc, foo)
> loc
$LC_COLLATE
[1] "German_Germany.1252"
$LC_CTYPE
[1] "German_Germany.1252"
$LC_MONETARY
[1] "German_Germany.1252"
$LC_NUMERIC
[1] "C"
$LC_TIME
[1] "German_Germany.1252"
步骤2:从本地信息获取国家名称
country.this <- unlist(strsplit(loc$LC_TIME, split="_|\\."))[2]
> country.this
[1] "Germany"
第三步:获取ISO国家代码
使用country.this
在数据集ISO_3166_1
中查找相关的国家代码,该数据集位于ISOcodes包中。
require("ISOcodes")
data("ISO_3166_1")
iso <- ISO_3166_1
idx <- which(iso$Name %in% country.this)
code <- iso[idx, "Alpha_2"]
> code
[1] "DE"
步骤4:获取时区
使用代码
在从文件RHOME/share/zoneinfo/zone.tab
派生出来的数据框中查找时区。
path <- file.path(Sys.getenv("R_HOME"), "share/zoneinfo/zone.tab")
tzones <- read.delim(
path,
row.names=NULL,
header=FALSE,
col.names=c("country", "coords", "name", "comments"),
as.is=TRUE,
fill=TRUE,
comment.char = "#"
)
> tzones[which(tzones$country == code), "name"]
[4] "Europe/Berlin"
system
调用呢? - Jase_shell('systeminfo | findstr ".*zone:"')
。或者你可以使用注册表:readRegistry("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones", "HLM", 2)
(这两种解决方案仅适用于Windows)。 - sgibb