【问题标题】:Convert Double to java.sql.Time将 Double 转换为 java.sql.Time
【发布时间】:2019-09-21 22:44:00
【问题描述】:

我正在从 Excel 文件的单元格中读取数据。我有 Double 中的时间值(毫秒),即 0.36712962962962964。

我需要将此值转换为 java.sql.Time 格式。我尝试使用各种方法对其进行解析,但失败了。以下是代码。

timeInDouble = 0.36712962962962964; Time time = new Time(Long.parseLong(timeInDouble.toString()));

这段代码的输出是:

java.lang.NumberFormatException: For input string: "0.36712962962962964"

这种转换的正确方法是什么?

【问题讨论】:

  • Long只能包含自然数,那么0.36应该怎么处理呢?变成 0 了吗?
  • 是的,所以我应该将 long 乘以 1000,然后将其传递给 Time() 类吗?
  • 仅供参考,java.sql.Time 类在几年前被java.time.LocalTime 取代,并采用了JSR 310

标签: java parsing time double datetime-conversion


【解决方案1】:

tl;博士

现代解决方案使用 java.timeLocalTime

将您的字符串输入转换为 double,作为一天的一小部分,乘以一天中的纳秒数(或者可能是毫秒),再加上一天中的 00:00:00。

LocalTime
.MIN
.plusNanos (
    (long)
    (
            TimeUnit.HOURS.toNanos ( 24 )
            *
            Double.parseDouble ( "0.36712962962962964" )
    )
)

08:48:40

java.time

java.sql.Time 类是一个可怕的 hack,它假装是一天中的时间,但实际上是通过子类化java.util.Date 来实现的。 永远不要使用这个类。

随着 JSR 310 的采用,这个类成为了传统,被 java.time.LocalTime 类所取代。 LocalTime 真正代表没有日期、没有时区上下文或与 UTC 偏移的时间。

我假设您说 Microsoft Excel 提供的这个十进制数字代表一天 24 小时的一小部分是正确的。顺便说一句,这是表示一天中某个时间的糟糕方式。更好的方法是使用标准ISO 8601 格式的文本。

首先将您的输入解析为double 原语。通常情况下,我会建议 BigDecimal 类以确保准确性,但我猜 Excel 使用 floating-point technology 来处理这个数字,所以我们也会这样做。

// Parse your input string as a `double`.
String input = "0.36712962962962964";
double fractionOf24Hours = Double.parseDouble ( input );

该输入可能代表一天 24 小时的一小部分。所以让我们计算一天的纳秒数。我想 Excel 使用毫秒而不是纳秒,但最终结果可能是相同的。

// Calculate the number of nanoseconds in a day.
long nanosIn24Hours = TimeUnit.HOURS.toNanos ( 24 );

我们有常数 LocalTime.MIN 来表示一天中的时间 00:00:00。再加上代表我们一天中所需分数的纳秒数。

// Start at time-of-day zero, adding the amount of time in nanos.
long nanosToAdd = ( long ) ( nanosIn24Hours * fractionOf24Hours );
LocalTime localTime = LocalTime.MIN.plusNanos ( nanosToAdd );

看到这个code run live at IdeOne.com

localTime.toString(): 08:48:40

转换

如果您必须拥有java.sql.Time 对象才能与尚未更新到java.time 的旧代码互操作,则可以来回转换。查看添加到旧类的新方法。

java.sql.Time t = Time.valueOf( localTime ) ;

【讨论】:

    【解决方案2】:

    双精度值表示一天持续时间的一部分,其中 0 表示一天的开始,1 表示一天的结束。 Time 类的构造函数期望时间以毫秒为单位。一天有 24 x 60 x 60 x 1000 毫秒。首先,我们将 daouble 转换为自一天开始以来的毫秒数。然后使用毫秒创建一个时间。

    double timeInDouble = 0.36712962962962964;
    
    // The number of milliseconds since the beginning of the day
    long milliseconds = (long) (timeInDouble * 24 * 60 * 60 * 1000);
    
    Time time = new Time(milliseconds);
    

    【讨论】:

      猜你喜欢
      • 2022-01-28
      • 2016-10-28
      • 1970-01-01
      • 2023-04-01
      • 2016-10-10
      • 1970-01-01
      • 1970-01-01
      • 2020-06-22
      • 2010-11-09
      相关资源
      最近更新 更多