Есть ли способ сравнить метки времени с разными форматами? - PullRequest
0 голосов
/ 08 января 2020

Я пытаюсь сравнить ответ от базы данных и веб-сервисов.

response from web services is : 2020-01-07T17:15:00-08:00
response from database is :     2020-01-08 01:15:00.0

Как преобразовать их обоих в общий формат?

Или есть способ использовать подстроку для сравнения?

Ответы [ 3 ]

1 голос
/ 12 января 2020

Мы не знаем. Строки не дают одинаковую информацию, поэтому информация из них не легко сопоставима. Если вы знаете, какой часовой пояс предполагается во второй строке, мы конвертируем каждый в определенный момент времени и сравниваем их.

Первая строка является более простой, поскольку в дополнение к дате и времени дня она также сообщает смещение от UT C (смещение часового пояса). Таким образом, с помощью этой строки мы можем определить момент времени. Кроме того, строка в формате ISO 8601. Классы java .time, современный Java API даты и времени, анализируют формат ISO 8601 (или его наиболее распространенные варианты) в качестве значений по умолчанию, то есть без какого-либо явного средства форматирования.

    String responseFromWs = "2020-01-07T17:15:00-08:00";
    OffsetDateTime odtFromWs = OffsetDateTime.parse(responseFromWs);
    System.out.println(odtFromWs);

Вывод этого значения:

2020-01-07T17:15-08:00

Очень похоже на вход (пропущены только 00 секунды). Это связано с тем, что OffsetDateTime также печатает обратно формат ISO 8601 (и секунды необязательны в соответствии с этим форматом). Важно то, что у нас есть объект даты и времени, который мы можем использовать для дальнейшей обработки, например, для сравнения с другими объектами даты и времени.

Проблема со второй строкой, той из базы данных, заключается в мы не знаем подразумеваемое смещение. Общие рекомендации включают хранение даты и времени в формате UT C в вашей базе данных, а также не для извлечения ее в виде строки из базы данных, а в качестве правильного объекта даты и времени, например OFfsetDateTime, подобного тому, который мы использовали ранее.

Если вы знаете, что строка в UT C, и мы пока полагаемся на строку:

    DateTimeFormatter dbFormatter = new DateTimeFormatterBuilder()
            .append(DateTimeFormatter.ISO_LOCAL_DATE)
            .appendLiteral(' ')
            .append(DateTimeFormatter.ISO_LOCAL_TIME)
            .toFormatter();

    String responseFromDatabase = "2020-01-08 01:15:00.0";

    OffsetDateTime odtFromDb = LocalDateTime
            .parse(responseFromDatabase, dbFormatter)
            .atOffset(ZoneOffset.UTC);
    System.out.println(odtFromDb);
2020-01-08T01:15Z

Теперь у нас есть два OffsetDateTime объектов. У них есть методы для сравнения:

    System.out.println("Before: " + odtFromWs.isBefore(odtFromDb));
    System.out.println("After: " + odtFromWs.isAfter(odtFromDb));
    System.out.println("Same time: " + odtFromWs.isEqual(odtFromDb));
    System.out.println("Equal: " + odtFromWs.equals(odtFromDb));
Before: false
After: false
Same time: true
Equal: false

Вы можете быть удивлены, что isEqual() возвращает true и equals() false. Это связано с тем, что isEqual() проверяет, обозначают ли два объекта одну и ту же точку во времени, что они и делают, в то время как equals() требуется одна и та же точка во времени и одинаковое смещение , прежде чем он выдаст значение true. Поскольку два объекта имеют разные смещения, в этом случае он возвращает false.

Ваш драйвер JDB C или реализация JPA, вероятно, будут рады получить объект даты-времени из базы данных, а не строку, которая Как я уже сказал, рекомендуется. Детали зависят от типа данных, используемого в базе данных, но вы можете прочитать больше в моем ответе на другие вопросы, см. Ссылку внизу.

Ссылки

1 голос
/ 08 января 2020

