Я знаю, что эти типы тем полностью обсуждаются, но я обнаружил, что пакет commons-lang действительно хорошо справляется с этими распространенными проблемами Java. commons.apache.org/lang/api-2.5/org/apache/commons/lang/time Проверьте различные пакеты, которые они имеют.
Какое местное время вы хотите, и с какой точностью. Большинство часовых поясов определены относительно UTC с фиксированным смещением, измеренным в секундах СИ , но взаимосвязь GMT, которая основана на наблюдении за Солнцем и (слегка) переменной длиной секунды, является более сложной. Два отличаются до 0,9 секунд.
mc0e
1
A Dateне содержит часовой пояс, поэтому «но в местном часовом поясе» не является правильным (или в лучшем случае неточным). См. Все о java.util.Date .
Ole VV
Ответы:
409
java.util.Dateне имеет определенного часового пояса, хотя его значение чаще всего рассматривается по отношению к UTC. Что заставляет вас думать, что это по местному времени?
Если быть точным: значение в пределах java.util.Date- это количество миллисекунд, прошедших с эпохи Unix, которая произошла в полночь 1 января 1970 года по Гринвичу. Та же самая эпоха могла также быть описана в других часовых поясах, но традиционное описание в терминах UTC. Так как это число в миллисекундах с фиксированной эпохи, значение в пределах java.util.Dateодного и того же момента в любой точке мира независимо от местного часового пояса.
Я подозреваю, что проблема заключается в том, что вы отображаете его с помощью экземпляра Calendar, который использует местный часовой пояс, или, возможно, с помощью, Date.toString()который также использует местный часовой пояс, или SimpleDateFormatэкземпляра, который по умолчанию также использует местный часовой пояс.
Если это не проблема, пожалуйста, отправьте пример кода.
Однако я бы порекомендовал вам в любом случае использовать Joda-Time , который предлагает гораздо более понятный API.
Тогда это, вероятно, проблема с драйверами. Вам может потребоваться установить соединение с UTC или что-то в этом роде. Я видел такие проблемы раньше, но проблема не в java.util.Date.
Джон Скит
13
Behrang, согласно stackoverflow.com/questions/4123534/… , драйвер MySQL JDBC преобразует данный java.util.Timestamp(или java.util.Date) в часовой пояс сервера.
Дерек Махар
5
@Г-н. Cat: Как вы это определяете? Это написано System.out.println(new Date())? Если это так, вы должны знать, что это toString()метод, который применяет часовой пояс там ... если это не так, пожалуйста, дайте более подробную информацию.
Джон Скит
8
@KanagaveluSugumar: toString()всегда использует часовой пояс по умолчанию. date.getTime()безусловно, возвращает миллисекунды с эпохи Unix, в UTC. Точнее всего сказать, что Dateсам по себе часовой пояс вообще не существует - это просто момент времени, который можно рассматривать в нескольких часовых поясах. Но когда вы создаете экземпляр, он не зависит от вашего часового пояса.
Джон Скит
6
@Jemenake: На самом деле этого не произошло, когда в Гринвиче была полночь, потому что в то время Великобритания была на UTC + 1. Просто один из странных кусочков истории. Но я понимаю вашу точку зрения - лучше сказать, что «new Date (). GetTime () возвращает миллисекунды с эпохи Unix, которая была полуночью в начале 1 января 1970 года, UTC». Таким образом, UTC является частью закрепления эпохи к определенному моменту времени, а не частью результата.
Джон Скит
325
ТЛ; др
Instant.now()// Capture the current moment in UTC.
Создайте строку для представления этого значения:
Instant.now().toString()
2016-09-13T23: 30: 52.123Z
подробности
Как правильно сказал Джон Скит , у объекта java.util.Date нет часового пояса † . Но его toStringреализация применяет часовой пояс JVM по умолчанию при генерации строкового представления этого значения даты и времени. Смущает наивного программиста дата, кажется, имеет часовой пояс, но не имеет.
В java.util.Date, j.u.Calendarи java.text.SimpleDateFormatклассы в комплекте с Java , как известно , хлопотное. Избежать их. Вместо этого используйте любую из этих компетентных библиотек даты и времени:
Java 8 предлагает отличный новый пакет java.time. * Для замены старых классов java.util.Date/Calendar.
Получение текущего времени в формате UTC / GMT - это простой однострочный…
Instant instant =Instant.now();
Этот Instantкласс является основным строительным блоком в java.time, представляющим момент на временной шкале в UTC с разрешением наносекунд .
В Java 8 текущий момент фиксируется только с разрешением до миллисекунд. Java 9 приносит свежую реализацию из Clockзахватов текущего момента в до полной наносекундной возможности этого класса, в зависимости от способности аппаратных часов вашего главного компьютера.
Если вы хотите более гибкое форматирование или другие дополнительные функции, тогда примените нулевое смещение от UTC, чтобы сам UTC ( ZoneOffset.UTCпостоянный ) получил a OffsetDateTime.
OffsetDateTime now =OffsetDateTime.now(ZoneOffset.UTC );
Вы можете обмениваться объектами java.time напрямую с вашей базой данных. Используйте драйвер JDBC, соответствующий JDBC 4.2 или более поздней версии . Нет необходимости в строках, нет необходимости в java.sql.*классах.
Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Вы можете найти некоторые полезные классы здесь , такие как Interval, YearWeek, YearQuarter, и более .
Используя стороннюю бесплатную библиотеку с открытым исходным кодом 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 );
Читайте о форматах ISO 8601 . И java.time, и Joda-Time используют разумные форматы этого стандарта в качестве значений по умолчанию для анализа и генерации строк.
† На самом деле, java.util.Date делает есть часовой пояс, похороненный глубоко под слоями исходного кода. Для большинства практических целей этот часовой пояс игнорируется. Итак, в качестве сокращения, мы говорим, что java.util.Date не имеет часового пояса. Кроме того, этот скрытый часовой пояс не тот, который используется методом Дейта toString; этот метод использует текущий часовой пояс JVM по умолчанию. Все больше причин избегать этого запутанного класса и придерживаться Joda-Time и java.time.
DateTime.now().toDateTime(DateTimeZone.UTC)было то, что я искал! Спасибо!
Манагарм
1
@Managarm Вы можете сократить это до: DateTime nowUtc = DateTime.now ( DateTimeZone.UTC ) ;
Василий Бурк
Как получить это с помощью Pure Java 8 2014-01-21T15:34:29.933-08:00в примере, который вы использовалиnew org.joda.time.DateTime()
GOXR3PLUS
1
@ GOXR3PLUS ZonedDateTime.now( ZoneId.of( "America/Los_Angeles" ) ).truncatedTo( ChronoUnit.MILLIS ).toOffsetDateTime().toString() Мы получаем текущий момент для указанного часового пояса. Затем отрежьте любые микро / нанос. Затем мы конвертируем в наличие только простого смещения от UTC (количество часов-минут-секунд), а не полноценного часового пояса (история прошлых, настоящих и будущих изменений в смещении, используемом людьми конкретный регион). Наконец, мы генерируем текст, представляющий значение в OffsetDateTimeсоответствии со стандартным форматом ISO 8601, используемым по умолчанию в его toStringметоде.
Василий Бурк
Спасибо за то, что дали это подробное объяснение, также +1 для поддержки Android :) @BasilBourque
mochadwi
271
SimpleDateFormat dateFormatGmt =newSimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));//Local time zone SimpleDateFormat dateFormatLocal =newSimpleDateFormat("yyyy-MMM-dd HH:mm:ss");//Time in GMTreturn dateFormatLocal.parse( dateFormatGmt.format(newDate()));
Почему вы анализируете с dateFormatLocal после использования формата dateFormatGmt ... не имеет смысла читать его. Я уверен, что это работает, но просто интересно?
MindWire
2
setTimeZone сделал это (я думаю, вы также можете использовать getTimeZone («UTC») так же, как GMT?)
rogerdpack
6
но время зависит от времени установки устройства. Если пользователь установил неправильное время на своем устройстве, то вы получите неправильный UTC. Исправьте меня, если я ошибаюсь
Басаварадж Хампали
@BasavarajHampali, но в сегодняшнем мире большинство устройств подключены к Интернету, что исправляет неправильное время
Акшат Агарвал
3
Нет разницы во времени между всемирным координированным временем (UTC) и средним временем по Гринвичу (GMT)
slott
86
Это определенно возвращает время UTC: как объекты String и Date!
В своем ответе я забыл показать, как определяется DATEFORMAT: static final String DATEFORMAT = "yyyy-MM-dd HH:mm:ss";
Кто-то где-то
21
Пожалуйста, избегайте начинать имена методов с верхнего регистра в Java. Посмотрите соглашения о кодировании Java для имен методов.
Флориан Шрофнер
2
Поскольку я перенаправлен на этот ответ, Calling new Date()никогда не вернет правильное время UTC, если время устройства неверно.
Sanoop
время получения этого метода зависит от календаря устройства?
Арнольд Браун
Стоит отметить одну вещь. Любое решение, которому нужно получить дату или метку времени в UTC, похоже, что ключ состоит в том, чтобы не использовать SimpleDateFormat повторно, а использовать его, чтобы получить UTC в строку, а затем создать другой UTC при преобразовании строки в дату. или метка времени объекта. Я заметил, что если вы попытаетесь повторно использовать тот же SimpleDateFormat, то полученный объект Date / Timestamp вернется в местный часовой пояс вместо UTC.
Да, хорошее и чистое решение. Меня просто беспокоит, неэффективно ли создавать новый объект Date вместо простого получения экземпляра Calendar?
Beemo
Он будет оптимизирован JVM, и HotSpot выполнит наиболее эффективный код x86
Антонио
17
Календарь aGMTCalendar = Calendar.getInstance (TimeZone.getTimeZone ("GMT")); Тогда все операции, выполняемые с использованием объекта aGMTCalendar, будут выполняться с часовым поясом GMT и не будут применяться летнее время или фиксированные смещения.
java.util.Dateвсегда в UTC. Что заставляет вас думать, что это по местному времени? Я подозреваю, что проблема в том, что вы отображаете его с помощью экземпляра Calendar, который использует местный часовой пояс, или, возможно, с помощью
Date.toString()которого также используется местный часовой пояс.
показывает часы по Гринвичу вместо местных часов - обратите внимание, что getTime.getHours()отсутствует, потому что это создаст Date()объект, который теоретически хранит дату в GMT, но возвращает часы в местном часовом поясе.
Я не видел этот ответ раньше, но если вы прочитали документацию по устаревшему Date.getHours()методу, это очень ясно дает понять: «Возвращаемое значение - это число (от 0 до 23), представляющее час в течение дня, который содержит или начинается с момент времени, представленный этим объектом Date, как интерпретируется в местном часовом поясе . " (Подчеркните мое.) Это getHours()метод, который интерпретирует значение в пределах местного часового пояса - он не является частью состояния самого Dateобъекта.
Джон Скит
2
Как правильно сказал Джон Скит, у объекта java.util.Date нет часового пояса . Но сбивает с толку методы toStringи getHoursприменяют часовой пояс по умолчанию к их выводу. Таким образом, наивных программистов легко обмануть, так как кажется, что у Date есть часовой пояс, но на самом деле его нет.
Базилик Бурк
7
Если вам нужен объект Date с полями, настроенными для UTC, вы можете сделать это следующим образом с Joda Time :
import org.joda.time.DateTimeZone;import java.util.Date;...Date local =newDate();System.out.println("Local: "+ local);DateTimeZone zone =DateTimeZone.getDefault();long utc = zone.convertLocalToUTC(local.getTime(),false);System.out.println("UTC: "+newDate(utc));
Ты слишком много работаешь. Joda-Time может сделать это в одной строке кода. Смотрите мой собственный ответ на этот вопрос. Вызовите .toDateTimeметод и передайте константу для часового пояса UTC.
Базилик Бурк
1
DateTime utcDate = new DateTime (). ToDateTime (DateTimeZone.UTC)
Тогда все операции, выполняемые с использованием объекта aGMTCalendar, будут выполняться с часовым поясом GMT и не будут применяться летнее время или фиксированные смещения. Я думаю, что предыдущий плакат верен, что объект Date () всегда возвращает GMT, пока вы не сделаете что-то с объектом даты, который будет преобразован в местный часовой пояс.
Вы можете спросить cal.get(Calendar.DATE);или другую константу календаря о других деталях.
Дата и метка времени устарели в Java. Календарный класс это не так.
Пример кода для отображения системного времени в определенном часовом поясе и в определенном формате.
import java.text.SimpleDateFormat;import java.util.Calendar;import java.util.Date;import java.util.TimeZone;publicclassTimZoneTest{publicstaticvoid 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"));}publicstaticString 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 =newSimpleDateFormat(format);
date_format_gmt.setTimeZone(tz);return date_format_gmt.format(date);}}
Вывод
10/08/201121: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
Вызов getTime () приводит к тому, что он теряет информацию о часовом поясе и возвращает местное время.
RealCasually
3
Преобразование текущего DateTime в UTC:
DateTimeFormatter formatter =DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");DateTimeZone dateTimeZone =DateTimeZone.getDefault();//Default Time ZoneDateTime currDateTime =newDateTime();//Current DateTimelong 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
Вы делаете слишком много работы здесь. (a) Заданная вами программа форматирования уже встроена в DateTime по умолчанию; просто вызовите toStringDateTime, чтобы получить этот строковый шаблон ISO 8601 . (б) слишком много кода для преобразования между часовыми поясами. Просто вызовите «toDateTime» и передайте объект часового пояса. Как это: myDateTime.toDateTime( DateTimeZone.UTC ). Для конкретного часового пояса создайте экземпляр и передайте объект часового пояса на основе правильного имени , call myDateTime.toDateTime( DateTimeZone.forID( "Asia/Tehran" ) ).
Базилик Бурк
2
Это сработало для меня, возвращает метку времени в GMT!
Используйте этот класс, чтобы получить правильное время UTC с онлайн-сервера NTP:
import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.InetAddress;class NTP_UTC_Time
{privatestaticfinalString TAG ="SntpClient";privatestaticfinalint RECEIVE_TIME_OFFSET =32;privatestaticfinalint TRANSMIT_TIME_OFFSET =40;privatestaticfinalint NTP_PACKET_SIZE =48;privatestaticfinalint NTP_PORT =123;privatestaticfinalint NTP_MODE_CLIENT =3;privatestaticfinalint NTP_VERSION =3;// Number of seconds between Jan 1, 1900 and Jan 1, 1970// 70 years plus 17 leap daysprivatestaticfinallong OFFSET_1900_TO_1970 =((365L*70L)+17L)*24L*60L*60L;privatelong mNtpTime;publicboolean requestTime(String host,int timeout){try{DatagramSocket socket =newDatagramSocket();
socket.setSoTimeout(timeout);InetAddress address =InetAddress.getByName(host);byte[] buffer =newbyte[NTP_PACKET_SIZE];DatagramPacket request =newDatagramPacket(buffer, buffer.length, address, NTP_PORT);
buffer[0]= NTP_MODE_CLIENT |(NTP_VERSION <<3);
writeTimeStamp(buffer, TRANSMIT_TIME_OFFSET);
socket.send(request);// read the responseDatagramPacket response =newDatagramPacket(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);returnfalse;}returntrue;}publiclong getNtpTime(){return mNtpTime;}/**
* Reads an unsigned 32 bit big endian number from the given offset in the buffer.
*/privatelong 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 valuesint 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).
*/privatelong 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
*/privatevoid 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 «сейчас», используйте функцию DateTimeString:
Проще говоря. Объект календаря хранит информацию о часовом поясе, но при выполнении cal.getTime () информация о часовом поясе будет потеряна. Поэтому для преобразования часовых поясов я советую использовать классы DateFormat ...
publicstaticStringGetCurrentTimeStamp(){Calendar cal=Calendar.getInstance();long offset = cal.getTimeZone().getOffset(System.currentTimeMillis());//if you want in UTC else remove it .returnnew java.sql.Timestamp(System.currentTimeMillis()+offset).toString();}
publicclassCurrentUtcDate{publicstaticvoid main(String[] args){Date date =newDate();SimpleDateFormat dateFormat =newSimpleDateFormat("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-201813:14:35
Вы можете изменить формат даты по мере необходимости.
Пожалуйста, не учите молодых использовать давно устаревшие и печально известные хлопоты SimpleDateFormat. Сегодня у нас гораздо лучше в java.timeсовременном API даты и времени Java . И что вы предлагаете, чего еще нет в ответах Дэна, Антонио и других?
Оле В.В.
2
(а) Как этот ответ увеличивает ценность десятков существующих ответов? (b) Используемые здесь проблемные классы были вытеснены несколько лет назад современными классами java.time . Предлагать их использование в 2018 году - плохой совет.
Василий Бурк
0
Используйте пакет java.time и включите ниже
ZonedDateTime now = ZonedDateTime.now( ZoneOffset.UTC );
(A) Если используется смещение ( ZoneOffset), а не часовой пояс ( ZoneId), то OffsetDateTimeболее подходящим, чем ZonedDateTime. (B) LocalDateTimeне должен использоваться для захвата текущего момента, так как он не имеет понятия часового пояса или смещения от UTC. (C) Другие ранее существовавшие Ответы охватили этот материал и сделали лучшую работу. Я не вижу, как этот ответ добавляет ценность.
Date
не содержит часовой пояс, поэтому «но в местном часовом поясе» не является правильным (или в лучшем случае неточным). См. Все о java.util.Date .Ответы:
java.util.Date
не имеет определенного часового пояса, хотя его значение чаще всего рассматривается по отношению к UTC. Что заставляет вас думать, что это по местному времени?Если быть точным: значение в пределах
java.util.Date
- это количество миллисекунд, прошедших с эпохи Unix, которая произошла в полночь 1 января 1970 года по Гринвичу. Та же самая эпоха могла также быть описана в других часовых поясах, но традиционное описание в терминах UTC. Так как это число в миллисекундах с фиксированной эпохи, значение в пределахjava.util.Date
одного и того же момента в любой точке мира независимо от местного часового пояса.Я подозреваю, что проблема заключается в том, что вы отображаете его с помощью экземпляра Calendar, который использует местный часовой пояс, или, возможно, с помощью,
Date.toString()
который также использует местный часовой пояс, илиSimpleDateFormat
экземпляра, который по умолчанию также использует местный часовой пояс.Если это не проблема, пожалуйста, отправьте пример кода.
Однако я бы порекомендовал вам в любом случае использовать Joda-Time , который предлагает гораздо более понятный API.
источник
java.util.Timestamp
(илиjava.util.Date
) в часовой пояс сервера.System.out.println(new Date())
? Если это так, вы должны знать, что этоtoString()
метод, который применяет часовой пояс там ... если это не так, пожалуйста, дайте более подробную информацию.toString()
всегда использует часовой пояс по умолчанию.date.getTime()
безусловно, возвращает миллисекунды с эпохи Unix, в UTC. Точнее всего сказать, чтоDate
сам по себе часовой пояс вообще не существует - это просто момент времени, который можно рассматривать в нескольких часовых поясах. Но когда вы создаете экземпляр, он не зависит от вашего часового пояса.ТЛ; др
Создайте строку для представления этого значения:
подробности
Как правильно сказал Джон Скит , у объекта java.util.Date нет часового пояса † . Но его
toString
реализация применяет часовой пояс JVM по умолчанию при генерации строкового представления этого значения даты и времени. Смущает наивного программиста дата, кажется, имеет часовой пояс, но не имеет.В
java.util.Date
,j.u.Calendar
иjava.text.SimpleDateFormat
классы в комплекте с Java , как известно , хлопотное. Избежать их. Вместо этого используйте любую из этих компетентных библиотек даты и времени:java.time (Java 8)
Java 8 предлагает отличный новый пакет java.time. * Для замены старых классов java.util.Date/Calendar.
Получение текущего времени в формате UTC / GMT - это простой однострочный…
Этот
Instant
класс является основным строительным блоком в java.time, представляющим момент на временной шкале в UTC с разрешением наносекунд .В Java 8 текущий момент фиксируется только с разрешением до миллисекунд. Java 9 приносит свежую реализацию из
Clock
захватов текущего момента в до полной наносекундной возможности этого класса, в зависимости от способности аппаратных часов вашего главного компьютера.Этот
toString
метод генерирует строковое представление его значения, используя один определенный формат ISO 8601 . Этот формат выводит ноль, три, шесть или девять цифр ( миллисекунды , микросекунды или наносекунды ) по мере необходимости для представления доли секунды.Если вы хотите более гибкое форматирование или другие дополнительные функции, тогда примените нулевое смещение от UTC, чтобы сам UTC (
ZoneOffset.UTC
постоянный ) получил aOffsetDateTime
.Дамп на консоль…
Когда беги…
О java.time
Java.time каркас встроен в Java 8 и более поздних версий. Эти классы вытеснять неприятные старые устаревшие классы даты и времени , такие как
java.util.Date
,Calendar
, иSimpleDateFormat
.Чтобы узнать больше, смотрите Oracle Tutorial . И поиск переполнения стека для многих примеров и объяснений. Спецификация JSR 310 .
Проект Joda-Time , находящийся сейчас в режиме обслуживания , рекомендует перейти на классы java.time .
Вы можете обмениваться объектами java.time напрямую с вашей базой данных. Используйте драйвер JDBC, соответствующий JDBC 4.2 или более поздней версии . Нет необходимости в строках, нет необходимости в
java.sql.*
классах.Где взять классы java.time?
Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Вы можете найти некоторые полезные классы здесь , такие как
Interval
,YearWeek
,YearQuarter
, и более .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.
Более подробный пример кода (Joda-Time 2.3)…
Дамп на консоль…
Когда беги…
Более подробный пример кода, выполняющего работу с часовым поясом, см. В моем ответе на аналогичный вопрос.
Часовой пояс
Я рекомендую вам всегда указывать часовой пояс, а не полагаться неявно на текущий часовой пояс JVM по умолчанию (который может измениться в любой момент!). Такое доверие, по-видимому, является распространенной причиной путаницы и ошибок в работе с датой и временем.
При звонке
now()
пройдите желаемый / ожидаемый часовой пояс, который будет назначен. ИспользуйтеDateTimeZone
класс.Этот класс содержит константу для часового пояса UTC .
Если вы действительно хотите использовать текущий часовой пояс JVM по умолчанию, сделайте явный вызов, чтобы ваш код самодокументировался.
ISO 8601
Читайте о форматах ISO 8601 . И java.time, и Joda-Time используют разумные форматы этого стандарта в качестве значений по умолчанию для анализа и генерации строк.
† На самом деле, java.util.Date делает есть часовой пояс, похороненный глубоко под слоями исходного кода. Для большинства практических целей этот часовой пояс игнорируется. Итак, в качестве сокращения, мы говорим, что java.util.Date не имеет часового пояса. Кроме того, этот скрытый часовой пояс не тот, который используется методом Дейта
toString
; этот метод использует текущий часовой пояс JVM по умолчанию. Все больше причин избегать этого запутанного класса и придерживаться Joda-Time и java.time.источник
DateTime.now().toDateTime(DateTimeZone.UTC)
было то, что я искал! Спасибо!DateTime nowUtc = DateTime.now ( DateTimeZone.UTC ) ;
2014-01-21T15:34:29.933-08:00
в примере, который вы использовалиnew org.joda.time.DateTime()
ZonedDateTime.now( ZoneId.of( "America/Los_Angeles" ) ).truncatedTo( ChronoUnit.MILLIS ).toOffsetDateTime().toString()
Мы получаем текущий момент для указанного часового пояса. Затем отрежьте любые микро / нанос. Затем мы конвертируем в наличие только простого смещения от UTC (количество часов-минут-секунд), а не полноценного часового пояса (история прошлых, настоящих и будущих изменений в смещении, используемом людьми конкретный регион). Наконец, мы генерируем текст, представляющий значение вOffsetDateTime
соответствии со стандартным форматом ISO 8601, используемым по умолчанию в егоtoString
методе.источник
Это определенно возвращает время UTC: как объекты String и Date!
источник
static final String DATEFORMAT = "yyyy-MM-dd HH:mm:ss";
new Date()
никогда не вернет правильное время UTC, если время устройства неверно.источник
На самом деле не время, но его представление можно изменить.
Время одинаково в любой точке Земли, но наше восприятие времени может быть различным в зависимости от местоположения.
источник
Неправильно!
а также
вернется в то же время. То же самое для
источник
Этот код печатает текущее время UTC.
Результат
источник
Это работает для получения UTC миллисекунд в Android.
источник
c.add(Calendar.MILLISECOND, (-utcOffset))
получить календарь с часовым поясом utcВот что кажется неправильным в ответе Джона Скита . Он сказал:
Тем не менее, код:
показывает местное время, а не время по Гринвичу (UTC), используя no
Calendar
и noSimpleDateFormat
вообще.Вот почему, кажется, что-то не так.
Собираем ответы, код:
показывает часы по Гринвичу вместо местных часов - обратите внимание, что
getTime.getHours()
отсутствует, потому что это создастDate()
объект, который теоретически хранит дату в GMT, но возвращает часы в местном часовом поясе.источник
Date.getHours()
методу, это очень ясно дает понять: «Возвращаемое значение - это число (от 0 до 23), представляющее час в течение дня, который содержит или начинается с момент времени, представленный этим объектом Date, как интерпретируется в местном часовом поясе . " (Подчеркните мое.) ЭтоgetHours()
метод, который интерпретирует значение в пределах местного часового пояса - он не является частью состояния самогоDate
объекта.toString
иgetHours
применяют часовой пояс по умолчанию к их выводу. Таким образом, наивных программистов легко обмануть, так как кажется, что у Date есть часовой пояс, но на самом деле его нет.Если вам нужен объект Date с полями, настроенными для UTC, вы можете сделать это следующим образом с Joda Time :
источник
.toDateTime
метод и передайте константу для часового пояса UTC.Ты можешь использовать:
Тогда все операции, выполняемые с использованием объекта aGMTCalendar, будут выполняться с часовым поясом GMT и не будут применяться летнее время или фиксированные смещения. Я думаю, что предыдущий плакат верен, что объект Date () всегда возвращает GMT, пока вы не сделаете что-то с объектом даты, который будет преобразован в местный часовой пояс.
источник
источник
Вы можете напрямую использовать это
источник
С:
Затем
cal
укажите текущую дату и время.Вы также можете получить текущую дату и время для часового пояса с помощью:
Вы можете спросить
cal.get(Calendar.DATE);
или другую константу календаря о других деталях.Дата и метка времени устарели в Java. Календарный класс это не так.
источник
Вот другое предложение, чтобы получить объект GMT Timestamp:
источник
Вот еще один способ получить время по Гринвичу в формате String
источник
Вот моя реализация TOUTC:
Вероятно, есть несколько способов улучшить это, но это работает для меня.
источник
Пример кода для отображения системного времени в определенном часовом поясе и в определенном формате.
Вывод
источник
Просто чтобы сделать это проще, для создания
Date
вUTC
вы можете использоватьCalendar
:Который создаст новый экземпляр для
Calendar
использования «UTC»TimeZone
.Если вам нужен
Date
объект из этого календаря, вы можете просто использоватьgetTime()
.источник
Преобразование текущего DateTime в UTC:
источник
toString
DateTime, чтобы получить этот строковый шаблон ISO 8601 . (б) слишком много кода для преобразования между часовыми поясами. Просто вызовите «toDateTime» и передайте объект часового пояса. Как это:myDateTime.toDateTime( DateTimeZone.UTC )
. Для конкретного часового пояса создайте экземпляр и передайте объект часового пояса на основе правильного имени , callmyDateTime.toDateTime( DateTimeZone.forID( "Asia/Tehran" ) )
.Это сработало для меня, возвращает метку времени в GMT!
источник
Используйте этот класс, чтобы получить правильное время UTC с онлайн-сервера NTP:
И используйте его с:
Если вам нужно время UTC «сейчас», используйте функцию DateTimeString:
и используйте его с:
источник
источник
Проще говоря. Объект календаря хранит информацию о часовом поясе, но при выполнении cal.getTime () информация о часовом поясе будет потеряна. Поэтому для преобразования часовых поясов я советую использовать классы DateFormat ...
источник
это моя реализация:
источник
Если вы хотите избежать разбора даты и просто хотите использовать метку времени в GMT, вы можете использовать:
источник
Если вы используете joda time и хотите использовать текущее время в миллисекундах без локального смещения, вы можете использовать это:
источник
Вывод:
Вы можете изменить формат даты по мере необходимости.
источник
SimpleDateFormat
. Сегодня у нас гораздо лучше вjava.time
современном API даты и времени Java . И что вы предлагаете, чего еще нет в ответах Дэна, Антонио и других?Используйте пакет java.time и включите ниже
ZonedDateTime now = ZonedDateTime.now( ZoneOffset.UTC );
или
LocalDateTime now2 = LocalDateTime.now( ZoneOffset.UTC );
в зависимости от необходимости вашего приложения.
источник
ZoneOffset
), а не часовой пояс (ZoneId
), тоOffsetDateTime
более подходящим, чемZonedDateTime
. (B)LocalDateTime
не должен использоваться для захвата текущего момента, так как он не имеет понятия часового пояса или смещения от UTC. (C) Другие ранее существовавшие Ответы охватили этот материал и сделали лучшую работу. Я не вижу, как этот ответ добавляет ценность.