Как получить текущую дату и время в UTC или GMT на Java?

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

415
21 нояб. '08 в 16:02
источник поделиться
31 ответ
  • 1
  • 2

java.util.Date не имеет определенного часового пояса, хотя его значение чаще всего рассматривается в отношении UTC. Что заставляет вас думать об этом в местное время?

Чтобы быть точным: значение в пределах java.util.Date - это количество миллисекунд с эпохи Unix, которое произошло в полночь 1 января 1970 года, UTC. Та же эпоха также может быть описана в других часовых поясах, но традиционное описание относится к UTC. Поскольку это число в миллисекундах с фиксированной эпохи, значение в пределах java.util.Date во всем мире одинаково, независимо от локального часового пояса.

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

Если это не проблема, отправьте несколько примеров кода.

Тем не менее, я бы рекомендовал вам использовать Joda-Time, что дает гораздо более четкий API.
371
21 нояб. '08 в 16:04
источник

Связанные вопросы


Похожие вопросы

SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));

//Local time zone   
SimpleDateFormat dateFormatLocal = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");

//Time in GMT
return dateFormatLocal.parse( dateFormatGmt.format(new Date()) );
265
27 марта '10 в 10:08
источник

ТЛ; др

Instant.now()   // Capture the current moment in UTC. 

Сгенерируйте строку для представления этого значения:

Instant.now().toString()  

2016-09-13T23: 30: 52.123Z

подробности

Как правильно сказал Джон Скит, у объекта java.util.Date нет часового пояса . Но его реализация toString применяет часовой пояс JVM по умолчанию при генерации строкового представления этого значения даты и времени. Смущает наивного программиста дата, кажется, имеет часовой пояс, но не имеет.

juCalendar java.util.Date, juCalendar и java.text.SimpleDateFormat связанные с Java, общеизвестно проблематичны. Избежать их. Вместо этого используйте любую из этих компетентных библиотек даты и времени:

java.time(Java 8)

Java 8 содержит отличный новый пакет java.time. *, Который заменит старые классы java.util.Date/Calendar.

Получение текущего времени в UTC/GMT - это простая однострочная…

Instant instant = Instant.now();

Этот класс Instant является основным строительным блоком в java.time, представляющим момент на временной шкале в UTC с разрешением наносекунд.

В Java 8 текущий момент фиксируется только с разрешением до миллисекунд. В Java 9 реализована свежая реализация Clock фиксирующая текущий момент вплоть до полной наносекундной способности этого класса, в зависимости от возможностей тактового оборудования вашего хост-компьютера.

Его метод toString генерирует строковое представление своего значения, используя один определенный формат ISO 8601. Этот формат выводит ноль, три, шесть или девять цифр (миллисекунды, микросекунды или наносекунды) по мере необходимости для представления доли секунды.

Если вы хотите более гибкое форматирование или другие дополнительные функции, тогда примените нулевое смещение от UTC для самого UTC (константа ZoneOffset.UTC), чтобы получить OffsetDateTime.

OffsetDateTime now = OffsetDateTime.now( ZoneOffset.UTC );

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

System.out.println( "now: " + now );

Когда беги…

now: 2014-01-21T23:42:03.522Z

Table of types of date-time classes in modern java.time versus legacy.

Классы java.time определены JSR 310. Они были вдохновлены Joda-Time, но полностью перестроены.

Joda времени

ОБНОВЛЕНИЕ: Проект Joda-Time, находящийся сейчас в режиме обслуживания, рекомендует перейти на классы java.time.

Используя стороннюю бесплатную библиотеку с открытым исходным кодом Joda-Time, вы можете получить текущую дату и время всего за одну строку кода.

Joda-Time вдохновил новые классы java.time. * В Java 8, но имеет другую архитектуру. Вы можете использовать Joda-Time в более старых версиях Java. Joda-Time продолжает работать на Java 8 и продолжает активно поддерживаться (по состоянию на 2014 год). Тем не менее, команда Joda-Time советует перейти на java.time.

System.out.println( "UTC/GMT date-time in ISO 8601 format: " + new org.joda.time.DateTime( org.joda.time.DateTimeZone.UTC ) );

Более подробный пример кода (Joda-Time 2.3)…

org.joda.time.DateTime now = new org.joda.time.DateTime(); // Default time zone.
org.joda.time.DateTime zulu = now.toDateTime( org.joda.time.DateTimeZone.UTC );

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

