Эпоха не эпоха, если сделать новую дату (0L). Зачем? - PullRequest
4 голосов
/ 12 марта 2010

Моя проблема довольно просто объяснена:

если я сделаю это:

public class Main {

public static void main(String[] args) throws Exception {
        Date d = new Date(0L );
        System.out.println(d);
}

}

Я получаю следующий вывод: чт 01 января 01:00:00 CET 1970

Согласно документу, я ожидал: Чт 01 января 00:00:00 CET 1970

Я бы хотел пойти не так ...

РЕДАКТИРОВАТЬ: Действительно, я читаю документ слишком быстро. Я должен иметь четверг 01 января 00:00:00 по Гринвичу 1970

Итак, как я могу принудительно использовать GMT и игнорировать все местное время?

Редактировать, Решение:

public static void main(String[] args) throws Exception {
    SimpleDateFormat sdf = new SimpleDateFormat("H:m:s:S");
SimpleTimeZone tz = new SimpleTimeZone(0,"ID");
sdf.setTimeZone(tz) ;
Date d = new Date(0L );
System.out.println( sdf.format(d));
}

Ответы [ 4 ]

6 голосов
/ 12 марта 2010

Epoch определяется как 00:00:00 1970-1-1 UTC. Поскольку CET - это UTC + 1, ваше время равно 1:00.

Если вы посмотрите на конструктор Date (long) , вы увидите, что он ожидает значение равное количеству миллисекунд с начала эпохи, UTC :

Распределяет объект Date и инициализирует его для представления указанное количество миллисекунд с стандартное базовое время, известное как эпоха ", а именно 1 января 1970 г., 00:00:00 GMT.

Относительно вашего желания использовать GMT вместо местного часового пояса: Короче говоря, экземпляр Date всегда использует GMT. Если вы просто хотите отформатировать выходную строку, чтобы она использовала GMT, имел класс DateFormat и, в частности, его метод setTimeZone () .

3 голосов
/ 22 декабря 2013

ТЛ: др

Instant.EPOCH
       .toString()

1970-01-01T00: 00: 00Z

Date::toString ложь

Вы узнали одну из многих причин, по которой следует избегать использования классов java.util.Date/Calendar: экземпляр Date не имеет информации о часовом поясе, однако метод toString использует ваш часовой пояс по умолчанию при рендеринге Строка для отображения. Это сбивает с толку, поскольку подразумевает, что у даты есть часовой пояс, а на самом деле это не так.

Избегать Date / Calendar

Вместо даты / календаря вы должны использовать Joda-Time или новые классы Java 8, java.time. * Из JSR 310.

java.time

Используйте класс Instant в качестве эквивалента Date, момент времени на шкале UTC.

Instant.now()

Для справочной даты эпохи используйте константу.

Instant.EPOCH.toString()

1970-01-01T00: 00: 00Z

Если под «игнорировать все время» вы имеете в виду, что вам действительно нужно значение только для даты без времени суток, используйте класс LocalDate.

LocalDate.ofEpochDay( 0L )

1970-01-01

Пример Joda-Time

Обновление: проект Joda-Time в настоящее время находится в режиме обслуживания, и команда советует перейти на классы java.time.

В Joda-Time экземпляр DateTime действительно знает свой собственный часовой пояс. При желании вы можете использовать форматтер для создания строковых выводов в других часовых поясах.

Вот ваш код, нацеленный на Unix time Epoch , но с использованием Joda-Time 2.3.

// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
// import org.joda.time.*;
// import org.joda.time.format.*;

DateTimeZone timeZone_Paris = DateTimeZone.forID( "Europe/Paris" );

DateTime epochParis = new DateTime( 0L, timeZone_Paris );
DateTime epochUtc = new DateTime( 0L, DateTimeZone.UTC );

Дамп на консоль ...

System.out.println( "epochParis: " + epochParis );
System.out.println( "epochUtc: " + epochUtc );

При запуске ...

epochParis: 1970-01-01T01:00:00.000+01:00
epochUtc: 1970-01-01T00:00:00.000Z

Преобразовать в UTC / GMT

Итак, как я могу принудительно использовать GMT и игнорировать все местное время?

Чтобы использовать UTC / GMT (без смещения часового пояса), либо:

  • Преобразование DateTime в другой экземпляр с другим часовым поясом.
    (Joda-Time делает вещи неизменными для безопасности потоков, поэтому мы не выполняем преобразование, мы создаем новые экземпляры на основе старых.)
  • Использование средства форматирования для создания строк, отображаемых для указанного часового пояса.
// To use UTC/GMT instead of local time zone, create new instance of DateTime.
DateTime nowInParis = new DateTime( timeZone_Paris );
DateTime nowInUtcGmt = nowInParis.toDateTime( DateTimeZone.UTC );

Дамп на консоль ...

System.out.println( "nowInParis: " + nowInParis );
System.out.println( "nowInUtcGmt: " + nowInUtcGmt );

При запуске…

nowInParis: 2013-12-22T08:40:01.443+01:00
nowInUtcGmt: 2013-12-22T07:40:01.443Z
3 голосов
/ 12 марта 2010

Это может быть связано с вашими настройками локали. Предполагая, что вы француз, а не франко-канадец, может показаться, что ваша метка времени обрабатывается как метка времени без часового пояса, и конструктор Date пытается исправить это, добавляя час к дате.

Если это недокументированное поведение или нет, я не могу вам сказать.

Редактировать: Ошибка чтения: CET! = UTC: /

Так что да, часовой пояс Locale.

Reedit: Для полной и абсолютной ясности.

Выходные данные: чт 01 января 01:00:00 CET 1970

Ожидаемый результат: чт 01 января 00:00:00 CET 1970

Фактический ожидаемый выходной: Чт 01 января 00:00:00 по Гринвичу 1970 года (≡ Чт 01 января 01:00:00 CET 1970)

1 голос
/ 12 марта 2010

CET на один час опережает время по Гринвичу, то есть часовой пояс, используемый для определения эпохи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...