如何从POSIXct和POSIXlt对象中提取正确的时区?

时间:2011-05-20 11:17:29

标签: r timezone posix

time1 = as.POSIXlt("2010-07-01 16:00:00", tz="Europe/London")
time1
# [1] "2010-07-01 16:00:00 Europe/London"

time2 = as.POSIXct("2010-07-01 16:00:00", tz="Europe/London")
time2
# [1] "2010-07-01 16:00:00 BST"

为什么时区的呈现方式不同?这对我很重要,因为我需要从我的约会时间中提取时区。

base::format(time1, format="%Z")
# [1] "BST"
base::format(time2, format="%Z")
# [1] "BST"

两者都为英国拯救时间提供相同的“BST”!

问题是“BST”不会被POSIXct / POSIXlt格式识别:

as.POSIXlt("2010-07-01 16:00:00", tz="BST")
# [1] "2010-07-01 16:00:00 BST"
# Warning messages:
# 1: In strptime(xx, f <- "%Y-%m-%d %H:%M:%OS", tz = tz) :
#   unknown timezone 'BST'
# 2: In structure(xx, class = c("POSIXct", "POSIXt"), tzone = tz) :
#   unknown timezone 'BST'
# 3: In strptime(x, f, tz = tz) : unknown timezone 'BST'
as.POSIXct("2010-07-01 16:00:00", tz="BST")
# [1] "2010-07-01 16:00:00 GMT"
# Warning messages:
# 1: In strptime(xx, f <- "%Y-%m-%d %H:%M:%OS", tz = tz) :
#   unknown timezone 'BST'
# 2: In structure(xx, class = c("POSIXct", "POSIXt"), tzone = tz) :
#   unknown timezone 'BST'
# 3: In strptime(x, f, tz = tz) : unknown timezone 'BST'
# 4: In structure(xx, class = c("POSIXct", "POSIXt"), tzone = tz) :
#   unknown timezone 'BST'
# 5: In as.POSIXlt.POSIXct(x, tz) : unknown timezone 'BST'

我真的很困惑。 我有两个问题:

1 / POSIXct和POSIXlt格式有什么区别

2 /任何人都知道我可以使用的时区吗?

“欧洲/伦敦”适用于POSIXlt但不适用于POSIXct。另外,使用base :: format
无法从时间中提取它 “BST”as.POSIXctas.POSIXlt个功能中无法识别为有效时区。

3 个答案:

答案 0 :(得分:13)

@Koshke已经向你展示了

  • 两种日期类型的内部表示的差异,以及
  • 在内部,两个时区规格都相同。

您可以使用attr()以标准化方式获取时区。这将获得zone.tab文件中指定格式的时区,R用于定义时区(?timezones中的更多信息)。

例如:

> attr(time1,"tzone")
[1] "Europe/London"
> attr(time2,"tzone")
[1] "Europe/London"

尽管POSIXct使用的时区与POSIXlt不同,我感到非常惊讶,但属性是相同的。显然,这个“BST”只在打印POSIXct时弹出。在打印之前,POSIXct再次转换为POSIXlt,并使用同义词修改tzone属性:

> attr(as.POSIXlt(time2),"tzone")
[1] "Europe/london" "GMT"           "BST"   

这发生在内部 R函数as.POSIXlt的下游某处,由于需要解决更严重的问题,我暂时无法查看。但请随意浏览它,看看到底发生了什么。

在旁注中,在我的Windows 7 / R 2.13.0安装中,“BST”未被识别为时区(在zone.tab中也未提及)。

答案 1 :(得分:7)

或许,unclass对象可以帮助您检查差异:

> unclass(time1)
$sec
[1] 0

$min
[1] 0

... snip

$yday
[1] 181

$isdst
[1] 1

attr(,"tzone")
[1] "Europe/London"

> unclass(time2)
[1] 1277996400
attr(,"tzone")
[1] "Europe/London"

因此,POSIXlt包含日期作为组件列表,而POSIXct包含它作为数字,即UNIX纪元时间。

至于时区,它将超出R.的范围 请参阅http://en.wikipedia.org/wiki/Tz_database

中的说明

至于

的不同行为
as.POSIXct("2010-07-01 16:00:00", tz="BST")
as.POSIXlt("2010-07-01 16:00:00", tz="BST")

我怀疑as.POSIXct中存在一个错误,它不会处理tz参数。

答案 2 :(得分:-2)

  

1 / POSIXct和POSIXlt格式有什么区别

  • POSIXct是自the epoch
  • 以来的秒数
  • POSIXlt将日期时间拆分为%Y-%m-%d%Y/%m/%d %H:%M:%S或其他此类格式