Эти строки представляют определенные форматы. Сравнение их было бы равносильно тому, чтобы спросить «одинаковы ли эти форматы» - это не так, и это не то, что вы хотите протестировать (вы хотите проверить: действительно ли эти строки в разных форматах представляют один и тот же момент времени ).

Итак, сделайте это тогда. Во-первых, преобразуйте эти строки (которые являются вещами для людей) в реальные объекты времени, а затем сравните ТЕ .

. Вы можете превратить эти строки в Instant, который представляет моменты в время и, вероятно, то, что вы ищете здесь, а затем, после того как вы конвертировали оба в одно мгновение, вы можете сравнить два момента.

Чтобы превратить строки в Instant, используйте DateTimeFormatter. Дополнительная информация: java API времени .

0 голосов
/ 08 января 2020

Вы можете конвертировать метку времени в эквивалентные форматы даты. Веб-служба выглядит как ISO, поэтому вы можете преобразовать метку времени базы данных в ISO, а затем, наконец, проанализировать текст для получения даты, которую можно использовать для сравнения.

Например:

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class CompareTimeStamp {

    private String webServiceTS = ": 2020-01-07T17:15:00-08:00".replace(": ", "");
    private String dataBaseTS = ": 2020-01-08 01:15:00.0".replace(": ", "");
    private DateTimeFormatter isoFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssXXX");
    private DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.S");

    public static void main(String[] args) {
        CompareTimeStamp cts = new CompareTimeStamp();
        LocalDateTime webServiceTime = LocalDateTime.parse(cts.webServiceTS, cts.isoFormat);
        LocalDateTime dataBaseTime = LocalDateTime.parse(cts.dataBaseTS, cts.format);
        /** OPTION 1 -Remove below code if not choosing this option*/
        System.out.println("webServiceTime: " + webServiceTime);
        System.out.println("dataBaseTime: " + dataBaseTime);
        System.out.println(cts.compareTimeStamps(webServiceTime, dataBaseTime) + "\n");
        /*********************************************************************/

        /** OPTION 2 -Remove below code if not choosing this option*/
        String webServiceTS = cts.formatTimeStamp(webServiceTime);
        String dataBaseTS = cts.formatTimeStamp(dataBaseTime);
        System.out.println("webServiceTS: " + webServiceTS);
        System.out.println("dataBaseTS: " + dataBaseTS);
        System.out.println(cts.compareTimeStamps(webServiceTS, dataBaseTS));
        /*********************************************************************/
    }

    // OPTION 1 - Compares this LocalDateTime with another ensuring that the date-time is the same.
    private String compareTimeStamps(LocalDateTime webServiceTime, LocalDateTime dataBaseTime) {
        if (webServiceTime.equals(dataBaseTime)) {
            return "Time stamp matches";
        } else {
            return "Time stamp does not match";
        }
    }

    // OPTION 2 - Compares this string to the specified object.
    private String compareTimeStamps(String webServiceTS2, String dataBaseTS2) {
        if (webServiceTS2.equals(dataBaseTS2)) {
            return "Time stamp matches";
        } else {
            return "Time stamp does not match";
        }
    }

    private String formatTimeStamp(LocalDateTime timeStamp) {
        DateTimeFormatter formating = DateTimeFormatter.ofPattern("EEEE, MMM d, yyyy HH:mm:ss a");
        String localTimeStamp = formating.format(timeStamp);
        return localTimeStamp;
    }
}

выходы:

webServiceTime: 2020-01-07T17:15
dataBaseTime: 2020-01-08T01:15
Time stamp does not match

webServiceTS: Tuesday, Jan 7, 2020 17:15:00 PM
dataBaseTS: Wednesday, Jan 8, 2020 01:15:00 AM
Time stamp does not match

изменение меток времени:

": 2020-01-07T17:15:00-08:00"
": 2020-01-07 17:15:00.0"

выходы:

webServiceTime: 2020-01-07T17:15
dataBaseTime: 2020-01-07T17:15
Time stamp matches

webServiceTS: Tuesday, Jan 7, 2020 17:15:00 PM
dataBaseTS: Tuesday, Jan 7, 2020 17:15:00 PM
Time stamp matches
...