R中的posixct日期和时间未以午夜为中心

4
我有两列存储日期和时间的数据。第一列存储日期,格式为“20180831”。时间以距午夜的秒数存储;例如,凌晨3点将存储为10800。
我需要一个合并的日期时间列,但是这件事情却很棘手。
我可以轻松获取日期,但 lubridate “hms” 将时间字段解释为一段时间,而不是真正的“时间”。
我尝试将日期转换为posix.ct格式,并将其用作时间字段的起始时间,但是posix.ct不会将时间设置为午夜,而是将其设置为1800或1900小时,具体取决于日期。我需要所有行的时间都设置为午夜,我不希望进行任何夏令时调整。
以下是代码: 首先,我创建了一个函数,因为我需要对多个日期和时间字段执行此操作。
mkdate<-function(x){
a<-as.Date(as.character(x),format='%Y%m%d')
a<-as.POSIXct(a)
return(a)
}

df$date<-mkdate(df$date) #applies date making function to date field 

df$datetime<-as.POSIXct(df$time,origin=df$date)

我相信这与时区有关。我在中部时区,尝试在mkdate函数和创建“datetime”列的时间代码中添加“tz”规范。

我尝试了以下命令:

tz="America/Chicago"
tz="CST"
tz="UTC"

希望能得到您的帮助!

以下是示例:

x<-c(20180831,20180710,20160511,20170105,20180101) #these are dates.

as.POSIXct(as.Date(as.character(x),format="%Y%m%d")) 

上述代码将日期转换为从1970年1月1日开始算起的秒数。我可以将其转换为数字,并将我的“秒”值加入此字段,但这是不正确的。下面是输出结果:
[1] "2018-08-30 19:00:00 CDT" "2018-07-09 19:00:00 CDT" "2016-05-10 19:00:00 CDT" "2017-01-04 18:00:00 CST" "2017-12-31 18:00:00 CST"

看第一个日期 - 应该是8/31,但实际上是8/30。在这其中某个地方进行了时区调整。它将时钟向后移动了5或6个小时,因为我处于中央时区。第一条记录应该是2018-08-31 00:00:00。然后我会将其转换为数字,并添加秒字段,然后再转换回POSIXct格式。我试过在各个地方包括TZ规范,但没有成功。

Sys.getlocale("LC_TIME")

返回 "English_United States.1252"

2个回答

1

有很多种方法可以做到这一点:

mktime = function(a, b)modifyList(strptime(a, '%Y%m%d'), list(sec = as.numeric(gsub(',', '', b))))

 mktime("20180831",'10,800')
 [1] "2018-08-31 03:00:00 PDT"
mktime('20180301','10800')
[1] "2018-03-01 03:00:00 PST"
 mktime('20180321','10800')
[1] "2018-03-21 03:00:00 PDT"

看着上面的代码,它没有调整夏令时。不管日期如何,秒数仍然显示为凌晨3点,包括从标准时间(ST)到夏令时(DT)的日期。这也将考虑你的本地时区。


1
我相信以下内容可以满足你的需求。
我的语言环境如下,因此结果与你的不同。
Sys.getlocale("LC_TIME")
#[1] "Portuguese_Portugal.1252"

由于夏令时的影响,时间差异会产生。
至于您的问题,您只需要记住,"POSIXct"类的对象编码是自一个起点以来的秒数,而该起点通常是1970-01-01午夜。因此,您需要将从午夜开始的秒数加到as.Date的秒数上。
x <- "20180831"

xd <- mkdate(x)
y <- 10800

as.POSIXct(as.integer(xd) + y, origin = "1970-01-01")
#[1] "2018-08-31 04:00:00 BST"

as.POSIXct(as.integer(xd) + y, origin = "1970-01-01", tz = "America/Chicago")
#[1] "2018-08-30 22:00:00 CDT"

这并没有完全解决问题。当我将日期转换为POSIXct格式时,时间会显示为1800或1900,而不是0。我可以像你上面所做的那样添加秒数到时间中,但由于日期函数给我留下了一个嵌入的1800或1900的时间,所以结果时间并不准确。我将在问题中附上我看到的示例。 - Will Hauser
我想我明白了。问题在于使用“as.Date”函数,它似乎进行了一些时区调整。像您所做的那样始终使用as.POSIXct,看起来一切都正常。 “as.Date”函数需要更好的文档和一些灵活的选项来控制此行为,这可能是好事或非常糟糕的情况,具体情况取决于情况。 - Will Hauser

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接