R 方法通过将整个数据集向上移动半年 hour/down 小时来将标准时间转换为夏令时?

R method to shift standard to daylight savings time by shifting entire dataset up an hour/down an hour for half the year?

有很多关于夏令时转换和 posixct/posixlt、date.time 等的问题,但我发现 none 似乎解决了我的夏令时方法储蓄。

我对分析能源使用的每日负载曲线很感兴趣,只是从数据集中删除 spring 小时的方法对我不起作用。我需要一种方法,将所有测量值转移到 spring 夏令时后的下一小时和秋季调整后的前一小时。请参阅下面的清晰示例。


EnergyUse <- data.table("Date"= c("1997-04-06", "1997-04-06", "1997-04-06", "1997-04-06"), "Hour"= 1:4, "Power"=c(30,40,60,80))

print(EnergyUse)
#             Date   Hour     Power
#1:     1997-04-06      1        30
#2:     1997-04-06      2        40 #when daylight savings kicked in for 1997
#3:     1997-04-06      3        60
#4:     1997-04-06      4        80

“小时”字段的范围为 0 到 23,表示一年中的每一天,即“本地标准时间”。正如您将在下面看到的,它恰好是太平洋时间,但对于实施夏令时的任何时区,我都会有同样的问题。

现在我需要将日期和时间字段合并到单个 date_time 字段中,格式设置为日期和时间并结合夏令时,因为我对每小时的功率模式(即负载曲线)感兴趣,它改变了两者基于相对时间(例如人们 to/get 下班的时间)和绝对时间(例如 cold/hot 或太阳落山的时间)。

EnergyUseAdj <- EnergyUse[, Date_Time := as.POSIXct(paste(Date, Hour), format="%Y-%m-%d %H", tz="America/Los_Angeles")]

这导致:

print(EnergyUseAdj)

#         Date Hour  Power            Date_Time
#1: 1997-04-06    1     30  1997-04-06 01:00:00
#2: 1997-04-06    2     40                 <NA>
#3: 1997-04-06    3     60  1997-04-06 03:00:00
#4: 1997-04-06    4     80  1997-04-06 04:00:00

然而,这使得新的夏令时凌晨 3 点和凌晨 4 点的“功率”数据不正确。夏令时调整后的凌晨 3 点的实际发电量数据将改为标准时间凌晨 2 点列出的数据(即 40),而凌晨 4 点的数据则为 60。

对此进行调整的正确方法是在 spring 中通过 1 小时的正偏移量和 1 小时的负偏移量来调整整个时间序列,尽管对于大型数据集来说可能计算量更大秋天的小时,如下所示:

#         Date Hour  Power            Date_Time
#1: 1997-04-06    1     30  1997-04-06 01:00:00
#2: 1997-04-06    2   <NA>                 <NA>
#3: 1997-04-06    3     40  1997-04-06 03:00:00
#4: 1997-04-06    4     60  1997-04-06 04:00:00

或者,由于缺少 NA 行,在其他算法中使用可能更顺畅,如下所示:

#         Date Hour  Power            Date_Time
#1: 1997-04-06    1     30  1997-04-06 01:00:00
#2: 1997-04-06    3     40  1997-04-06 03:00:00
#3: 1997-04-06    4     60  1997-04-06 04:00:00
#4: 1997-04-06    5     80  1997-04-06 05:00:00

在玩弄 Posixct 并阅读了一堆关于此调整的类似问题之后,我找不到很好的解决方案。有什么想法吗?

编辑:GregorThomas 的请求,如果您想使用两天的数据,请参阅下面的更大样本数据。

#       OP_DATE OP_HOUR Power
# 1: 1997-04-05       0    71
# 2: 1997-04-05       1    61
# 3: 1997-04-05       2    54
# 4: 1997-04-05       3    57
# 5: 1997-04-05       4    68
# 6: 1997-04-05       5    76
# 7: 1997-04-05       6    89
# 8: 1997-04-05       7   106
# 9: 1997-04-05       8   148
#10: 1997-04-05       9   154
#11: 1997-04-05      10   143
#12: 1997-04-05      11   123
#13: 1997-04-05      12   105
#14: 1997-04-05      13    94
#15: 1997-04-05      14    85
#16: 1997-04-05      15    86
#17: 1997-04-05      16    84
#18: 1997-04-05      17    83
#19: 1997-04-05      18    99
#20: 1997-04-05      19   105
#21: 1997-04-05      20    94
#22: 1997-04-05      21    95
#23: 1997-04-05      22    81
#24: 1997-04-05      23    66
#25: 1997-04-06       0    75
#26: 1997-04-06       1    70
#27: 1997-04-06       2    62
#28: 1997-04-06       3    56
#29: 1997-04-06       4    55
#30: 1997-04-06       5    57
#31: 1997-04-06       6    51
#32: 1997-04-06       7    57
#33: 1997-04-06       8    59
#34: 1997-04-06       9    61
#35: 1997-04-06      10    64
#36: 1997-04-06      11    63
#37: 1997-04-06      12    63
#38: 1997-04-06      13    63
#39: 1997-04-06      14    60
#40: 1997-04-06      15    68
#41: 1997-04-06      16    69
#42: 1997-04-06      17    69
#43: 1997-04-06      18    91
#44: 1997-04-06      19   120
#45: 1997-04-06      20   100
#46: 1997-04-06      21    74
#47: 1997-04-06      22    56
#48: 1997-04-06      23    55

如果您的数据是可靠的每小时,您可以计算出适当长度的小时序列。 POSIX 日期时间的实现考虑了夏令时、闰年等

在我的评论中简化方法,我建议根据开始时间和长度计算序列。

EnergyUseAdj <- EnergyUse[,
  Date_Time := seq(
    from = as.POSIXct(paste(Date[1], Hour[1]), format="%Y-%m-%d %H", tz="America/Los_Angeles"),
    length.out = .N,
    by = "1 hour"
  )]