【问题标题】:Convert milli seconds to day-normalized javax.xml.datatype.Duration将毫秒转换为日标准化 javax.xml.datatype.Duration
【发布时间】:2020-12-14 06:59:10
【问题描述】:

我需要转换以毫秒为单位的持续时间 => 输入 javax.xml.datatype.Duration。 该类型的问题在于,它使用年和月作为字段(其持续时间取决于当前时间戳)。

话虽如此,我想将javax.xml.datatype.Duration 标准化为仅包含天数(编辑:当然,还有小时、分钟……)。 这可能是这样的:

private static Duration millis2Duration(final long millis) throws DatatypeConfigurationException {
    Duration duration = DatatypeFactory.newInstance().newDuration(millis);
    GregorianCalendar cal = new GregorianCalendar();
    cal.setTimeInMillis(0);
    return duration.normalizeWith(cal);
}

但是为了标准化持续时间而创建日历似乎很奇怪。我是否遗漏了什么,或者这是进行此转换的最佳方式?

【问题讨论】:

    标签: java xml duration


    【解决方案1】:

    tl;博士

    java.time.Duration.ofMillis( m ).toDaysPart()
    

    避免使用旧的日期时间类型

    您正在使用糟糕的日期时间类,这些类在几年前已被现代 java.time 类所取代。切勿使用CalendarGregorianCalendarjava.util.Date 等。

    java.time.Duration

    使用java.time.Duration 而不是javax.xml.datatype.Duration

    Duration duration = Duration.ofMillis( yourCountOfMillisecondsGoesHere ) ;
    

    显然,您想要计算通用的 24 小时天数,而不考虑日期。 java.time.Duration 类可以give you that

    long countOf24HourDays = duration.toDaysPart() ;
    

    您无需创建自己的正式方法。无论您需要它,只需使用:

    Duration.ofMillis( m ).toDaysPart()
    

    关于java.time

    java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.DateCalendarSimpleDateFormat

    要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310

    Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

    您可以直接与您的数据库交换 java.time 对象。使用符合JDBC 4.2 或更高版本的JDBC driver。不需要字符串,不需要java.sql.* 类。 Hibernate 5 & JPA 2.2 支持 java.time

    从哪里获取 java.time 类?

    【讨论】:

    • 我明确要求 javax.xml.datatype。我无法选择另一种数据类型。另外: Duration#toDaysPart 只返回平淡的日子?!编辑:啊,好吧,对不起。我编辑了上面的描述。持续时间当然还应包含小时、分钟、...
    【解决方案2】:

    在需要 javax.xml.datatype.Duration 时也使用 java.time

    我明确要求 javax.xml.datatype。它不在我的手中 选择其他数据类型。

    java.time.Duration 转换为javax.xml.datatype.Duration 来满足您的要求可能并非易事,但我仍然更喜欢它,因为它是获得您想要的东西的最容易理解和最安全的方式。

        long millis = 21_098_765_432L;
    
        boolean positive = millis > 0;
        java.time.Duration javaTimeDuration = java.time.Duration.ofMillis(millis);
        if (! positive) {
            javaTimeDuration = javaTimeDuration.negated();
        }
        BigDecimal seconds = BigDecimal.valueOf(javaTimeDuration.toSecondsPart())
                .add(BigDecimal.valueOf(javaTimeDuration.getNano(), 9))
                .stripTrailingZeros();
        Duration dur = DatatypeFactory.newInstance().newDuration(
                positive,
                null,
                null,
                BigInteger.valueOf(javaTimeDuration.toDays()),
                BigInteger.valueOf(javaTimeDuration.toHoursPart()),
                BigInteger.valueOf(javaTimeDuration.toMinutesPart()),
                seconds);
    
        System.out.println(dur);
    

    这个 sn-p 的输出是:

    P244DT4H46M5.432S

    我喜欢这段代码的地方在于,它明确地使用了天、小时、分钟和秒,包括 java.time 持续时间的几分之一秒,并构造了一个没有年月的 XML 持续时间。

    一些麻烦来自于这样一个事实,将秒的小数部分传递给工厂方法的唯一方法是通过BigIntegerBigDecimal。所以我首先构建了一个BigDecimal 保存秒和秒的分数。

    我正在使用的 toHoursParttoMinutesParttoSecondsPart 方法是在 Java 9 中添加的。

    链接

    Oracle tutorial: Date Time 解释如何使用 java.time。

    【讨论】:

      猜你喜欢
      • 2019-12-24
      • 1970-01-01
      • 1970-01-01
      • 2010-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-05
      • 2011-06-08
      相关资源
      最近更新 更多