Як я можу отримати поточну дату та час у UTC чи GMT на Java?


479

Коли я створюю новий Dateоб'єкт, він ініціалізується на поточний час, але в локальному часовому поясі. Як я можу отримати поточну дату та час у GMT?


Я знаю, що ці теми обговорюються повністю, але я виявив, що пакет «commons-lang» справді добре справляється з цими поширеними проблемами Java. commons.apache.org/lang/api-2.5/org/apache/commons/lang/time Ознайомтеся з різними пакетами, які вони мають.

Який місцевий час ви хочете і з якою точністю. Більшість часових поясів визначаються відносно UTC з фіксованим зміщенням, виміряним у СІ секундах, але співвідношення ГМТ, яке ґрунтується на сонячному спостереженні та (трохи) змінної довжини секунди, є складнішим. Вони відрізняються до 0,9 секунди.
mc0e

1
А Dateне містить часовий пояс, тому "але в локальному часовому поясі" невірно (або в кращому випадку неточне). Дивіться все про java.util.Date .
Оле VV

Відповіді:


409

java.util.Dateне має конкретного часового поясу, хоча його значення найчастіше продумується стосовно UTC. Чому ви думаєте, що це місцевий час?

Якщо бути точним: значення в межах a java.util.Date- це кількість мілісекунд після епохи Unix, що сталася опівночі 1 січня 1970 р., UTC. Таку саму епоху можна було б описати і в інших часових поясах, але традиційний опис є з точки зору UTC. Оскільки це минуло кілька мілісекунд з моменту фіксованої епохи, значення всередині світу java.util.Dateє однаковим у будь-який момент, незалежно від місцевого часового поясу.

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

Якщо це не проблема, будь ласка, опублікуйте зразок коду.

Однак я рекомендую вам використовувати Joda-Time у будь - якому випадку, що пропонує набагато чіткіший API.


5
То, мабуть, це проблема драйвера. Можливо, вам доведеться встановити ваше з'єднання на UTC, або щось подібне. Я бачив подібні проблеми раніше, але проблема не в java.util.Date.
Джон Скіт

13
Берег, відповідно до stackoverflow.com/questions/4123534/… , драйвер MySQL JDBC перетворює заданий java.util.Timestamp(або java.util.Date) часовий пояс сервера.
Дерек Махар

5
@Містер. Кіт: Як ви це визначаєте? Це написання System.out.println(new Date())? Якщо так, то вам слід знати, що саме toString()метод застосовує там часовий пояс ... якщо це не все, будь ласка, надайте більше деталей.
Джон Скіт

8
@KanagaveluSugumar: toString()завжди використовується часовий пояс за замовчуванням. date.getTime()Однозначно повертає мілісекунди з епохи Unix, в UTC. Найточніше сказати, що Dateсам по собі взагалі не має часового поясу - це лише момент у часі, який можна розглядати в декількох часових поясах. Але коли ви створюєте екземпляр, це не залежить від вашого часового поясу.
Джон Скіт

6
@Jemenake: Насправді цього не сталося, коли в Грінвічі була опівночі, тому що Великобританія в той час була на UTC + 1. Лише один із дивних бітів історії. Але я вважаю, що краще сказати "нова дата (). GetTime () повертає мілісекунди після епохи Unix, яка була опівночі на початку 1 січня 1970 року, UTC". Тож UTC є частиною закріплення епохи до певного моменту, а не частиною результату.
Джон Скіт

323

тл; д-р

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.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.toString(): " + now );

Під час запуску…

now.toString(): 2014-01-21T23:42:03.522Z

Таблиця типів дат і часу на Java, як сучасна, так і застаріла.


Про java.time

Java.time каркас вбудований в Java 8 і пізніших версій. Ці класи витісняти неприємні старі застарілі класи дати і часу , такі як java.util.Date, Calendar, і SimpleDateFormat.

Щоб дізнатися більше, дивіться навчальний посібник Oracle . І шукайте переповнення стека за багатьма прикладами та поясненнями. Специфікація - JSR 310 .

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

Ви можете обмінюватися об'єктами java.time безпосередньо зі своєю базою даних. Використовуйте драйвер JDBC, сумісний з JDBC 4.2 або пізнішої версії. Немає необхідності в струнах, немає потреби в java.sql.*заняттях.

Де отримати класи java.time?

Таблиця, яку бібліотеку java.time використовувати в якій версії Java або Android

Проект ThreeTen-Extra розширює java.time додатковими класами. Цей проект є передумовою для можливих майбутніх доповнень до java.time. Ви можете знайти деякі корисні класи тут , такі як Interval, YearWeek, YearQuarter, і більш .


Joda-Time

ОНОВЛЕННЯ: Проект 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 не має часового поясу. Крім того, часовий пояс закопаного не є тим, що використовується методом Дате toString; цей метод використовує поточний часовий пояс JVM за замовчуванням. Тим більше причин уникати цього заплутаного класу та дотримуватися Joda-Time та java.time.