System.out.println( "Local time in ISO 8601 format: " + now );
System.out.println( "Same moment in UTC (Zulu): " + zulu );

Когда беги…

Local time in ISO 8601 format: 2014-01-21T15:34:29.933-08:00
Same moment in UTC (Zulu): 2014-01-21T23:34:29.933Z

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

Часовой пояс

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

При вызове now() передайте желаемый/ожидаемый часовой пояс, который будет назначен. Используйте класс DateTimeZone.

DateTimeZone zoneMontréal = DateTimeZone.forID( "America/Montreal" );
DateTime now = DateTime.now( zoneMontréal );

Этот класс содержит константу для часового пояса UTC.

DateTime now = DateTime.now( DateTimeZone.UTC );

Если вы действительно хотите использовать текущий часовой пояс JVM по умолчанию, сделайте явный вызов, чтобы ваш код самодокументировался.

DateTimeZone zoneDefault = DateTimeZone.getDefault();

ISO 8601

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


На самом деле, java.util.Date имеет часовой пояс, похороненный глубоко под слоями исходного кода. Для большинства практических целей этот часовой пояс игнорируется. Итак, в качестве сокращения, мы говорим, что java.util.Date не имеет часового пояса. Кроме того, этот скрытый часовой пояс не тот, который используется методом Dates toString; этот метод использует текущий часовой пояс по умолчанию для JVM. Все больше причин избегать этого запутанного класса и придерживаться Joda-Time и java.time.

223
28 окт. '13 в 13:14
источник

Это определенно возвращает время UTC: как объекты String и Date!

static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";

public static Date getUTCdatetimeAsDate() {
    // note: doesn't check for null
    return stringDateToDate(getUTCdatetimeAsString());
}

public static String getUTCdatetimeAsString() {
    final SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
    sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
    final String utcTime = sdf.format(new Date());

    return utcTime;
}

public static Date stringDateToDate(String StrDate) {
    Date dateToReturn = null;
    SimpleDateFormat dateFormat = new SimpleDateFormat(DATEFORMAT);

    try {
        dateToReturn = (Date)dateFormat.parse(StrDate);
    }
    catch (ParseException e) {
        e.printStackTrace();
    }

    return dateToReturn;
}
78
14 июля '11 в 21:06
источник
    Calendar c = Calendar.getInstance();
    System.out.println("current: "+c.getTime());

    TimeZone z = c.getTimeZone();
    int offset = z.getRawOffset();
    if(z.inDaylightTime(new Date())){
        offset = offset + z.getDSTSavings();
    }
    int offsetHrs = offset / 1000 / 60 / 60;
    int offsetMins = offset / 1000 / 60 % 60;

    System.out.println("offset: " + offsetHrs);
    System.out.println("offset: " + offsetMins);

    c.add(Calendar.HOUR_OF_DAY, (-offsetHrs));
    c.add(Calendar.MINUTE, (-offsetMins));

    System.out.println("GMT Time: "+c.getTime());
65
16 марта '10 в 14:14
источник

На самом деле не время, но его можно было изменить.

SimpleDateFormat f = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
f.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(f.format(new Date()));

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

49
08 нояб. '10 в 17:23
источник

Этот код печатает текущее время UTC.

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


public class Test
{
    public static void main(final String[] args) throws ParseException
    {
        final SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
        f.setTimeZone(TimeZone.getTimeZone("UTC"));
        System.out.println(f.format(new Date()));
    }
}

Результат

2013-10-26 14:37:48 UTC
16
26 окт. '13 в 17:39
источник

Календарь aGMTCalendar = Calendar.getInstance(TimeZone.getTimeZone( "GMT" )); Затем все операции, выполняемые с использованием объекта aGMTCalendar, будут выполняться с часовым поясом GMT и не будут применяться летнее время или фиксированные смещения.

Неправильно!

Calendar aGMTCalendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
aGMTCalendar.getTime(); //or getTimeInMillis()

и

Calendar aNotGMTCalendar = Calendar.getInstance(TimeZone.getTimeZone("GMT-2"));aNotGMTCalendar.getTime();

вернет то же время. То же самое для

new Date(); //it not GMT.
15
06 апр. '10 в 17:28
источник

Это работает для получения UTC миллисекунд в Android.

