Получить время по Гринвичу в Java - PullRequest
26 голосов
/ 08 марта 2011

В Java я хочу узнать текущее время по Гринвичу.

Я пробовал разные варианты, например:

Date date = new Date();
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
date1 = calendar.getTime();

Но дата всегда интерпретируется в моем местном часовом поясе..

Что я делаю не так и как я могу преобразовать Java-дату в GMT?

Ответы [ 10 ]

34 голосов
/ 08 марта 2011

Скорее всего, вы правильно сделали, что получили дату, но ничто не указывает на то, что вы не взяли это время по Гринвичу и отформатировали его в соответствии с текущей локалью вашего компьютера.

final Date currentTime = new Date();

final SimpleDateFormat sdf =
        new SimpleDateFormat("EEE, MMM d, yyyy hh:mm:ss a z");

// Give it to me in GMT time.
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println("GMT time: " + sdf.format(currentTime));

Ключ должен использовать ваш собственный DateFormat, а не предоставленный системой.Таким образом, вы можете установить часовой пояс DateFormat на то, что вы хотите, вместо того, чтобы установить часовой пояс Locale.

18 голосов
/ 28 ноября 2013

Интересно, почему никто этого не делает:

Calendar time = Calendar.getInstance();
time.add(Calendar.MILLISECOND, -time.getTimeZone().getOffset(time.getTimeInMillis()));
Date date = time.getTime();

Обновление: начиная с Java 8,9,10 и более, должны быть лучшие альтернативы, поддерживаемые Java.Спасибо за ваш комментарий @ человечность

6 голосов
/ 18 августа 2014

Исходя из моего опыта, связанные классы Calendar и Date в Java могут дать недооцененный эффект. Если вы не против обновления до Java 8, подумайте об использовании ZonedDateTime

вроде так:

ZonedDateTime currentDate = ZonedDateTime.now( ZoneOffset.UTC );
5 голосов
/ 05 февраля 2016

ТЛ; др

Instant.now()

java.time

Ответ от Damilola является верным, предлагая использовать инфраструктуру java.time, встроенную в Java 8 и более поздние версии. Но этот Ответ использует класс ZonedDateTime, который является избыточным, если вы просто хотите использовать UTC, а не какой-либо конкретный часовой пояс.

Мучительные старые классы даты и времени теперь унаследованы, заменены классами java.time.

Instant

Класс Instant представляет момент на временной шкале в UTC с разрешением наносекунд (до девяти (9) цифр десятичного знака) доля).

Простой код:

Instant instant = Instant.now() ;

instant.toString (): 2016-11-29T23: 18: 14.604Z

Вы можете думать о Instant как о строительном блоке, к которому вы можете добавить часовой пояс (ZoneID), чтобы получить ZonedDateTime.

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );

О java.time

Фреймворк java.time встроен в Java 8 и более поздние версии. Эти классы вытесняют старые классные устаревшие классы даты и времени, такие как java.util.Date, Calendar, & SimpleDateFormat.

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

Чтобы узнать больше, см. Oracle Tutorial . И поиск переполнения стека для многих примеров и объяснений. Спецификация JSR 310 .

Где получить классы java.time?

  • Java SE 8 и SE 9 и более поздние
    • Встроенный.
    • Часть стандартного Java API с комплексной реализацией.
    • Java 9 добавляет некоторые незначительные функции и исправления.
  • Java SE 6 и SE 7
    • Большая часть функциональности java.time перенесена в Java 6 & 7 в ThreeTen-Backport .
  • Android

Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Здесь вы можете найти несколько полезных классов, таких как Interval, YearWeek, YearQuarter и more .

3 голосов
/ 23 октября 2012

Чтобы получить время в миллисекундах по Гринвичу, все, что вам нужно, это

long millis = System.currentTimeMillis();

Вы также можете сделать

long millis = new Date().getTime();

и

