чи повертає System.currentTimeMillis () час UTC?


93

Я хочу отримати поточний час UTC у мілісекундах. Я шукав google і отримав відповіді на те, що System.currentTimeMillis () повертає час UTC. але це не так. Якщо я роблю наступне:

long t1 = System.currentTimeMillis();
long t2 = new Date().getTime();
long t3 = Calendar.getInstance().getTimeInMillis();

усі три рази майже однакові (різниця в мілі секундах через дзвінки).

t1 = 1372060916
t2 = 1372060917
t3 = 1372060918

і цей час не час UTC, натомість це мій часовий пояс. Як я можу отримати поточний час UTC в android?


4
Повертає поточний системний час у мілісекундах з 1 січня 1970 р. 00:00:00 UTC
Блекбелт,


3
long t3 = Calendar.getInstance (TimeZone.getTimeZone ("UTC")). getTimeInMillis ();
Blackbelt

3
У наведеному вище посиланні сказано: "Див. Опис дати курсу для обговорення незначних розбіжностей, які можуть виникнути між" комп’ютерним часом "та координованим універсальним часом (UTC)". і в документації java.util.Date ви знаходите: "Хоча клас Date призначений для відображення узгодженого універсального часу (UTC), він може робити це не точно, залежно від середовища хосту віртуальної машини Java" -> тому він може можливо, щоб ваша машина повертала час, що не за UTC
Марко Форберг,

4
@ g.revolution: Це "кількість мілісекунд з 1 січня 1970 р. 00:00:00 UTC" - як ви очікуєте, що це налаштується на часовий пояс? Місцевий часовий пояс не впливає на кількість мілісекунд, що відбулися з тієї епохи.
Джон Скіт,

Відповіді:


132

Усі три рядки, які ви показали, дадуть кількість мілісекунд з епохи unix, яка є фіксованим моментом часу, не залежачи від вашого місцевого часового поясу.

Ви кажете "цей час не час UTC" - я підозрюю, що ви насправді діагностували це неправильно. Я б запропонував використовувати epochconverter.com для цього. Наприклад, у вашому прикладі:

1372060916 = Mon, 24 Jun 2013 08:01:56 GMT

Ми не знаємо, коли ви створили це значення, але якщо це насправді не було о 8:01 ранку за UTC, це проблема з вашим системним годинником.

Ні , System.currentTimeMillisні вартість в Dateсобі страждають від тимчасової зони. Тим НЕ менше, ви повинні знати , що Date.toString() робить використання локального часового поясу, який вводить в оману багатьох розробників в мисленні , що Dateневід'ємно пов'язані з часовим поясом - це не так , це просто момент часу, без відповідної тимчасової зони або навіть системи календаря.


6
Отже, в основному, це означає, що ця функція повертає одне і те ж значення, якщо викликана одночасно з різних часових поясів, незалежно від годинника хоста, правильно?
Філіп

14
Людина це змушує мене хотіти, щоб світ (міг) прийняти єдиний часовий пояс. Кому цікаво, чи на годиннику є цифра 00:00 чи 08:00, коли на небі з’являється велика яскрава річ? Безлічі годин продуктивного часу, витраченого на цю історичну реліквію, змушує мою кров кипіти ...
corsiKa

У зв'язку з цим зауважте, що основний виклик функції годинника ОС має задокументований "дрейф" у кілька мілісекунд. Java має "високопродуктивний таймер", якщо метою є отримання дуже точної тривалості операції (час, коли завдання починається і закінчується, дельта - це проміжок часу). Див .: docs.oracle.com/javase/7/docs/api/java/lang/…
Даррелл Тіг

@JonSkeet if toString () внутрішньо використовує часовий пояс, як я міг побудувати з нього рядок без часового поясу. Насправді я генерую файл на сервері REST, який має ім'я файлу рівно північного значення часу, наприклад "1551139200.json" (26 лютого 2019 р., 00:00:00), і до якого потрібно отримати доступ із програми Android після того, як System.currentTimeMillis пристрою. повертає точний час.
кіранкінг

@kiranking: Використовуйте Date.getTime()для пошуку часу мілісекунд з часу Unix-епохи, розділіть на 1000 (оскільки це ім'я файлу в секундах після епохи Unix) і просто відформатуйте ціле число як рядок.
Джон Скіт,

3

Я можу підтвердити, що всі три дзвінки можуть залежати від місцевого часу, враховуючи епоху, а не той Date.toString()чи інший подібний метод. Я бачив, як вони залежать від місцевого часу на певних пристроях з ОС Android 2.3. Я не тестував їх на інших пристроях та версіях Android. У цьому випадку місцевий час встановлювався вручну.

Єдиним надійним способом отримати незалежний час UTC є запит на оновлення місцезнаходження за допомогою GPS_PROVIDER. getTime()Значення місця розташування , витягнуте з NETWORK_PROVIDERтакож залежить від місцевого часу. Інший варіант - ping сервера, який повертає, наприклад, часову мітку UTC.

Отже, я роблю наступне:

public static String getUTCstring(Location location) {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
    String date = sdf.format(new Date(location.getTime()));
    // Append the string "UTC" to the date
    if(!date.contains("UTC")) {
        date += " UTC";
    }
    return date;
}

1
System.currentTimeMillis () повертає значення на основі UTC. Що стосується "точності" або точності годинника операційної системи, хоча це, безумовно, впливає на результат, жодним чином не пов'язане із значенням часового поясу системи або середовища Java.
Darrell Teague,

@DarrellTeague Я наполягаю, що я бачив різні значення в конкретному пристрої Huawei. Так що ні, це не завжди повертає правильний час UTC (відкидаючи різницю в точності)
jlhonora

Питання OP стосувалося використання часового поясу класу Java. Мова не йшла про апаратне забезпечення або точність поверненого значення часу. Простіше кажучи, JVM отримує свій час від (абстрактного) операційного "системного годинника" (який залежить від операційної системи з точки зору того, як вона функціонує). Дивіться також: drdobbs.com/embedded-systems / ... і «C» реалізації на операційних системах chemie.fu-berlin.de/chemnet/use/info/libc/libc_17.html
Даррелл Тіг
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.