date - 是否有日期/时间间隔格式的名称,例如“1h10m”

标签 date datetime duration dateinterval

即使在软件外部,以截断的方式交流时间或日期间隔也是很平常的事。例如:1h10m转换为“一小时十分钟”。

这可以抽象为一组规则。例如:日期间隔表示为_h_m和(等等)的组合,其中_字符表示非负整数或浮点数,它们被加到一个日期间隔对象中。

允许混合天,小时,分钟。例如,0.5d1h60m将是14h的同义词。

是否有类似的地方定义了这样的标准?

最佳答案

其标准是ISO 8601持续时间
请注意,间隔是一个不同的概念(也由同一ISO定义),尽管两者密切相关:

  • 持续时间定义了量的时间(例如“1小时10分钟”或“2年3个月零4天”)。但是它不会告诉您何时开始或结束(相对于什么时间是“1小时10分钟”)。只是时间本身。
  • 间隔(引用Wikipedia)是“两个时间点之间的间隔时间”。它具有定义的开始日期和结束日期,但是您可以使用持续时间来定义它,因为它可以有4种不同的格式:
  • 开头和结尾,例如2007-03-01T13:00:00Z/2008-05-11T15:30:00Z
  • 开始和持续时间,例如2007-03-01T13:00:00Z/P1Y2M10DT2H30M
  • 持续时间和结束时间,例如P1Y2M10DT2H30M/2008-05-11T15:30:00Z
  • 仅持续时间,例如P1Y2M10DT2H30M和其他上下文信息

  • 情况1、2和3是等效的(都具有相同的开始和结束日期)。唯一的区别是,在情况2和3中,持续时间P1Y2M10DT2H30M用于计算另一个日期(在情况2中,您将其添加到开始日期,在情况3中,您将其从结束日期中减去)。



    如上文所述,持续时间的标准格式为P[n]Y[n]M[n]DT[n]H[n]M[n]S,其中:
  • P是放置在持续时间表示开始处的持续时间指示符(用于周期)。
  • Y是跟随年份值的年份指示符。
  • M是跟随月份数的月份指示符。
  • W是跟随星期数的值的星期指示符。
  • D是遵循天数值的日期指示符。
  • T是表示形式的时间成分之前的时间指示符。
  • H是小时数标记,它跟随小时数的值。
  • M是分钟标记,紧随分钟数的值。
  • S是第二个跟随该秒数的指示符。

  • 因此,“1年零10个月”表示为P1Y10M,“1小时10分钟”表示为PT1H10M(请注意,为了解决1个月(T)和1分钟(P1M)之间的潜在歧义,需要PT1M使用与指示符相同的字母M)。

    正如@MattJohnson所说,带有日期的数学并不总是很明显,因此不同持续时间之间的等效性不是我们通常期望的。

    对于下面的示例,我正在使用Java 8(只是为了说明持续时间如何变得棘手)。请注意,java.time API使用2个不同的类(PeriodDuration),但是两者的想法是相同的(它们都是时间量)。
  • 一个月的持续时间等于多少天?这取决于:

    // one month period
    Period oneMonth = Period.parse("P1M");
    // January 1st
    LocalDate jan = LocalDate.of(2016, 1, 1);
    System.out.println(jan); // 2016-01-01
    // January 1st plus 1 month period = February 1st
    LocalDate feb = jan.plus(oneMonth);
    System.out.println(feb); // 2016-02-01
    // February 1st plus 1 month period = March 1st
    LocalDate mar = feb.plus(oneMonth);
    System.out.println(mar); // 2016-03-01
    
    // difference between Jan 1st and Feb 1st = 31 days
    System.out.println(ChronoUnit.DAYS.between(jan, feb)); // 31
    // difference between Feb 1st and Mar 1st = 29 days (2016 is leap year)
    System.out.println(ChronoUnit.DAYS.between(feb, mar)); // 29
    

  • 因此,在2月1日的1月1日结果中添加1个月-在这种情况下,1个月等于31天(又名添加1个月的持续时间(P1M)等于添加31天的持续时间(P31D)),然后添加1月到2月1日的结果是3月1日(在这种情况下,1个月= 29天,因为2016年是a年)。
  • 1天= 24小时?不总是。如果涉及到Daylight Saving Time转换,您会得到奇怪的结果:

    // 1 day period
    Period oneDay = Period.parse("P1D");
    // 24 hours period
    Duration twentyFourHours = Duration.parse("PT24H");
    // in Sao Paulo, summer time starts at Oct 15, at midnight
    // getting a date one day before DST change, at 10:00 AM
    ZonedDateTime z = ZonedDateTime.of(2017, 10, 14, 10, 0, 0, 0, ZoneId.of("America/Sao_Paulo"));
    System.out.println(z); // 2017-10-14T10:00-03:00[America/Sao_Paulo]
    
    // add 1 day - gets the same hour (10:00 AM)
    System.out.println(z.plus(oneDay)); // 2017-10-15T10:00-02:00[America/Sao_Paulo]
    
    // add 24 hours - gets 11:00 AM because of DST shift (at midnight, clocks moved forward 1 hour)
    System.out.println(z.plus(twentyFourHours)); // 2017-10-15T11:00-02:00[America/Sao_Paulo]
    

  • 2017年10月15日,在圣保罗,DST开始(时钟向前移动1小时),因此:
  • 如果您在10月14日上午10点将 24小时添加到10月14日,则您将在10月15日上午 11月
  • 但是,如果您添加 1天,您将在10月15日获得 10 AM

  • 因此,在这种情况下,1天= 23小时-,这意味着添加1天的持续时间(P1D)等同于添加23小时的持续时间(PT23H)

    DST结束后,情况恰好相反:时钟向后移1小时,而1天等于25小时。

    因此,该标准定义了时间概念的格式和含义,但是不同持续时间之间的等效性取决于上下文(尽管听起来不直观的是1天并不总是24小时,但是日期/时间数学却是没有我们想要的那么明显)。

    关于date - 是否有日期/时间间隔格式的名称,例如“1h10m”,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44662242/

    相关文章:

    date - 在 Kotlin 中计算日期

    php - 获取当前季度的开始日期和结束日期 php

    java - 在 Java 中将字符串转换为日期对象

    symfony - 使用 Nemo/Alice 包导入日期时间

    java - Java 和 SQL 中的时间跨度?

    javascript - 使用 JavaScript 获取给定月份的给定工作日

    python - ISO 8601 日期时间格式 : parse 11:05:14 PM into 23:05:14

    c# - Java 中 DateTime.FromOADate() 的等价物是什么(Java 中 Datetime 的两倍)

    go - time.Since() 有月份和年份

    google-sheets - 如何在 Google 表格中求和持续时间?