【问题标题】:Convert time duration (BigDecimal value + time units) to milliseconds long将持续时间(BigDecimal 值 + 时间单位)转换为毫秒长
【发布时间】:2017-12-06 13:50:30
【问题描述】:

我必须创建一个具有 2 个输入参数的函数: Time duration 在 BigDecimal 中(精度 38,小数位数 6) 和 TimeUnitsType enum(天、小时、分钟或秒)。

结果我需要得到long 值(毫秒); 据我了解,BigDecimal 中的 longValue() 方法在这里无法精确工作,因为它将比例设置为 0,longValueExact() 将抛出 ArithmeticException("Overflow")(因为精度 - 比例 > 19)

public static long convertTimeToMillis(BigDecimal time, TimeUnitsType timeUnitsType) {
    long timeLong = time.longValue();
    switch (timeUnitsType) {
        case DAYS:
            return TimeUnit.DAYS.toMillis(timeLong);
        case HOURS:
            return TimeUnit.HOURS.toMillis(timeLong);
        case MINUTES:
            return TimeUnit.MINUTES.toMillis(timeLong);
        default:
            return TimeUnit.SECONDS.toMillis(timeLong);
    }
}

所以我需要对每种情况分别进行单独计算。你能帮我么? BigDecimal 操作让我有点害怕,因为我之前没有使用过它们 :) 并且在其余任务中需要精度。

附: Java版本是1.6

【问题讨论】:

  • 请准确定义BigDecimal time 所代表的内容。 time 的持续时间是timeUnitsType 的单位还是time 在它自己的单位中并被转换为timeUnitsType 中的等效持续时间?

标签: java converter long-integer bigdecimal duration


【解决方案1】:

如果timetimeUnitsType 为单位,并且您将该时间(以它的单位)转换为毫秒,那么总是有可能发生溢出。 long 不能容纳超过 19 位,而在这里你可以有 32 位 6 位小数以秒为单位,将其转换为毫秒将使其达到 35 位。 32 位数天到毫秒甚至更糟...

您确定需要在几毫秒内将其TimeUnit 中的BigDecimal 转换为单个long

BigDecimal.longValueExact() 会在丢失任何信息时抛出异常。因此,如果您检查该异常并进行处理,那么我想一切都会好起来的。

【讨论】:

  • 是的,我这里需要转换成millis(这是一个要求),因为还有很多进一步的计算,应该有一个单一的格式。据我了解 - 我可以使用 longValueExact() 结果将其异常包装到我的自定义异常中,对吧?
  • 是的,如果有任何信息丢失,BigDecimal.longValueExact() 将抛出异常。因此,如果您检查该异常并进行处理,那么我想一切都会好起来的。
  • 谢谢,我会检查这是否正常工作。如果是这样,这当然是最简单的解决方案。
  • @alexkov 如果这回答了您的问题,那么“接受”将不胜感激。
【解决方案2】:

您在传入值中允许最多 6 个小数位是有原因的,因此您不能忽略它们。自己进行转换,创建一个保留小数位的新 BigDecimal。一旦你有毫秒,四舍五入 BigDecimal。最后,将 BigDecimal 与 Long.MAX_VALUE 和 MIN_VALUE 进行比较。如果超出这些范围,则抛出异常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多