Calendar c = Calendar.getInstance();
int utcOffset = c.get(Calendar.ZONE_OFFSET) + c.get(Calendar.DST_OFFSET);  
Long utcMilliseconds = c.getTimeInMillis() + utcOffset;
13
16 мая '13 в 22:35
источник

Вот что кажется неправильным в ответе Джона Скита. Он сказал:

java.util.Date всегда в UTC. Что заставляет вас думать это по местному времени? Я подозреваю, что проблема в том, что вы отображаете его с помощью экземпляра Calendar, который использует локальный часовой пояс, или, возможно, с помощью Date.toString() который также использует локальный часовой пояс.

Тем не менее, код:

System.out.println(new java.util.Date().getHours() + " hours");

показывает местное время, а не время по Гринвичу (UTC), без использования Calendar и SimpleDateFormat.

Вот почему, кажется, что-то не так.

Собираем ответы, код:

System.out.println(Calendar.getInstance(TimeZone.getTimeZone("GMT"))
                           .get(Calendar.HOUR_OF_DAY) + " Hours");

показывает часы по Гринвичу вместо локальных часов - обратите внимание, что отсутствует getTime.getHours() потому что это создаст объект Date(), который теоретически сохраняет дату в GMT, но возвращает часы в местном часовом поясе.

10
22 мая '12 в 21:01
источник

Если вы хотите объект Date с полями, настроенными для UTC, вы можете сделать это следующим образом Joda Time:

import org.joda.time.DateTimeZone;
import java.util.Date;

...

Date local = new Date();
System.out.println("Local: " + local);
DateTimeZone zone = DateTimeZone.getDefault();
long utc = zone.convertLocalToUTC(local.getTime(), false);
System.out.println("UTC: " + new Date(utc));
7
04 мая '12 в 13:51
источник

Вы можете использовать:

Calendar aGMTCalendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));

Затем все операции, выполняемые с использованием объекта aGMTCalendar, будут выполняться с часовым поясом GMT и не будут применяться летнее время или фиксированные смещения. Я думаю, что предыдущий плакат верен, что объект Date() всегда возвращает GMT, пока вы не сделаете что-то с объектом даты, который он преобразует в локальный часовой пояс.

6
26 янв. '10 в 19:32
источник

Вы можете напрямую использовать этот

SimpleDateFormat dateFormatGmt = new SimpleDateFormat("dd:MM:yyyy HH:mm:ss");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(dateFormatGmt.format(new Date())+"");
6
17 апр. '12 в 9:39
источник
SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MM-dd");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(dateFormatGmt.format(date));
6
21 дек. '10 в 14:36
источник

С

Calendar cal = Calendar.getInstance();

Затем cal имеют текущую дату и время.
Вы также можете получить текущую дату и время для часового пояса с помощью:

Calendar cal2 = Calendar.getInstance(TimeZone.getTimeZone("GMT-2"));

Вы можете задать cal.get(Calendar.DATE); или другую константу календаря о других деталях.
Дата и временная метка устарели на Java. Календарного класса это не так.

5
21 нояб. '08 в 16:10
источник

Здесь другое предложение получить объект Timestamp GMT:

import java.sql.Timestamp;
import java.util.Calendar;

...

private static Timestamp getGMT() {
   Calendar cal = Calendar.getInstance();
   return new Timestamp(cal.getTimeInMillis()
                       -cal.get(Calendar.ZONE_OFFSET)
                       -cal.get(Calendar.DST_OFFSET));
}
5
09 мая '12 в 13:34
источник

Вот еще один способ получить время по Гринвичу в формате String

String DATE_FORMAT = "EEE, dd MMM yyyy HH:mm:ss z" ;
final SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
String dateTimeString =  sdf.format(new Date());
5
01 окт. '12 в 6:48
источник

Чтобы сделать это проще, для создания Date в UTC вы можете использовать Calendar:

Calendar.getInstance(TimeZone.getTimeZone("UTC"));

Будет создан новый экземпляр для Calendar с использованием "UTC" TimeZone.

Если вам нужен объект Date из этого календаря, вы можете просто использовать getTime().

3
17 мая '12 в 16:04
источник

Пример кода для отображения системного времени в определенном часовом поясе и в определенном формате.

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

