Конвертировать Double в java.sql.Time - PullRequest
1 голос
/ 22 сентября 2019

Я читаю данные из ячейки в файле 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"

Какой правильный путь для этого преобразования

Ответы [ 2 ]

1 голос
/ 22 сентября 2019

tl; dr

Использование современного решения 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*Класс 1024 * - это ужасный хак , притворяющийся временем суток, но фактически реализованный мгновенно путем подкласса java.util.Date. Никогда не используйте этот класс.

С принятием JSR 310 этот класс стал наследием, вытесненным классом java.time.LocalTime.LocalTime действительно представляет время суток без даты и без контекста часового пояса или смещения от UTC.

Полагаю, вы правы, говоря, что это десятичное число, предоставленное MicrosoftExcel представляет собой долю 24-часового дня.Кстати, это плохой способ представить время суток;лучший способ - использовать текст в стандартном формате ISO 8601 .

Начните с анализа ввода в примитиве double.Обычно я бы предложил BigDecimal класс для точности, но я предполагаю, что Excel использует технологию с плавающей точкой для обработки этого числа, поэтому мы будем делать то же самое.

// 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 );

См. Этот код, запущенный в режиме реального времени на IdeOne.com .

localTime.toString (): 08: 48: 40

Преобразование

Если вам необходим объект java.sql.Time для взаимодействия со старым кодом, который еще не обновлен до java.time , вы можете конвертировать туда и обратно.Посмотрите на новые методы, добавленные к старым классам.

java.sql.Time t = Time.valueOf( localTime ) ;
0 голосов
/ 22 сентября 2019

Двойное значение представляет часть продолжительности дня, где 0 - начало, а 1 - конец дня.Contructor класса Time ожидает время в миллисекундах.В день 24 х 60 х 60 х 1000 миллисекунд.Сначала мы конвертируем двойное число в миллисекунды с начала дня.Затем создайте время, используя миллисекунды.

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);
...