2
DateTime.now().toDateTime(DateTimeZone.UTC)було те, що я шукав! Дякую!
Managarm

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

11
Чому ви розбираєтеся з dateFormatLocal після використання формату dateFormatGmt ... не має сенсу, читаючи його. Я впевнений, що це працює, але просто цікаво?
MindWire

2
setTimeZone зробив це (я думаю, ви можете також використовувати getTimeZone ("UTC") те саме, що GMT?)
rogerdpack

6
але час залежить від часу встановлення пристрою. Якщо користувач встановив неправильний час на своєму пристрої, ви отримаєте помилку UTC. Поправте мене, якщо я помиляюся
Basavaraj Hampali

@BasavarajHampali, але в сучасному світі більшість пристроїв підключені до Інтернету, що виправляє невірний час
Akshat Agarwal

3
Там немає різниці у часі між координованого часу (UTC) і середній час по Грінвічу (GMT)
Slott

86

Це безумовно повертає час 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;
}

У своїй відповіді я забув показати, як визначається DATEFORMAT: static final String DATEFORMAT = "yyyy-MM-dd HH:mm:ss";
Хтось десь

21
Будь ласка, уникайте імен методів запуску з великих літер на Java Див. Умови кодування Java для назв методів.
Флоріан Шрофнер

2
Як я переспрямований на цю відповідь, якщо дзвінок new Date()не відповідає правильному часу UTC , виклик ніколи не поверне правильний час UTC.
Sanoop

чи залежить цей метод від часу календаря пристрою?
Арнольд Браун

Одне зауваження. Будь-яке рішення, якому потрібно отримати дату або часову позначку в UTC, схоже, що ключовим є не повторне використання SimpleDateFormat, а скоріше використовувати один, щоб отримати UTC у рядок, а потім створити інший UTC при перетворенні рядка в будь-який дату або об’єкт відмітки часу. Я помітив, що якщо ви спробуєте повторно використовувати той же SimpleDateFormat, то отриманий об'єкт Date / Timestamp повернеться до локального часового поясу замість UTC.
Брайан Бігун

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

52

Насправді не час, але його представництво можна змінити.

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

Час однаковий у будь-якій точці Землі, але наше сприйняття часу може бути різним залежно від місця.


Так, приємне та чисте рішення. Мене просто хвилює, якщо неефективно створити новий об'єкт Date, а не просто отримати екземпляр календаря?
Бемо

Він буде оптимізований JVM, а HotSpot виконає найефективніший код x86
Антоніо,

17

Календар 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's not GMT.

17

Цей код друкує поточний час 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

14

Це працює для отримання UTC мілісекунд в Android.

Calendar c = Calendar.getInstance();
int utcOffset = c.get(Calendar.ZONE_OFFSET) + c.get(Calendar.DST_OFFSET);  
Long utcMilliseconds = c.getTimeInMillis() + utcOffset;

7
тільки вам потрібно відняти зміщення?
тевч

c.add(Calendar.MILLISECOND, (-utcOffset))щоб отримати Календар із часовим поясом utc
Shanavas M

10

Ось що, здається, є неправильним у відповіді Джона Скіта . Він сказав:

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

Однак код:

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

дає місцеві години, а не GMT ​​(UTC годин), використовуючи no Calendarі no SimpleDateFormatвзагалі.

Ось чому, здається, щось неправильно.

Збираючи разом відповіді, код:

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

показує GMT години замість місцевих годин - зауважте, що getTime.getHours()цього немає, оскільки це створило б Date()об’єкт, який теоретично зберігає дату в GMT, але повертає години в локальному часовому поясі.


6
Я раніше не бачив цієї відповіді, але якщо ви читаєте документацію щодо застарілого Date.getHours()методу, це дає зрозуміти: "Повернене значення - це число (від 0 до 23), що представляє годину протягом дня, що містить або починається з мить у часі, представлений цим об'єктом дати, як інтерпретується в локальному часовому поясі . " (Наголос моє.) Це 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 = 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));

1
Ви надто наполегливо працюєте. Joda-Time може це зробити в одному рядку коду. Дивіться мою власну відповідь на це питання. Викличте .toDateTimeметод та передайте константу для часового поясу UTC.
Василь Бурк

1
DateTime utcDate = new DateTime (). ToDateTime (DateTimeZone.UTC)
Maciej Miklas

6

Ви можете використовувати:

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

Тоді всі операції, що виконуються за допомогою об'єкта aGMTCalendar, будуть виконуватися з часовим поясом GMT і не застосовуватимуть літнього часу або фіксованого зміщення. Я думаю, що в попередньому плакаті правильно, що об’єкт Date () завжди повертає GMT, це не поки ви не підете робити щось із об'єктом дати, який він перетворює в локальний часовий пояс.


6
SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MM-dd");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(dateFormatGmt.format(date));

