Как проверить дату (в формате UTC) за 48 часов до сегодняшней даты [дубликаты]

1

Я попытался преобразовать новый объект сегодняшней даты в UTC. Но не повезло, так как новый объект даты всегда находится в локальном часовом поясе. Я пытаюсь проверить две даты, используя метод "раньше". date1 находится в формате UTC. date2 сегодня.

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

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;

public class test {

    /**
     * @param args
     */
    public static void main(String[] args) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
        sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
        String todayStr = sdf.format(new Date());// This string is in UTC. But I need date object in UTC.

        try {
            System.out.println(sdf.parse(todayStr));// This is still printing in local time zone.
        } catch (ParseException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }


    }

}
  • 0
    Я думаю, что сравнение дат нормализуется ко времени UTC, так что вам не о чем беспокоиться
  • 0
    @ne1410s ne1410s Извините, я не могу понять, что вы пытаетесь сказать. не могли бы вы, пожалуйста, высказаться.
Показать ещё 1 комментарий
Теги:
date

2 ответа

4
Лучший ответ

Объект Date не находится в часовом поясе - это всего лишь обертка вокруг количества миллисекунд с эпохи Unix. Эпоха Unix обычно описывается в терминах UTC (а именно, полночь в начале 1 января 1970 года), но это действительно только момент времени.

Чтобы получить момент за 48 часов до "сейчас", вы можете использовать что-то вроде:

Date earlier = new Date(System.currentTimeMillis() - TimeUnit.HOURS.toMillis(48));

Вы можете сравнить это с любым объектом Date чтобы увидеть, что произошло раньше времени - опять же, без ссылки на какой-либо конкретный часовой пояс.

По правде говоря, это не легко проверяемое решение - я предпочитаю абстрагировать System.currentTimeMillis() за интерфейсом Clock, чтобы я мог протестировать с поддельными часами, установленными в любое время, которое я хочу.)

Если вам не требуется строковое представление, не обращайте на него внимания - как только вы хотите получить строковое представление, вам нужно подумать о том, какая система календаря и часовой пояс вам интересна.

Обратите внимание, что вы говорите о "сегодняшней дате" в вопросе - если вы имеете в виду начало определенного дня, то часовой пояс имеет значение, и вам нужно будет сделать больше работы.

Наконец, я бы предположил, что если возможно, вы используете либо java.time.* Из Java 8, либо Joda Time, а не java.util.Date и т.д. Первые два являются гораздо лучшими API, чем предыдущие.

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

Да, это потому, что Date.toString() использует локальный часовой пояс. Это то, что он делает (к сожалению), и это не значит, что объект Date находится в локальном часовом поясе.

  • 1
    +1 Весьма всеобъемлющий. И даже не относящиеся к середине двадцатых годов Сингапур. Это мой любимый :)
  • 0
    @ Джон Скит, Спасибо за хорошее объяснение. Это имеет смысл. Просто хочу попробовать ниже подход. Я не уверен, работает ли мой подход или нет. Я просто пытаюсь сейчас: 1. преобразовать дату (в UTC) в григорианский календарь и получить объект даты 2. преобразовать сегодняшнюю дату в григорианский календарь и получить объект даты 3. проверить, какая дата была раньше.
Показать ещё 3 комментария
0

Подробные сведения см. В правильном ответе Джона Скита.

Вчера и за день до

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

Избегайте java.util.Date

Избегайте использования классов java.util.Date и.Calendar в комплекте с Java. Они, как известно, хлопотно. Вместо этого используйте Joda-Time или новый java.time в Java 8 (вдохновленный Joda-Time). Обе библиотеки имеют класс времени, который знает свой собственный часовой пояс, в отличие от java.util.Date.

Полуоткрытый промежуток времени

И обе библиотеки имеют классы для представления промежутка времени. Сравнение осуществляется с помощью метода "Half-Open", где начало является инклюзивным и окончательным исключением. Таким образом, ваш двухдневный период определяется как первый момент дня до вчерашнего дня (включительно) и заканчивается, но не включает в себя первый момент сегодняшнего дня (эксклюзивный).

ISO 8601

Формат вашей строки определяется стандартом ISO 8601. И Joda-Time, и java.time используют ISO 8601 для дефолтов при разборе и генерации строк. Таким образом, у них есть встроенный форматтер для синтаксического анализа вашей строки. Просто передайте строку.

Неизменяемые объекты

Joda-Time использует неизменяемые объекты. Вместо того, чтобы изменять ("мутировать") существующий объект, создается новый объект со значениями, основанными на оригинале. Причина в том, что безопасность потока.

Joda времени

Вот пример кода в Joda-Time 2.4.

DateTime target = new DateTime( "2014-01-02T03:04:05.789Z", DateTimeZone.UTC );
DateTime nowUtc = DateTime.now( DateTimeZone.UTC );
DateTime today = nowUtc.withTimeAtStartOfDay();
DateTime dayBeforeYesterday = today.minusDays( 2 ).withTimeAtStartOfDay();
Interval interval = new Interval( dayBeforeYesterday, today ); // Half-Open.
boolean hit = interval.contains( target );

Ещё вопросы

Сообщество Overcoder
Наверх
Меню