由于无法解决的原因,我收到了带有奇数时区的R数据。
我想测试数据集中的最新日期是否等于给定日期(比如当前日期),但我在(不需要的)时区转换方面遇到了问题。是否有一种自然的方法来测试两个日期字符串是否相同,即使时区不同?我不一定知道数据的时区。
我偶然发现了两种"解决方案",但这两种方案似乎都是低效(且限制性)的黑客:
substr(as.character(last(odd_data$date)), 1, 10) == substr(as.character(Sys.Date()), 1, 10)
和
lastDate <- as.POSIXlt(last(odd_data$date))
as.Date(paste0(lastDate$year + 1900, "-", lastDate$mon + 1, "-", lastDate$mday)) == Sys.Date()
两人都给了我需要的答案,但我觉得我在反对语言。
我想回答的问题是:如果不同时区的人写下进行体验的日期,它会和我提供的日期相同吗(示例代码为Sys.Date()
)?
--
消除歧义——假设我有这两个日期:
> date.Syd <- as.POSIXct("2012-12-11 08:30:01", tz = 'Australia/Sydney')
> date.Syd
[1] "2012-12-11 08:30:01 EST"
> date.Ldn <- as.POSIXct("2012-12-11 23:00:11", tz = 'GMT')
> date.Ldn
[1] "2012-12-11 23:00:11 GMT"
其中:
> as.Date(date.Syd)
[1] "2012-12-10"
> unclass(date.Syd)
[1] 1355175001
attr(,"tzone")
[1] "Australia/Sydney"
> as.Date(date.Ldn)
[1] "2012-12-11"
> unclass(date.Ldn)
[1] 1355266811
attr(,"tzone")
[1] "GMT"
在这种情况下,由于时区转换,测试日期相等性失败(不希望):
> as.Date(date.Syd) == as.Date(date.Ldn)
[1] FALSE
这就是为什么我使用了我的丑陋角色/POSIXlt黑客:
> substr(as.character(date.Syd), 1,10) == substr(as.character(date.Ldn), 1,10)
[1] TRUE
和
> date.Syd_lt <- as.POSIXlt(date.Syd)
> date.Ldn_lt <- as.POSIXlt(date.Ldn)
> paste0(date.Syd_lt$year + 1900, "-", date.Syd_lt$mon + 1, "-", date.Syd_lt$mday) ==
+ paste0(date.Ldn_lt$year + 1900, "-", date.Ldn_lt$mon + 1, "-", date.Ldn_lt$mday)
[1] TRUE
如果转换为Date
,则会丢失时区信息。
正如?Sys.Date
所说的
"日期"返回当前时区中的当前日期。
因此,在给定的时间点,它可能会根据您所在的时区返回不同的值。
> Sys.setenv(TZ="Australia/Sydney")
> d <- Sys.Date()
> d
[1] "2012-12-11"
> Sys.setenv(TZ="America/Los_Angeles")
> Sys.Date()
[1] "2012-12-10"
> d
[1] "2012-12-11"
相反,您可以使用包含时区信息的Sys.time()
,因为它是POSIXct
> Sys.setenv(TZ="America/Los_Angeles")
> .POSIXct(Sys.time(), tz='America/Los_Angeles')
[1] "2012-12-10 18:01:26.667964 PST"
> .POSIXct(Sys.time(), tz='Australia/Sydney')
[1] "2012-12-11 13:01:26.668636 EST"
> Sys.setenv(TZ="Australia/Sydney")
> .POSIXct(Sys.time(), tz='America/Los_Angeles')
[1] "2012-12-10 18:01:26.669352 PST"
> .POSIXct(Sys.time(), tz='Australia/Sydney')
[1] "2012-12-11 13:01:26.669907 EST"
IMO,POSIXlt
通常应该避免,但如果你真的想,你可以转换为POSIXlt
> Sys.setenv(TZ="America/Los_Angeles")
> as.POSIXlt(Sys.time(), tz='America/Los_Angeles')
[1] "2012-12-10 18:09:27.135976 PST"
> as.POSIXlt(Sys.time(), tz='Australia/Sydney')
[1] "2012-12-11 13:09:27.137197 EST"
> Sys.setenv(TZ="Australia/Sydney")
> as.POSIXlt(Sys.time(), tz='America/Los_Angeles')
[1] "2012-12-10 18:09:27.138371 PST"
> as.POSIXlt(Sys.time(), tz='Australia/Sydney')
[1] "2012-12-11 13:09:27.13928 EST"
我找到的让datetime函数在输入时识别"tz"参数的唯一方法是在使用as.POSIXct:之前使用as.PPOSIXlt
> date.p5 <- as.POSIXct( as.POSIXlt(Sys.time(), tz = 'GMT+5'))
> date.m5 <- as.POSIXct( as.POSIXlt(Sys.time(), tz = 'GMT-5'))
> date.p5
[1] "2012-12-11 01:02:51 GMT"
> date.m5
[1] "2012-12-11 11:03:05 GMT"
> date.m5C <- as.POSIXct(Sys.time(), tz = 'GMT-5')
> date.m5C
[1] "2012-12-10 22:08:19 PST"
> date.p5C <- as.POSIXct(Sys.time(), tz = 'GMT+5')
> date.p5C
[1] "2012-12-10 22:08:44 PST"
> date.l0PST <- as.POSIXlt(Sys.time(), tz = 'PST')
> date.l0PST
[1] "2012-12-11 06:15:31 UTC" # My clock reads 22:15:31 Pacific (US) Standard Time
> date.c0PST <- as.POSIXct(Sys.time(), tz = 'PST')
> date.c0PST
[1] "2012-12-10 22:15:42 PST"