Когда я создаю новый объект Date
, он инициализируется текущим временем, но в локальном часовом поясе. Как я могу получить текущую дату и время в GMT?
Как получить текущую дату и время в UTC или GMT на Java?
Ответ 1
java.util.Date
не имеет определенного часового пояса, хотя его значение чаще всего рассматривается в отношении UTC. Что заставляет вас думать об этом в местное время?
Чтобы быть точным: значение в пределах java.util.Date
- это количество миллисекунд с эпохи Unix, которое произошло в полночь 1 января 1970 года, UTC. Та же эпоха также может быть описана в других часовых поясах, но традиционное описание относится к UTC. Поскольку это число в миллисекундах с фиксированной эпохи, значение в пределах java.util.Date
во всем мире одинаково, независимо от локального часового пояса.
Я подозреваю, что проблема заключается в том, что вы показываете его через экземпляр Календаря, который использует локальный часовой пояс или, возможно, использует Date.toString()
, который также использует локальный часовой пояс или экземпляр SimpleDateFormat
, который, по умолчанию, также использует локальный часовой пояс.
Если это не проблема, отправьте несколько примеров кода.
Тем не менее, я бы рекомендовал вам использовать Joda-Time, что дает гораздо более четкий API.Ответ 2
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()) );
Ответ 3
ТЛ; др
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
- Joda времени
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
Классы 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.
Ответ 4
Это определенно возвращает время 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;
}
Ответ 5
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());
Ответ 6
На самом деле не время, но его можно было изменить.
SimpleDateFormat f = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
f.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(f.format(new Date()));
Время одинаково в любой точке Земли, но наше восприятие времени может быть различным в зависимости от местоположения.
Ответ 7
Этот код печатает текущее время 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
Ответ 8
Календарь 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.
Ответ 9
Это работает для получения UTC миллисекунд в Android.
Calendar c = Calendar.getInstance();
int utcOffset = c.get(Calendar.ZONE_OFFSET) + c.get(Calendar.DST_OFFSET);
Long utcMilliseconds = c.getTimeInMillis() + utcOffset;
Ответ 10
Вот что кажется неправильным в ответе Джона Скита. Он сказал:
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, но возвращает часы в местном часовом поясе.
Ответ 11
Если вы хотите объект 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));
Ответ 12
Вы можете использовать:
Calendar aGMTCalendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
Затем все операции, выполняемые с использованием объекта aGMTCalendar, будут выполняться с часовым поясом GMT и не будут применяться летнее время или фиксированные смещения. Я думаю, что предыдущий плакат верен, что объект Date() всегда возвращает GMT, пока вы не сделаете что-то с объектом даты, который он преобразует в локальный часовой пояс.
Ответ 13
SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MM-dd");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(dateFormatGmt.format(date));
Ответ 14
Вы можете напрямую использовать этот
SimpleDateFormat dateFormatGmt = new SimpleDateFormat("dd:MM:yyyy HH:mm:ss");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(dateFormatGmt.format(new Date())+"");
Ответ 15
С
Calendar cal = Calendar.getInstance();
Затем cal
имеют текущую дату и время.
Вы также можете получить текущую дату и время для часового пояса с помощью:
Calendar cal2 = Calendar.getInstance(TimeZone.getTimeZone("GMT-2"));
Вы можете задать cal.get(Calendar.DATE);
или другую константу календаря о других деталях.
Дата и временная метка устарели на Java. Календарного класса это не так.
Ответ 16
Здесь другое предложение получить объект 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));
}
Ответ 17
Вот еще один способ получить время по Гринвичу в формате 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());
Ответ 18
Пример кода для отображения системного времени в определенном часовом поясе и в определенном формате.
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
Ответ 19
Чтобы сделать это проще, для создания Date
в UTC
вы можете использовать Calendar
:
Calendar.getInstance(TimeZone.getTimeZone("UTC"));
Будет создан новый экземпляр для Calendar
с использованием "UTC" TimeZone
.
Если вам нужен объект Date
из этого календаря, вы можете просто использовать getTime()
.
Ответ 20
Преобразование текущей даты в 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
Ответ 21
Вот моя реализация toUTC:
public static Date toUTC(Date date){
long datems = date.getTime();
long timezoneoffset = TimeZone.getDefault().getOffset(datems);
datems -= timezoneoffset;
return new Date(datems);
}
Возможно, есть несколько способов улучшить его, но он работает для меня.
Ответ 22
Это сработало для меня, возвращает метку времени в 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();
}
Ответ 23
public static void main(String args[]){
LocalDate date=LocalDate.now();
System.out.println("Current date = "+date);
}
Ответ 24
Проще говоря. Объект календаря хранит информацию о часовом поясе, но когда вы выполняете cal.getTime(), информация о часовом поясе будет потеряна. Поэтому для конверсий Timezone я советую использовать классы DateFormat...
Ответ 25
Используйте этот класс, чтобы получить доступное время 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);
Ответ 26
это моя реализация:
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();
}
Ответ 27
Если вы хотите избежать разбора даты и просто хотите отметки времени в GMT, вы можете использовать:
final Date gmt = new Timestamp(System.currentTimeMillis()
- Calendar.getInstance().getTimeZone()
.getOffset(System.currentTimeMillis()));
Ответ 28
Если вы используете время joda и хотите текущее время в миллисекундах без вашего локального смещения, вы можете использовать это:
long instant = DateTimeZone.UTC.getMillisKeepLocal(DateTimeZone.getDefault(), System.currentTimeMillis());
Ответ 29
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
Вы можете изменить формат даты по мере необходимости.
Ответ 30
Используйте пакет java.time и включите ниже code-
ZonedDateTime now = ZonedDateTime.now( ZoneOffset.UTC );
или же
LocalDateTime now2 = LocalDateTime.now( ZoneOffset.UTC );
в зависимости от необходимости вашего приложения.