Преобразование 2 строк с миллисекундами в дату и вычисление разницы во времени java

У меня есть 2 строки с минутами, секундами и миллисекундами

String startTime = "02:58.917"
String finishTime = "04:03.332"

и мне нужно рассчитать разницу во времени. Насколько я понимаю (но я не уверен), самый простой способ - преобразовать их в тип даты, но я не знаю, как это сделать правильно, особенно с миллисекундами. P.S. Если кто-нибудь знает, как я могу рассчитать разницу во времени без преобразования в дату, это также подходит. Помогите пожалуйста!

UPD: мне нужно получить результат в таком же формате, например "01:04:415"


person Ilya    schedule 15.05.2020    source источник
comment
Это может помочь: stackoverflow.com/questions/ 6403851/   -  person user    schedule 15.05.2020
comment
Отвечает ли это на ваш вопрос? преобразование строки Java в дату   -  person Ali Ahmad    schedule 15.05.2020
comment
@AliAhmad, это полезно, но мне нужно получить результат в том же формате, например, 01:04:415, и я до сих пор не понимаю, как это сделать   -  person Ilya    schedule 15.05.2020
comment
Нет, не используйте Date, потому что этот класс плохо спроектирован и давно устарел. Используйте java.time, современный API даты и времени Java.   -  person Ole V.V.    schedule 15.05.2020
comment
Представляют ли ваши строки моменты времени, то есть примерно 3 и 4 минуты после часа, или они представляют количество времени (например, продолжительность), которое вам нужно вычесть? Правильный подход для этих двух случаев различен.   -  person Ole V.V.    schedule 15.05.2020
comment
@ОлеВ.В. Если я правильно понял, 1 случай. Это про гонки. Гонщик начинает круг в startTime и финиширует в FinishTime. Мне нужно рассчитать, сколько времени это займет, и получить результат в том же формате   -  person Ilya    schedule 15.05.2020
comment
В таком случае я бы посчитал правильными ответы Арвинда Кумара Авинаша и акузминых. Не смущает ли продолжительность круга в том же формате, что и моменты времени?   -  person Ole V.V.    schedule 15.05.2020


Ответы (2)


Вы можете получить объект java.time.Duration, рассчитав разницу между временем начала и временем окончания. Затем вы можете получить минутную часть, вторую часть и миллисекундную часть из объекта Duration, чтобы получить требуемый результат.

import java.text.ParseException;
import java.time.Duration;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;

public class Main {
    public static void main(String[] args) throws ParseException {
        String startTime = "02:58.917";
        String finishTime = "04:03.332";
        // Create a format by defaulting the hour to any value e.g. 0
        DateTimeFormatter format = new DateTimeFormatterBuilder().append(DateTimeFormatter.ofPattern("mm:ss.SSS"))
                .parseDefaulting(ChronoField.HOUR_OF_DAY, 0).toFormatter();
        LocalTime firstTime = LocalTime.parse(startTime, format);
        LocalTime secondTime = LocalTime.parse(finishTime, format);
        Duration diff = Duration.between(firstTime, secondTime);
        String msms = String.format("%02d:%02d:%03d", diff.toMinutesPart(), diff.toSecondsPart(), diff.toMillisPart());
        System.out.println("The difference is " + msms);
    }
}

Вывод:

The difference is 01:04:415
person Arvind Kumar Avinash    schedule 15.05.2020

Вот пример того, как это сделать с помощью java.time:

// create dtf for pattern where mm is minutes, ss is seconds, SSS is millis
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("mm:ss.SSS");

// we need to add a default value for hour so the parsing with LocalTime works
formatter = new DateTimeFormatterBuilder()
        .append(formatter)
        .parseDefaulting(ChronoField.HOUR_OF_DAY, 1)
        .toFormatter();

// parse the values
LocalTime t1 = LocalTime.parse("02:58.917", formatter);
LocalTime t2 = LocalTime.parse("04:03.332", formatter);

// get the millis between t1 and t2
System.out.println(t1.until(t2, ChronoUnit.MILLIS));

// another way
System.out.println(ChronoUnit.MILLIS.between(t1, t2));

// you can get the result in the same format by adding the difference
// to a new LocalTime with all set to zero and using the formatter
LocalTime delta = LocalTime.of(1, 0, 0, 0)
        .plus(t1.until(t2, ChronoUnit.MILLIS), ChronoUnit.MILLIS);
System.out.println(delta.format(formatter));
person akuzminykh    schedule 15.05.2020
comment
Но что я могу сделать, если мне нужно получить результат в том же формате, например, 01:04:415? - person Ilya; 15.05.2020
comment
@Ilya Вы можете сделать это, создав новый LocalTime со всеми установленными на ноль и добавив к нему разницу в миллисекундах. Затем с помощью средства форматирования вы получите желаемый файл String. Проверьте редактирование и не стесняйтесь принять ответ. - person akuzminykh; 15.05.2020
comment
Большая часть ответа хороша. Использование еще одного LocalTime для длительности между первыми двумя неверно. Используйте Duration, как в ответе Арвинда Кумара Авинаша. Это также проще. - person Ole V.V.; 15.05.2020
comment
@ОлеВ.В. Спасибо за внимание. Я оставлю это как есть, потому что это альтернатива. Это не неправильно, результат тот же. Duration может показаться немного более удобным. - person akuzminykh; 15.05.2020
comment
Могу я задать еще один вопрос? Мне было интересно, как это работает с часами, и я попробовал этот код DateTimeFormatter formatter = DateTimeFormatter.ofPattern(hh:mm:ss.SSS); LocalTime t1 = LocalTime.parse(01:02:58.917, средство форматирования); Но это не удалось. Можете ли вы сказать, в чем проблема? - person Ilya; 15.05.2020
comment
@Ilya Для этого нужно открыть отдельный вопрос. - person akuzminykh; 16.05.2020