【问题标题】:Display time inside a clock time after performing mathematical operations执行数学运算后在时钟时间内显示时间
【发布时间】:2017-06-24 18:12:52
【问题描述】:

我创建了一个从 00:00:00 hrs23:00:00 hrs 的时间序列。添加任何小时数都很容易,直到总和小于或等于 23:00:00 小时。总和超过 23:00:00 后,它开始以天数显示时间,这非常直观。但我希望在时钟时间内输出,无论我是做减法还是加法

假设我想像下面那样做加法

library(chron)
times("23:00:00")+ times("01:00:00")
Time in days:
[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 中打印时间和日期如果有什么对您没有意义,请告诉我,而不是对我的问题投反对票。

【问题讨论】:

  • 您是否尝试过定义as.POSIXct( format = "%Y-%m-%d %H:%M:%S")。将年、月、日保留为 0,但对其进行初始化。它将帮助您保持跟踪。在 R 中还有一个 difftime 函数,它减去两个日期时间之间的时间。我会使用它而不是减去它。
  • times 定义在哪里?
  • @nrussell 它在 chron 库中
  • @Dinesh.hmn 我的目的不是测量时差。

标签: r datetime time time-series


【解决方案1】:

请注意,chron 包的 times 在内部将时间表示为数值(十进制天数)。您要做的是保留小数点后的值并删除它之前的整数。这可以通过将模数乘以 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 对象添加时间间隔,只需添加以秒为单位的时间间隔。

要将 1 小时添加到“23:00:00”,您可以这样做

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"

【讨论】:

    【解决方案2】:

    您可以轻松使用lubridate 包。

    • 添加每个包裹在hms() 中的时间字符串,将其转换为时间格式。
    • 通过添加任何没有时间的日期来克服 24 小时制挑战(例如,today())。
    • 结果时间(忽略日期)将是您所追求的。

    例子:

    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"
    

    【讨论】:

      【解决方案3】:

      如果你真的想改变时间在变量中的存储方式,使它们在 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 将向您展示此函数是如何在包中编写的。你可以做一个简单的调整来得到你想要的(注意我还在这篇文章的末尾包含了编辑函数的完整代码,所以你可以复制/粘贴而不是自己更改它):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,该方法的原始功能仍然可用。

      print.times = function (x, digits, quote = FALSE, prefix = "", simplify, normalise = TRUE, ...) 
      {
        if (normalise) x = x-floor(x)
        if (!as.logical(length(x))) {
          cat("times(0)\n")
          return(invisible(x))
        }
        if (missing(simplify) && is.null(simplify <- getOption("chron.simplify"))) 
          simplify <- FALSE
        xo <- x
        if (all(is.na(x)) || any(x[!is.na(x)] >= 1)) 
          cat("Time in days:\n")
        x <- format.times(x, simplify = simplify)
        NextMethod("print", quote = quote)
        invisible(xo)
      }
      environment(print.times) <- environment(chron:::print.times)
      

      【讨论】:

        【解决方案4】:

        对于加法和减法,您只需要保留结果的小数部分,丢弃整数部分。很容易编写简单的函数来做到这一点。

        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
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-06-16
          • 2019-06-14
          • 1970-01-01
          • 2019-05-06
          • 1970-01-01
          相关资源
          最近更新 更多