在处理POSIXct时区和截断POSIXct对象的时间方面有困难

时间:2022-10-28 20:55:07

I have the following piece of R-code:

我有以下的R-code:

formatString = "%Y-%m-%d %H:%M:%OS"
x = as.POSIXct(strptime("2013-11-23 23:10:38.000000", formatString))
y = as.POSIXct(strptime("2015-07-17 01:43:38.000000", formatString))

I have the problem that when I do as.Date(y) then I get 2015-07-16 (although its date is one day later!). Apparently the problem is the timezone. So I checked the timezones:

我有一个问题,当我做的时候。日期(y)然后我得到了2015-07-16(尽管它的日期是一天后!)显然问题出在时区上。所以我检查了时区:

> x
[1] "2013-11-23 23:10:38 CET"
> y
[1] "2015-07-17 01:43:38 CEST"
> 

Ok, so they deviate in their timezone. This is weird, because why does R decide that one timestamp (given without any timezone at all) lies in a different timezone than another (given without any timezone at all)?

所以他们在时区上有偏差。这很奇怪,因为为什么R决定一个时间戳(没有任何时区)位于另一个时区(没有任何时区)?

Ok, so lets set the timezone. Googling revealed that attr(y, "tzone") <- "CET" should do the deal. Lets try this:

我们来设置时区。谷歌搜索显示,attr(y,“tzone”)<-“CET”应该完成交易。让我们试试这个:

> attr(y, "tzone") <- "CET"
> y
[1] "2015-07-17 01:43:38 CEST"
> 

Ok, that did not work. Let see what the timezone actually is in the beginning:

好吧,这行不通。让我们看看开始时的时区是什么:

> formatString = "%Y-%m-%d %H:%M:%OS"
> x = as.POSIXct(strptime("2013-11-23 23:10:38.000000", formatString))
> y = as.POSIXct(strptime("2015-07-17 01:43:38.000000", formatString))
> unclass(x)
[1] 1385244638
attr(,"tzone")
[1] ""
> unclass(y)
[1] 1437090218
attr(,"tzone")
[1] ""
> 

So... they dont have a timezone at all but their timezones are different????

所以…他们根本没有时区,但他们的时区不同。

--> here are my natural questions:

——>这是我的自然问题:

1) why are they initialized with a different timezone when I dont specify a timezone at all?

1)当我根本没有指定时区时,为什么要用不同的时区初始化它们?

2) why do both objects apparently not have a timezone and at the same time... how come they have different timezones?

为什么这两个物体都没有时区,同时……为什么他们有不同的时区?

3) How can I make as.Date(y) == "2015-07-17" true? I.e. how can I set both to the current timezone? Sys.timezone() results in 'NA'... (EDIT: my timezone [Germany] seems to be "CET" --> how can I set both to CET?)

3)我怎样才能使as.Date(y) =“2015-07-17”为真?例如,如何将两者都设置为当前时区?Sys.timezone()会导致“NA”……(编辑:我的时区[德国]似乎是“CET”——>我如何将两者都设为CET?)

I'm scratching my head here... Thanks for any thoughts on this you share with me :-)

我在这里挠头……谢谢你对这一点的任何想法与我分享:

FW

弗兰克-威廉姆斯

2 个解决方案

#1


2  

If you don't specify a timezone then R will use your system's locale as POSIXct objects must have a timezone. The difference between CEST and CET is that one is summertime and one is not. That means if you define a date during the part of the year defined as summertime then R will decide to use the summertime version of the timezone. If you want to set dates that don't use summertime versions then define them as GMT from the beginning.

如果不指定时区,那么R将使用系统的locale,因为POSIXct对象必须有时区。CEST和CET的区别在于一个是夏季,另一个不是夏季。这意味着如果你在一年中的某段时间内定义一个日期,那么R将决定使用时区的夏季版本。如果你想设置不使用夏季版本的日期,那么从一开始就把它们定义为GMT。

