Разница во времени между датами Java? - PullRequest
0 голосов
/ 06 мая 2020

Я использовал устаревший API Date для вычисления разницы во времени между двумя моментами времени в формате yyyyMMdd'T'HHmmss.

Клиент устанавливает атрибут requestExpirationTime в запросе, а сервер выполняет проверку, чтобы убедиться, что " RequestExpirationTime не раньше текущего системного времени ".

Клиент:

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd'T'HHmmss");
Timestamp originatingTimestamp = new Timestamp(new Date().getTime());

// duration is offset 5minutes for exmaple

Timestamp requestExpirationTimestamp = new Timestamp(originatingTimestamp.getTime() + duration); 
request.setRequestExpirationTimestamp(simpleDateFormat.format(requestExpirationTimestamp));

Сервер:

try {
        Date systemTime = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd'T'HHmmss");

        String ret = request.getRequestExpirationTimestamp();
        if (ret != null) {
            Date requestExpirationTimestamp = sdf.parse(ret);
            if (requestExpirationTimestamp.before(systemTime)) {                    

            logger.info("Request timedout: RequestExpirationTime is before current system time");

                }
            }
        }

Этот код вызывает проблемы, поскольку systemTime на сервере поставляется в IST (стандартное индийское время), и клиент может отправлять в любом UTC / IST.

Я переехал на Java 8, поэтому я могу оставить устаревшую версию Date Api в Java.

Как я могу убедиться, что такие проблемы с часовым поясом не появляются в моем коде? Я попытался установить часовой пояс в SimpleDateFormat на сервере, но new Date() ведет себя по-разному на разных серверах.

Любая помощь приветствуется.

1 Ответ

2 голосов
/ 06 мая 2020

Когда клиент отправляет время, отличное от UT C, например, стандартное время Индии (IST), и сервер не знает, какой часовой пояс использует клиент, тогда сервер ничего не может сделать, чтобы сделать он работает правильно. Вместо этого я предлагаю вам убедиться, что клиент всегда отправляет время в UT C.

Клиент

Убедитесь, что вы всегда отправляете время в UT C:

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuuMMdd'T'HHmmss");

    String requestExpirationTime = OffsetDateTime.now(ZoneOffset.UTC)
            .plusMinutes(5)
            .format(formatter);

    System.out.println(requestExpirationTime);

Пример вывода только что запущенного:

20200506T183409

Сервер

Теперь сервер знает, что время указано в UT C. Я предполагаю, что он использует форматировщик, идентичный тому, который использовал клиент.

    OffsetDateTime dateTime = LocalDateTime.parse(requestExpirationTime, formatter)
            .atOffset(ZoneOffset.UTC);
    OffsetDateTime systemTime = OffsetDateTime.now(ZoneOffset.UTC);
    if (dateTime.isBefore(systemTime)) {
        System.out.println("Request timedout: RequestExpirationTime is before current system time");
    } else {
        System.out.println("OK");
    }

ОК

Совет

Вы можете добавить Z к строке отметки времени, чтобы было ясно, что это UT C. Это может предотвратить некоторые ошибки в будущем.

20200506T183409Z

...