public class TimZoneTest {
    public static void main (String[] args){
        //<GMT><+/-><hour>:<minutes>
        // Any screw up in this format, timezone defaults to GMT QUIETLY. So test your format a few times.

        System.out.println(my_time_in("GMT-5:00", "MM/dd/yyyy HH:mm:ss") );
        System.out.println(my_time_in("GMT+5:30", "'at' HH:mm a z 'on' MM/dd/yyyy"));

        System.out.println("---------------------------------------------");
        // Alternate format 
        System.out.println(my_time_in("America/Los_Angeles", "'at' HH:mm a z 'on' MM/dd/yyyy") );
        System.out.println(my_time_in("America/Buenos_Aires", "'at' HH:mm a z 'on' MM/dd/yyyy") );


    }

    public static String my_time_in(String target_time_zone, String format){
        TimeZone tz = TimeZone.getTimeZone(target_time_zone);
        Date date = Calendar.getInstance().getTime();
        SimpleDateFormat date_format_gmt = new SimpleDateFormat(format);
        date_format_gmt.setTimeZone(tz);
        return date_format_gmt.format(date);
    }

}

Выход

10/08/2011 21:07:21
at 07:37 AM GMT+05:30 on 10/09/2011
at 19:07 PM PDT on 10/08/2011
at 23:07 PM ART on 10/08/2011
3
09 окт. '11 в 3:51
источник

Преобразование текущей даты в UTC:

DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");

DateTimeZone dateTimeZone = DateTimeZone.getDefault(); //Default Time Zone

DateTime currDateTime = new DateTime(); //Current DateTime

long utcTime = dateTimeZone.convertLocalToUTC(currDateTime .getMillis(), false);

String currTime = formatter.print(utcTime); //UTC time converted to string from long in format of formatter

currDateTime = formatter.parseDateTime(currTime); //Converted to DateTime in UTC
3
08 янв. '14 в 16:08
источник

Вот моя реализация toUTC:

    public static Date toUTC(Date date){
    long datems = date.getTime();
    long timezoneoffset = TimeZone.getDefault().getOffset(datems);
    datems -= timezoneoffset;
    return new Date(datems);
}

Возможно, есть несколько способов улучшить его, но он работает для меня.

3
31 авг. '16 в 18:10
источник