long millis = 
    Calendar.getInstance(TimeZone.getTimeZone("GMT")).getTimeInMillis();

но это неэффективные способы сделать один и тот же звонок.

2 голосов
/ 10 июля 2015

После многих испытаний я обнаружил, что для получения времени в миллисекундах по Гринвичу вам нужно создать два отдельных объекта SimpleDateFormat, один для форматирования в Гринвиче, а другой для анализа.

Вот код:

 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 format.setTimeZone(TimeZone.getTimeZone("UTC"));
 Date date = new Date();
 SimpleDateFormat dateParser = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 Date dateTime= dateParser.parse(format.format(date));
 long gmtMilliSeconds = dateTime.getTime();

Это отлично работает.:)

1 голос
/ 17 июня 2019

Вы не можете

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

Но дата всегда интерпретируется в моем местном часовом поясе.

Полагаю, вы напечатали Date или сделали что-то еще, что неявно вызывает его toString метод.Я считаю, что это единственный раз, когда Date интерпретируется в вашем часовом поясе.Точнее в текущем часовом поясе по умолчанию вашей JVM.С другой стороны, это неизбежно.Date.toString() ведет себя таким образом , он выбирает настройку часового пояса JVM и использует ее для визуализации возвращаемой строки.

Вы можете с помощью java.time

Вы не должны использовать Date, хотя.Этот класс плохо спроектирован и, к счастью, давно устарел.Также java.time, современный Java-API даты и времени, который его заменяет, имеет класс или два для дат и времени со смещением от GMT или UTC.Я рассматриваю GMT и UTC как синонимы, строго говоря, они не являются.

    OffsetDateTime now = OffsetDateTime.now(ZoneOffset.UTC);
    System.out.println("Time now in UTC (GMT) is " + now);

Когда я только что запустил этот фрагмент, вывод был:

Время в UTCВремя по Гринвичу: 2019-06-17T11: 51: 38.246188Z

Трейлинг Z выхода означает UTC.

Ссылки

0 голосов
/ 01 мая 2019

После Java 8 вы можете получить отформатированное время, как показано ниже:

DateTimeFormatter.ofPattern("HH:mm:ss.SSS").format(LocalTime.now(ZoneId.of("GMT")));
0 голосов
/ 29 ноября 2016

Полезные методы Utils, как показано ниже для управления временем в GMT с помощью DST Savings:

public static Date convertToGmt(Date date) {
    TimeZone tz = TimeZone.getDefault();
    Date ret = new Date(date.getTime() - tz.getRawOffset());

    // if we are now in DST, back off by the delta.  Note that we are checking the GMT date, this is the KEY.
    if (tz.inDaylightTime(ret)) {
        Date dstDate = new Date(ret.getTime() - tz.getDSTSavings());

        // check to make sure we have not crossed back into standard time
        // this happens when we are on the cusp of DST (7pm the day before the change for PDT)
        if (tz.inDaylightTime(dstDate)) {
            ret = dstDate;
        }
    }
    return ret;
}

public static Date convertFromGmt(Date date) {
    TimeZone tz = TimeZone.getDefault();
    Date ret = new Date(date.getTime() + tz.getRawOffset());

    // if we are now in DST, back off by the delta.  Note that we are checking the GMT date, this is the KEY.
    if (tz.inDaylightTime(ret)) {
        Date dstDate = new Date(ret.getTime() + tz.getDSTSavings());

        // check to make sure we have not crossed back into standard time
        // this happens when we are on the cusp of DST (7pm the day before the change for PDT)
        if (tz.inDaylightTime(dstDate)) {
            ret = dstDate;
        }
    }
    return ret;
}
0 голосов
/ 05 февраля 2016

Это довольно просто и прямо.

Date date = new Date();
TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
Calendar cal = Calendar.getInstance(TimeZone.getDefault());
date = cal.getTime();

Теперь дата будет содержать текущее время по Гринвичу.

...