Додайте трохи пояснень до своєї відповіді, чим вона відрізняється від багатьох інших відповідей?
akjoshi

чи залежить цей метод від часу календаря пристрою?
Арнольд Браун

6

Ви можете безпосередньо використовувати це

SimpleDateFormat dateFormatGmt = new SimpleDateFormat("dd:MM:yyyy HH:mm:ss");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(dateFormatGmt.format(new Date())+"");

5

З:

Calendar cal = Calendar.getInstance();

Тоді calмати поточну дату та час.
Ви також можете отримати поточну дату та час для часового поясу за допомогою:

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

Ви можете запитати cal.get(Calendar.DATE);або іншу постійну інформацію про Календар про інші деталі.
Дата та мітка часу застаріли на Java. Календарного класу це не так.


6
Деякі методи та конструктори Date та Timestamp застаріли, але самі класи - ні.
Powerlord

5

Ось інша пропозиція отримати об’єкт GMT Timestamp:

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

Ось ще один спосіб отримати час GMT у форматі 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

Ось моя реалізація toUTC:

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

Напевно, існує кілька способів її покращити, але це працює для мене.


3

Зразок коду для візуалізації системного часу у конкретному часовому поясі та конкретному форматі.

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

Просто, щоб зробити це простішим, для створення Dateв ньому UTCви можете використовувати Calendar:

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

Який побудує новий екземпляр для Calendarвикористання "UTC" TimeZone.

Якщо вам потрібен Dateоб’єкт із цього календаря, ви можете просто використовувати getTime().


5
Якщо викликати getTime (), це втратить інформацію про часовий пояс і поверне місцевий час.
RealCasically

3

Перетворення поточного часу в 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

1
Ви робите тут занадто багато роботи. (a) формат форматера, який ви визначаєте, вже за замовчуванням вбудований у DateTime; просто зателефонуйте toStringна DateTime, щоб отримати цей рядок ISO 8601 . (b) Занадто багато коду для перетворення між часовими поясами. Просто зателефонуйте "toDateTime" та передайте об'єкт часового поясу. Як це: myDateTime.toDateTime( DateTimeZone.UTC ). Для конкретного часового поясу екземпляруйте та передайте об'єкт часового поясу на основі власного імені , зателефонуйте myDateTime.toDateTime( DateTimeZone.forID( "Asia/Tehran" ) ).
Василь Бурк

2

Це працювало для мене, повертає часову позначку в 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

Використовуйте цей клас, щоб отримати будь-коли потрібний час 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" як функція використання 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);

В одному рядку <br/> <pre> <code> Календар utcTime = Calendar.getInstance (). Додати (Calendar.MILLISECOND, -time.getTimeZone (). GetOffset (time.getTimeInMillis ())); </pre> < / код>
Харун

1
Так, але це викликає локальний час пристрою, який міг би вручну змінити користувача від фальшивого DateTime
Ingo


1

Якщо говорити просто. Об'єкт календаря зберігає інформацію про часовий пояс, але коли ви виконайте cal.getTime (), інформація про часовий пояс буде втрачена. Тому для перетворень Timezone я пораджу використовувати класи DateFormat ...


1

це моя реалізація:

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

Якщо ви хочете уникнути розбору дати та просто хочете позначити часову позначку в GMT, ви можете використовувати:

final Date gmt = new Timestamp(System.currentTimeMillis()
            - Calendar.getInstance().getTimeZone()
                    .getOffset(System.currentTimeMillis()));

0

Якщо ви використовуєте час joda і хочете поточний час у мілісекундах без локального зміщення, ви можете скористатися цим:

long instant = DateTimeZone.UTC.getMillisKeepLocal(DateTimeZone.getDefault(), System.currentTimeMillis());

0
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

Ви можете змінити формат дати за потребою.


1
Будь ласка, не вчіть молодих людей користуватися давно застарілими та сумно відомими SimpleDateFormat. Сьогодні ми набагато краще java.timeвживаємо сучасний API дати та часу Java . Крім того, що ви надаєте, що ще не є відповідями Дена, Антоніо та інших?
Оле ВВ

2
(а) Як ця відповідь додає значення для десятків існуючих відповідей? (b) Використовувані тут клопітні класи були витіснені років тому сучасними класами java.time . Запропонувати їх використання у 2018 році - це погана порада.
Василь Бурк

0

Використовуйте пакет java.time та додайте нижче код-

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

або

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

залежно від вашої заявки.


(A) Якщо використовується зсув ( ZoneOffset), а не часовий пояс ( ZoneId), то OffsetDateTimeбільш доцільним є ZonedDateTime. (B) LocalDateTimeне слід використовувати для фіксації поточного моменту, оскільки він не має поняття часового поясу або зміщення з-за UTC. (C) Інші попередні відповіді висвітлили цей матеріал і зробили кращу роботу. Я не бачу, як ця відповідь додає цінності.
Василь Бурк
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.