Это сработало для меня, возвращает метку времени в GMT!

    Date currDate;
    SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
    dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
    SimpleDateFormat dateFormatLocal = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");

    long currTime = 0;
    try {

        currDate = dateFormatLocal.parse( dateFormatGmt.format(new Date()) );
        currTime = currDate.getTime();
    } catch (ParseException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
2
25 марта '13 в 15:46
источник
public static void main(String args[]){
    LocalDate date=LocalDate.now();  
    System.out.println("Current date = "+date);
}
2
19 окт. '16 в 13:31
источник

Проще говоря. Объект календаря хранит информацию о часовом поясе, но когда вы выполняете cal.getTime(), информация о часовом поясе будет потеряна. Поэтому для конверсий Timezone я советую использовать классы DateFormat...

1
05 дек. '12 в 11:21
источник

это моя реализация:

public static String GetCurrentTimeStamp()
{
    Calendar cal=Calendar.getInstance();
    long offset = cal.getTimeZone().getOffset(System.currentTimeMillis());//if you want in UTC else remove it .
    return new java.sql.Timestamp(System.currentTimeMillis()+offset).toString();    
}
1
27 мая '14 в 8:52
источник

Если вы хотите избежать разбора даты и просто хотите отметки времени в GMT, вы можете использовать:

final Date gmt = new Timestamp(System.currentTimeMillis()
            - Calendar.getInstance().getTimeZone()
                    .getOffset(System.currentTimeMillis()));
1
11 авг. '15 в 9:55
источник

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

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;


class NTP_UTC_Time
{
private static final String TAG = "SntpClient";

private static final int RECEIVE_TIME_OFFSET = 32;
private static final int TRANSMIT_TIME_OFFSET = 40;
private static final int NTP_PACKET_SIZE = 48;

private static final int NTP_PORT = 123;
private static final int NTP_MODE_CLIENT = 3;
private static final int NTP_VERSION = 3;

// Number of seconds between Jan 1, 1900 and Jan 1, 1970
// 70 years plus 17 leap days
private static final long OFFSET_1900_TO_1970 = ((365L * 70L) + 17L) * 24L * 60L * 60L;

private long mNtpTime;

public boolean requestTime(String host, int timeout) {
    try {
        DatagramSocket socket = new DatagramSocket();
        socket.setSoTimeout(timeout);
        InetAddress address = InetAddress.getByName(host);
        byte[] buffer = new byte[NTP_PACKET_SIZE];
        DatagramPacket request = new DatagramPacket(buffer, buffer.length, address, NTP_PORT);

        buffer[0] = NTP_MODE_CLIENT | (NTP_VERSION << 3);

        writeTimeStamp(buffer, TRANSMIT_TIME_OFFSET);

        socket.send(request);

        // read the response
        DatagramPacket response = new DatagramPacket(buffer, buffer.length);
        socket.receive(response);          
        socket.close();

        mNtpTime = readTimeStamp(buffer, RECEIVE_TIME_OFFSET);            
    } catch (Exception e) {
      //  if (Config.LOGD) Log.d(TAG, "request time failed: " + e);
        return false;
    }

    return true;
}


public long getNtpTime() {
    return mNtpTime;
}


/**
 * Reads an unsigned 32 bit big endian number from the given offset in the buffer.
 */
private long read32(byte[] buffer, int offset) {
    byte b0 = buffer[offset];
    byte b1 = buffer[offset+1];
    byte b2 = buffer[offset+2];
    byte b3 = buffer[offset+3];

    // convert signed bytes to unsigned values
    int i0 = ((b0 & 0x80) == 0x80 ? (b0 & 0x7F) + 0x80 : b0);
    int i1 = ((b1 & 0x80) == 0x80 ? (b1 & 0x7F) + 0x80 : b1);
    int i2 = ((b2 & 0x80) == 0x80 ? (b2 & 0x7F) + 0x80 : b2);
    int i3 = ((b3 & 0x80) == 0x80 ? (b3 & 0x7F) + 0x80 : b3);

    return ((long)i0 << 24) + ((long)i1 << 16) + ((long)i2 << 8) + (long)i3;
}

/**
 * Reads the NTP time stamp at the given offset in the buffer and returns 
 * it as a system time (milliseconds since January 1, 1970).
 */    
private long readTimeStamp(byte[] buffer, int offset) {
    long seconds = read32(buffer, offset);
    long fraction = read32(buffer, offset + 4);
    return ((seconds - OFFSET_1900_TO_1970) * 1000) + ((fraction * 1000L) / 0x100000000L);        
}

/**
 * Writes 0 as NTP starttime stamp in the buffer. --> Then NTP returns Time OFFSET since 1900
 */    
private void writeTimeStamp(byte[] buffer, int offset) {        
    int ofs =  offset++;

    for (int i=ofs;i<(ofs+8);i++)
      buffer[i] = (byte)(0);             
}

}

И используйте его с помощью:

        long now = 0;

        NTP_UTC_Time client = new NTP_UTC_Time();

        if (client.requestTime("pool.ntp.org", 2000)) {              
          now = client.getNtpTime();
        }

Если вам нужна UTC Time "now", как функция использования DateTimeString:

private String get_UTC_Datetime_from_timestamp(long timeStamp){

    try{

        Calendar cal = Calendar.getInstance();
        TimeZone tz = cal.getTimeZone();

        int tzt = tz.getOffset(System.currentTimeMillis());

        timeStamp -= tzt;

        // DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",Locale.getDefault());
        DateFormat sdf = new SimpleDateFormat();
        Date netDate = (new Date(timeStamp));
        return sdf.format(netDate);
    }
    catch(Exception ex){
        return "";
     }
    } 

и используйте его с помощью:

String UTC_DateTime = get_UTC_Datetime_from_timestamp(now);
1
02 нояб. '13 в 0:49
источник
public class CurrentUtcDate 
{
    public static void main(String[] args) {
        Date date = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
        dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
        System.out.println("UTC Time is: " + dateFormat.format(date));
    }
}

Вывод:

UTC Time is: 22-01-2018 13:14:35

Вы можете изменить формат даты по мере необходимости.

0
04 июля '18 в 6:24
источник

Используйте пакет java.time и включите ниже code-

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

или же

LocalDateTime now2 = LocalDateTime.now( ZoneOffset.UTC );

в зависимости от необходимости вашего приложения.

0
02 нояб. '18 в 1:47
источник

Если вы используете время joda и хотите текущее время в миллисекундах без вашего локального смещения, вы можете использовать это:

long instant = DateTimeZone.UTC.getMillisKeepLocal(DateTimeZone.getDefault(), System.currentTimeMillis());
0
08 июля '15 в 13:18
источник
  • 1
  • 2

Посмотрите другие вопросы по меткам или Задайте вопрос