我创建了从 00:00:00 hrs 到 23:00:00 hrs 的时间序列。在总和小于或等于23:00:00之前,添加任意小时数都很容易。总和在23:00:00之后开始显示天数的时间,这非常直观。但我想在时钟时间内输出,无论我是减法还是加法
假设我想添加如下
library(chron)
times("23:00:00")+ times("01:00:00")
Time in days:
[1] 1
我想要的输出低于1。而不是得到我想要的日子
00:00:00
我也试过减法
times("00:00:00")- times("01:00:00")
[1] -0.04166667
所需的输出
"23:00:00"
我也尝试使用 POSIXct ,但它在各种情况下都会出现各种错误
as.POSIXct("00:00:00", format = "%H:%M:%S", tz = "UTC")
[1] "2017-02-07 UTC" #Not printing time. Only dates
使用POSIXct
减法as.POSIXct("00:00:00", format = "%H:%M:%S", tz = "UTC") -as.POSIXct("01:00:00", format = "%H:%M:%S", tz = "UTC")
Time difference of -1 hours
Warning message:
In 1:0:0 : numerical expression has 2 elements: only the first used
使用POSIXct
添加as.POSIXct("23:00:00", format = "%H:%M:%S", tz = "UTC") + as.POSIXct("01:00:00", format = "%H:%M:%S", tz = "UTC")
Error in `+.POSIXt`(as.POSIXct("23:00:00", format = "%H:%M:%S", tz = "UTC"), :
binary '+' is not defined for "POSIXt" objects
请帮我解决这个问题。还请帮我打印上面显示的POSIXct中的时间和日期。如果对你没有任何意义,请告诉我,而不是向我投票。
答案 0 :(得分:3)
请注意,times
包中的chron
在内部将时间表示为数值(十进制天数)。您要做的是保留小数点后面的值并删除它之前的整数。这可以通过将模数乘以1来实现(尝试2.5 %% 1
)。所以,你可以通过times(1)
获取模数,这将消除这一天。
library(chron)
(times("23:00:00")+ times("01:00:00")) %% times(1)
#[1] 00:00:00
> (times("00:00:00") - times("01:00:00")) %% times(1)
#[1] 23:00:00
使用POSIXct
我不想使用POSIXct
,因为POSIXct
因日期和时区而变得复杂。在内部,POSIXct
是某些来源(通常是1970-01-01)的秒数值。因此,如果要向POSIXct
对象添加时间间隔,只需以秒为单位添加该时间间隔。
要向" 23:00:00"添加1小时,您可以
format(as.POSIXct(
as.numeric(as.POSIXct("23:00:00", format = "%H:%M:%S", tz = "UTC")) + 3600,
origin = "1970-01-01", tz = "UTC"), "%H:%M:%S")
#[1] "00:00:00"
减法可以以相同的方式工作
format(as.POSIXct(
as.numeric(as.POSIXct("24:00:00", format = "%H:%M:%S", tz = "UTC")) - 3600,
origin = "1970-01-01", tz = "UTC"), "%H:%M:%S")
#[1] "23:00:00"
答案 1 :(得分:1)
对于加法和减法,您需要的是仅保留结果的小数部分,丢弃整数部分。编写简单的函数很容易做到这一点。
library(chron)
hoursum = function(t1, t2) { t1 + t2 - floor(t1+t2) }
hourdiff = function(t1, t2) { t1 - t2 - floor(t1-t2) }
现在您可以进行所需的所有计算
hoursum(times("23:00:00"), times("01:00:00"))
## [1] 00:00:00
hoursum(times("23:00:00"), times("02:00:00"))
## [1] 01:00:00
hourdiff(times("00:00:00"), times("01:00:00"))
## [1] 23:00:00
hourdiff(times("02:00:00"), times("03:00:00"))
## [1] 23:00:00
hourdiff(times("02:00:00"), times("03:15:00"))
## [1] 22:45:00
答案 2 :(得分:1)
如果你真的想改变时间存储在变量中的方式,以便它们在0到24小时内,那么一个简单的单行函数就足够了:
clock = function(x) x - floor(x)
clock(times("23:00:00") + times("02:00:00"))
# [1] 01:00:00
如果您只想让打印的显示器始终采用24小时格式,那么最简单的方法是编辑类times
对象的S3打印方法。
键入chron:::print.times
将显示如何在包中写入此函数。您可以进行一个简单的调整以获得您想要的内容(请注意,我还在本文末尾包含已编辑函数的完整代码,因此您只需复制/粘贴而不是自己更改):在{{1添加第print.times
行。
测试有效:
x = x-floor(x)
注意,这样做的一个好处是它也可以用于times("00:00:00") - times("01:00:00")
# [1] 23:00:00
times("23:00:00") + times("01:00:00")
# [1] 00:00:00
times("23:00:00") + times("02:00:00")
# [1] 01:00:00
times("3:00:00") - times("22:00:00")
# [1] 05:00:00
和+
以外的操作。例如:
-
请注意,我还在函数中添加了参数sum(c(times("23:00:00"), times("22:00:00"), times("21:00:00"), times("20:00:00")))
# [1] 14:00:00
mean(c(times("23:00:00"), times("22:00:00"), times("21:00:00"), times("20:00:00")))
# [1] 21:30:00
cumsum(c(times("23:00:00"), times("22:00:00"), times("21:00:00"), times("20:00:00")))
# [1] 23:00:00 21:00:00 18:00:00 14:00:00
,以便在打印时指定normalise
时,方法的原始功能仍然可用。
normalise = FALSE
答案 3 :(得分:0)
您可以轻松使用lubridate包。
hms()
中,并转换为时间格式。today()
)来克服24小时时钟挑战。示例:
library(lubridate)
x <- today() + hms("23:00:00") + hms("2:00:00")
format(x, "%H:%M:%S")
#> [1] "01:00:00"
x <- today() + hms("00:00:00") - hms("1:00:00")
format(x, "%H:%M:%S")
#> [1] "23:00:00"