Получить время по Гринвичу в Java

В Java я хочу получить текущее время в GMT.

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

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

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

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

Ответ 1

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

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.

Ответ 2

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

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

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

Ответ 3

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

так:

ZonedDateTime currentDate = ZonedDateTime.now( ZoneOffset.UTC );

Ответ 4

TL;DR

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 и более поздних версий. Эти классы вытесняют неприятные старые legacy классы времени, такие как java.util.Date, Calendar и SimpleDateFormat.

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

Чтобы узнать больше, см. Учебник Oracle. И поиск Qaru для многих примеров и объяснений. Спецификация 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 и больше.

Ответ 5

Чтобы получить время в миллисе в GMT, вам нужно всего

long millis = System.currentTimeMillis();

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

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

и

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

но это неэффективные способы совершения одного и того же вызова.

Ответ 6

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

Вот код:

 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();

Это прекрасно работает.:)

Ответ 7

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

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

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

Ответ 8

Полезные методы Утилиты, как показано ниже, для управления временем в GMT с DST Экономия:

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;
}

Ответ 9

Предположим, только внешнее представление представляет интерес. Следующее сработало для меня без лишних слов. Он основан на объекте java.util.Calendar и на java.util.Formatter.

Кажется, что объект календаря действует как объект даты с изменяющимся часовым поясом вместо часового пояса по умолчанию и принимается средством форматирования вместо даты.

Тестовый код был:

Calendar cl = Calendar.getInstance();
cl.setTimeInMillis(System.currentTimeMillis());
System.out.println("cl="+String.format(
             "%1$ta, %1$td %1$tb %1$tY %1$tT %1$tZ", cl));
cl.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println("cl="+String.format(Locale.ENGLISH, 
             "%1$ta, %1$td %1$tb %1$tY %1$tT %1$tZ", cl));

Результат был:

cl=Mi, 06 Feb 2019 13:51:41 MEZ
cl=Wed, 06 Feb 2019 12:51:41 GMT

Ответ 10

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

DateTimeFormatter.ofPattern("HH:mm:ss.SSS").format(LocalTime.now(ZoneId.of("GMT")));

Ответ 11

Вы не можете

Во-первых, вы спрашиваете о невозможном. Старомодный объект 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 (GMT): 2019-06-17T11: 51: 38.246188Z

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

связи