formatString = "%Y-%m-%d %H:%M:%OS"
x = as.POSIXct(strptime("2013-11-23 23:10:38.000000", formatString), tz="GMT")
y = as.POSIXct(strptime("2015-07-17 01:43:38.000000", formatString), tz="GMT")

If you want to truncate out the time, don't use as.Date on a POSIXct object since as.Date is meant to convert character objects to Date objects (which aren't the same as POSIXct objects). If you want to truncate POSIXct objects with base R then you'll have to wrap either round or trunc in as.POSIXct but I would recommend checking out the lubridate package for dealing with dates and times (specifically POSIXct objects).

如果你想要缩短时间,不要使用as。在POSIXct对象上的日期。Date是指将字符对象转换为日期对象(与POSIXct对象不同)。如果要截断以R为底的POSIXct对象,则必须将圆形或trunc封装为as。但是我建议您检查处理日期和时间(特别是POSIXct对象)的lubridate包。

If you want to keep CET but never use CEST you can use a location that doesn't observe daylight savings. According to http://www.timeanddate.com/time/zones/cet your only options are Algeria and Tunisia. According to https://en.wikipedia.org/wiki/List_of_tz_database_time_zones the valid tz would be "Africa/Algiers". Therefore you could do

如果你想保留CET,但不要使用CEST,你可以使用一个不观察日光节约的地方。根据http://www.timeanddate.com/time/zones/cet,你唯一的选择是阿尔及利亚和突尼斯。根据https://en.wikipedia.org/wiki/list_of_tz_database_time_zone,有效的tz将是“非洲/阿尔及尔”。所以你能做的

 formatString = "%Y-%m-%d %H:%M:%OS"
x = as.POSIXct(strptime("2013-11-23 23:10:38.000000", formatString), tz="Africa/Algiers")
y = as.POSIXct(strptime("2015-07-17 01:43:38.000000", formatString), tz="Africa/Algiers")

and both x and y would be in CET.

x和y都在CET中。

One more thing about setting timezones. If you tell R you want a generic timezone then it won't override daylight savings settings. That's why setting attr(y, "tzone") <- "CET" didn't have the desired result. If you did attr(y, "tzone") <- "Africa/Algiers" then it would have worked as you expected. Do be careful with conversions though because when you change the timezone it will change the time to account for the new timezone. The package lubridate has the function force_tz which changes the timezone without changing the time for cases where the initial timezone setting was wrong but the time was right.

关于设置时区还有一件事。如果你告诉R你想要一个通用时区,那么它不会覆盖夏令时设置。这就是为什么设置attr(y,“tzone”)<-“CET”没有得到想要的结果。如果你做了attr(y,“tzone”)<-“Africa/Algiers”,那么它就会像你期望的那样工作。但是要注意转换,因为当您更改时区时,它将更改时间以考虑新的时区。包润滑具有函数force_tz,它可以更改时区,而不需要更改初始时区设置错误的时间,但是时间是正确的。

#2


1  

Complementary answer:

补充回答:

1) Just use the right timezone throughout from the beginning. Since I live in Hamburg, Germany, the right timezone for me is "Europe/Berlin", see this list as said by Dean.

1)从一开始就使用合适的时区。因为我住在德国汉堡,对我来说,合适的时区是“欧洲/柏林”,看看迪安说的这个列表。

2) For extracting information from POSIXct, for example, the date, I use

2)为了从POSIXct中提取信息,例如我使用的日期

as.Date(format(timeStamp, "%Y-%m-%d"))

which is slow but seems to give the correct answer... plus I dont have to install new packages [which is a bit complicated in my situation].

这是缓慢的,但似乎给出了正确的答案……另外,我不需要安装新的软件包(这在我的情况下有点复杂)。

#1


2  

If you don't specify a timezone then R will use your system's locale as POSIXct objects must have a timezone. The difference between CEST and CET is that one is summertime and one is not. That means if you define a date during the part of the year defined as summertime then R will decide to use the summertime version of the timezone. If you want to set dates that don't use summertime versions then define them as GMT from the beginning.

