关于R语言中时间类POSIXct和POSIXlt的一点儿学习收获

本文介绍了R语言中的POSIXct和POSIXlt时间类,它们遵循POSIX标准,分别代表协调世界时间和本地时间。POSIXct是秒数表示的时间,而POSIXlt包含了详细的日期和时间组件。文章详细探讨了两者的区别,如数据结构、属性和时区处理,并通过实例展示了它们在处理时间信息时的差异。此外,还讨论了时区设置和一些有趣的实验,揭示了时间转换过程中可能存在的细节问题。
摘要由CSDN通过智能技术生成

什么是“POSIX"

  R语言中有两个时间类对象,POSIXctPOSIXlt。对于我这种非专业的人员来说,看到这个名称是懵的,不知道这是什么单词的首字母缩写。在网上搜了一下才知道。“POSIX”的全称为“Portable Operating System Interface of UNIX” 翻译成中文是“可移植操作系统接口”,POSIX标准定义了操作系统应该为应用程序提供的接口标准。
 “POSIX”是一个IEEE的标准。UNIX系统出来后,出现了各种不同的版本。而计算机程序在不同版本的系统见运行时,出现不兼容的问题。为了解决计算机程序在不同UNIX系统之间的可移植性问题,在1980s诞生了“POSIX”。POSIX规定了一个计算机程序与UNIX系统之间交互的标准。
 在R中,POSIXctPOSIXlt这两个时间类的名称中,POSIX可以看做是一个标签。也就是符合POSIX标准的时间。可以称为“POSIX时间”或者“UNIX时间”。它的定义是从格林威治时间的1970年01月01日00时00分00秒起至现在的总秒数。所以,在R中,如果我们输入
as.numeric(as.POSIXlt("2022-5-1 00:00:00"))
将会得到一个数值
1651334400
 如果我们增加1秒,输入
as.numeric(as.POSIXlt("2022-5-1 00:00:01"))
得到的数值变为
1651334401

POSIXct和POSIXlt的区别

POSIXctPOSIXltltct分别表示“local time”和“calendar time”,是什么意思呢?

  • calendar time是指我们通常意义理解的时间,即公历的多少年多少月多少日
    举个例子看一下:

 在R中,输入a <- as.POSIXlt("2022-5-1 00:00:00"),然后查看a的类型mode(a),得到的输出是
"list"
 输入b <- as.POSIXct("2022-5-1 00:00:00"),然后查看a的类型mode(b),得到的输出是
"numeric"

 也就是说,如果时间是一个POSIXlt类,它的数据结构是list(列表),如果时间是一个POSIXct类,它的数据结构是数字向量。

POSIXlt

POSIXlt类型的日期含有以下列表元素:

sec
0–61: seconds.

min
0–59: minutes.

hour
0–23: hours.

mday
1–31: day of the month

mon
0–11: months after the first of the year.

year
years since 1900.

wday
0–6 day of the week, starting on Sunday.

yday
0–365: day of the year (365 only in leap years).

isdst
Daylight Saving Time flag. Positive if in force, zero if not, negative if unknown.

zone
(Optional.) The abbreviation for the time zone in force at that time: “” if unknown (but “” might also be used for UTC).

gmtoff
(Optional.) The offset in seconds from GMT: positive values are East of the meridian. Usually NA if unknown, but 0 could mean unknown.

所以对于一个POSIXlt的时间,可以通过$来引用它的某个属性,比如:

R命令输出结果意义
a$yday120是一年中的第120天。
a$zone“CST”时区是“中国标准时间”
a$isdst0不使用夏令时
a$gmtoffNA该时区与GMT时区的时间差未知

注:CST可以为如下4个不同的时区的缩写:

  • 美国中部时间:Central Standard Time (USA) UT-6:00
  • 澳大利亚中部时间:Central Standard Time (Australia) UT+9:30
  • 中国标准时间:China Standard Time UT+8:00
  • 古巴标准时间:Cuba Standard Time UT-4:00

在这里应该是指中国标准时间。

POSIXlt类的属性

> attributes(a)
$names
 [1] "sec"    "min"    "hour"   "mday"   "mon"    "year"   "wday"   "yday"   "isdst" 
[10] "zone"   "gmtoff"

$class
[1] "POSIXlt" "POSIXt" 

$tzone
[1] "Asia/Shanghai"

可见,POSIXlt类有3个属性,分别是namesclasstzone

关于时区

查看自己计算机R运行环境的时区,可以
Sys.timezone()Sys.getenv("TZ")
如果返回值是空值,则说明你还没有设置时区。通过Sys.setenv(TZ ="Asia/Shanghai")设置时区,再Sys.getenv("TZ")则得到
"Asia/Shanghai"。其中,Asia/Shanghai是时区的ID,不同时区的ID可以搜“国际时区ID列表”查到。
此时,我们再看
a <- as.POSIXlt("2022-5-1 00:00:00")

POSIXct

POSIXct就是一个长度为1的向量,存储的是自原点以来的秒数。但POSIXct虽然可以进行加减运算,但不能进行乘除运算。这提醒我们,POSIXct存储的仍然不是一个数值型数据,而是POSIXct型。

> a <- as.POSIXct("2022-5-1 00:00:00")
> attributes(a)
$class
[1] "POSIXct" "POSIXt" 

$tzone
[1] ""

可见,POSIXct类型的时间只有classtzone两个属性。

有趣的实验

运行下列命令以及得到的结果

> a <- as.POSIXlt("2022-5-1 00:00:00")
> a$gmtoff
[1] NA

> a <- as.POSIXlt(as.POSIXct("2022-5-1 00:00:00"))
> a$gmtoff
[1] 28800

> attr(a,"tzone")
[1] "Asia/Shanghai" "CST"           "CDT"  #不知道这个"CDT" 是什么

可以看到,将时间字符串转换为时间类时,如果直接转换为POSIXlt类型,则其gmtoff内容为NA;如果先转换为POSIXct,再转换为POSIXlt则其gmtoff内容不是空的。28800 秒正好就是8小时,也就是时区Asia/Shanghai时间与UTC的时间差。

这是为什么?

  事实上,正是这个问题导致我要更深入了解POSIXctPOSIXlt的区别。在比较两个POSIXlt类型的时间元素时(假设是a和b),我发现a==b返回的结果是TRUE,但setequal(a,b)得到的结果就是FALSE,这给我带来了极大的困惑。我想,正在表面上a和b完全一样的背后肯定有隐藏的东西我还没看到。现在我才知道,原来是其中一个时间是经过了POSIXct转换到POSIXlt格式的,而另外一个时间是直接转换为POSIXlt的。他们两个的差就在gmtoff这里。通过在网上搜索学习,解决这个问题,我还是挺欣慰的。当然,这种无知在R高手看来可能有点儿可笑。
问题解决了,我也不想再深入了,浅尝辄止。遇到新的问题再说吧。

更多参考

https://wrangle-r.rsquaredacademy.com/date-and-time-in-r.html

  • 9
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值