R语言中不同格式生成的小时时间序列长度为何不一致?
为什么两种小时时间序列的长度会差1?
哈哈,这个差异其实是夏令时(Daylight Saving Time, DST)的时区自动调整在搞鬼!两种方法对时间的处理逻辑完全不同,咱们来拆解清楚:
1. 第一种方法:纯数学的“硬计数”(不管时区/夏令时)
你第一种方法是把日期差转成数值天数,然后按1/24的步长生成序列——本质就是按“天文小时”来算,默认每天固定24小时,完全不管现实中时区因为夏令时切换,会出现“一天23小时”(夏令时开始,时钟拨快1小时)或者“一天25小时”(夏令时结束,时钟拨慢1小时)的情况。
它的计算逻辑就是死算:从first_date_year_start的00:00开始,到date_end的23:00结束,每小时一步,完全不考虑实际时间的时区规则。
2. 第二种方法:跟着时区规则走的“实际时间”
第二种方法用strptime生成带时区的时间对象,再用seq.POSIXt生成序列——这个函数会严格遵循你本地时区的夏令时规则:
- 当夏令时开始时,本地时钟会直接跳过一个小时(比如从2:00跳到3:00),这个不存在的小时会被
seq.POSIXt自动忽略,序列里就少了一个时间点; - 当夏令时结束时,时钟会拨慢1小时,会出现两个相同的本地时间,序列里会多一个时间点。
为什么不同结束日期结果不一样?
- 当你把结束日期设为
2015-10-31时,从1995-1-1到这个日期的时间段里,夏令时开始的次数比结束的次数多1次(或者说有一次净的“小时缺失”),导致seq.POSIXt生成的序列比纯数学计数少1个小时; - 而当结束日期是
2015-1-3时,这段时间正好在冬季(北半球),没有夏令时切换,本地时间每天都是标准的24小时,所以两种方法的计数完全一致。
怎么验证?
你可以用UTC时区来对比(UTC没有夏令时):
- 把第一种方法的数值序列转成UTC时间:
utc_times <- as.POSIXct(julDays_1hstep_simulation_period, origin = first_date_year_start, tz = "UTC") - 把第二种方法的本地时间转成UTC时间:
utc_dates_with_times <- as.POSIXct(dates_with_times_simulation_period, tz = "UTC") - 对比两者的长度,再查看缺失的那个时间点,就能对应到某次夏令时切换事件。
如果想让两种方法生成的序列长度完全一致,最简单的办法就是强制用UTC时区(避开夏令时),修改第二种方法的代码:
# 用as.POSIXct指定UTC时区,代替strptime first_date_year_start_with_time <- as.POSIXct(paste0(first_date_year_start, " 00:00"), tz = "UTC") date_end_with_time <- as.POSIXct(paste0(date_end, " 23:00"), tz = "UTC") dates_with_times_simulation_period <- seq(from = first_date_year_start_with_time, to = date_end_with_time, by = "hour")
这样生成的序列长度就会和第一种方法一模一样啦!
内容的提问来源于stack exchange,提问作者nrj
相关产品推荐
相关产品推荐