如果不指定时区,那么R将使用系统的locale,因为POSIXct对象必须有时区。CEST和CET的区别在于一个是夏季,另一个不是夏季。这意味着如果你在一年中的某段时间内定义一个日期,那么R将决定使用时区的夏季版本。如果你想设置不使用夏季版本的日期,那么从一开始就把它们定义为GMT。

formatString = "%Y-%m-%d %H:%M:%OS"
x = as.POSIXct(strptime("2013-11-23 23:10:38.000000", formatString), tz="GMT")
y = as.POSIXct(strptime("2015-07-17 01:43:38.000000", formatString), tz="GMT")

If you want to truncate out the time, don't use as.Date on a POSIXct object since as.Date is meant to convert character objects to Date objects (which aren't the same as POSIXct objects). If you want to truncate POSIXct objects with base R then you'll have to wrap either round or trunc in as.POSIXct but I would recommend checking out the lubridate package for dealing with dates and times (specifically POSIXct objects).

如果你想要缩短时间,不要使用as。在POSIXct对象上的日期。Date是指将字符对象转换为日期对象(与POSIXct对象不同)。如果要截断以R为底的POSIXct对象,则必须将圆形或trunc封装为as。但是我建议您检查处理日期和时间(特别是POSIXct对象)的lubridate包。

If you want to keep CET but never use CEST you can use a location that doesn't observe daylight savings. According to http://www.timeanddate.com/time/zones/cet your only options are Algeria and Tunisia. According to https://en.wikipedia.org/wiki/List_of_tz_database_time_zones the valid tz would be "Africa/Algiers". Therefore you could do

如果你想保留CET,但不要使用CEST,你可以使用一个不观察日光节约的地方。根据http://www.timeanddate.com/time/zones/cet,你唯一的选择是阿尔及利亚和突尼斯。根据https://en.wikipedia.org/wiki/list_of_tz_database_time_zone,有效的tz将是“非洲/阿尔及尔”。所以你能做的

 formatString = "%Y-%m-%d %H:%M:%OS"
x = as.POSIXct(strptime("2013-11-23 23:10:38.000000", formatString), tz="Africa/Algiers")
y = as.POSIXct(strptime("2015-07-17 01:43:38.000000", formatString), tz="Africa/Algiers")

and both x and y would be in CET.

x和y都在CET中。

One more thing about setting timezones. If you tell R you want a generic timezone then it won't override daylight savings settings. That's why setting attr(y, "tzone") <- "CET" didn't have the desired result. If you did attr(y, "tzone") <- "Africa/Algiers" then it would have worked as you expected. Do be careful with conversions though because when you change the timezone it will change the time to account for the new timezone. The package lubridate has the function force_tz which changes the timezone without changing the time for cases where the initial timezone setting was wrong but the time was right.

关于设置时区还有一件事。如果你告诉R你想要一个通用时区,那么它不会覆盖夏令时设置。这就是为什么设置attr(y,“tzone”)<-“CET”没有得到想要的结果。如果你做了attr(y,“tzone”)<-“Africa/Algiers”,那么它就会像你期望的那样工作。但是要注意转换,因为当您更改时区时,它将更改时间以考虑新的时区。包润滑具有函数force_tz,它可以更改时区,而不需要更改初始时区设置错误的时间,但是时间是正确的。

#2


1  

Complementary answer:

补充回答:

1) Just use the right timezone throughout from the beginning. Since I live in Hamburg, Germany, the right timezone for me is "Europe/Berlin", see this list as said by Dean.

1)从一开始就使用合适的时区。因为我住在德国汉堡,对我来说,合适的时区是“欧洲/柏林”,看看迪安说的这个列表。

2) For extracting information from POSIXct, for example, the date, I use

2)为了从POSIXct中提取信息,例如我使用的日期

as.Date(format(timeStamp, "%Y-%m-%d"))

which is slow but seems to give the correct answer... plus I dont have to install new packages [which is a bit complicated in my situation].

这是缓慢的,但似乎给出了正确的答案……另外,我不需要安装新的软件包(这在我的情况下有点复杂)。