将双精度转换为 java.sql.Time

Convert Double to java.sql.Time

我正在从 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"

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

double 值表示一天持续时间的一部分,其中 0 是开始,1 是一天的结束。时间构造函数 class 期望时间以毫秒为单位。一天有 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);

tl;博士

现代解决方案使用 java.time class LocalTime

将您的字符串输入转换为 double,作为一天的一小部分,乘以一天中的纳秒数(或毫秒),添加到 00:00:00 时间-天.

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

08:48:40

java.time

java.sql.Time class 是一个 可怕的 hack,伪装成时间但实际上由 subclassing java.util.Date永远不要使用这个 class。

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

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

首先将您的输入解析为 double 原语。通常,为了准确性,我会建议 BigDecimal class,但我猜测 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 的旧代码进行互操作,您可以来回转换。查看添加到旧 classes 的新方法。

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