根据区域设置国家/地区信息检索时区(与操作系统无关)

时间:2012-07-05 15:41:34

标签: r datetime date timezone locale

又一个与日期/时间相关的问题; - )

在瞄准和射击之前

对于德国+ MS Windows + R 组合,情况有些混乱,因为以下结果会产生无效的时区:

> Sys.timezone()
[1] "MST"
Warning message:
In as.POSIXlt.POSIXct(Sys.time()) : unknown timezone 'MET-1MST'

这绝对不是R的错,它是Windows。因此,首先是问题; - )

问题

是否有一种简单/替代和操作系统独立方式通过区域设置信息查询您当前的国家/地区,然后查找相应的时区(格式"<country>/<city>",例如{{1}对于德国)?

我还应该补充一点,我希望解决方案独立于互联网资源,例如post/answer中所述。

问题背景

假设您知道如何指定您的时区。您可能听说过有关 CET / CEST 等的一些内容,但AFAIK在使用基本R功能时(至少位于德国;-))并没有真正让您到任何地方。

您可以从RHOME目录中的"Europe/Berlin"文件中获取可用"<country>/<city>"对的列表。但是,为了找到与您当前所在国家/地区相对应的时区,您需要知道ISO国家/地区代码。

当然,我们通常会为我们的祖国做,但我们假设我们不这样做(我想最终采用通用方法)。你接下来做什么?

以下是我的“四步”解决方案,但我对此并不满意,因为

  1. 它依赖于另一个贡献包(ISOcodes
  2. 我无法测试它是否适用于其他语言环境,因为如果您在印度,俄罗斯,澳大利亚等地,我不知道该信息会是什么样的。
  3. 有人有更好的主意吗?此外,如果您在德国以外的其他国家/地区的某些人可以通过并发布其地区信息/share/zoneinfo/zone.tab,那就太棒了。

    第1步:获取区域设置信息

    Sys.getlocale()

    第2步:从区域设置信息

    获取国家/地区名称
    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"
    

    第3步:获取ISO国家代码

    使用country.this <- unlist(strsplit(loc$LC_TIME, split="_|\\."))[2] > country.this [1] "Germany" 在包ISOcodes的数据集country.this中查找关联的国家/地区代码

    ISO_3166_1

    第4步:获取时区

    使用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" 在数据框中查找可从文件code

    派生的时区
    RHOME/share/zoneinfo/zone.tab

2 个答案:

答案 0 :(得分:2)

特别是关于你的问题:

  

是否有一种简单/替代且与操作系统无关的方式通过区域设置信息查询当前国家/地区,然后查找相应的时区?

不 - 没有。这是因为有几个国家/地区有多个时区。人们无法仅从这个国家知道时区。

这就是为什么TZDB标识符采用Area/Location的形式,而不仅仅是国家/地区代码列表。

答案 1 :(得分:0)

对您的工作流程进行一些简化。

您可以使用

仅检索语言环境的时间部分
Sys.getlocale("LC_TIME")

避免了分裂字符串的需要。

lubridate包中包含一个检索Olson风格时区名称的函数,因此您不必担心阅读和解析zone.tab

library(lubridate)
olson_time_zones()