Как правильно преобразовать миллисекунды в соответствующую дату?

У меня проблема с датами.

Я уверен, что эти миллисекунды 1317322560000 представляют собой дату четверга, 29 сентября, 18:56:00 по Гринвичу + 02:00 2011 года в Италии.

Но с помощью класса Calendar дата — четверг, 29 сентября, 20:56:00 по Гринвичу + 02:00. Я думаю, это происходит потому, что действует летнее расписание.

как я могу преобразовать миллисекунды в соответствующую дату правильно?


person Gioacchino Del Prete    schedule 28.10.2011    source источник
comment
Откуда вы получаете четверг, 29 сентября, 18:56:00 GMT+02:00?   -  person kgautron    schedule 28.10.2011
comment
Из System.currentTimeMillis()   -  person Gioacchino Del Prete    schedule 28.10.2011
comment
Пожалуйста, примите некоторые ответы. Если ответ правильный, вы можете принять его.   -  person Matthew Farwell    schedule 28.10.2011


Ответы (3)


System.currentTimeMillis() возвращает «разницу, измеренную в миллисекундах, между текущим временем и полуночью 1 января 1970 года по всемирному координированному времени». (то есть по Гринвичу).

Итак, «Дата» 1317322560000 у вас есть 29.09.2011:18:56:00 по Гринвичу. В Италии 29 сентября смещение от GMT составляет +2 часа (из-за «летнего времени» или, технически говоря, DST = Летнее время). С 30.10.2011:03:00:00 (кстати, в следующее воскресенье) в Италии будет «зимнее время» (без летнего времени), поэтому смещение будет +1).

Таким образом, вы правильно получаете Чт, 29 сентября, 20:56:00 CEST 2011 (18:56:00 + смещение на 2 часа по часовому поясу Италии). Пожалуйста, проверьте этот код, который показывает все это (это Groovy).

import java.text.DateFormat
import java.util.TimeZone

println Locale.getDefault()
Date d = new Date(1317322560000)
println d
Locale.setDefault(new Locale("it", "IT"))
println Locale.getDefault()

DateFormat df = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL);
println df.getTimeZone().getOffset(1317322560000) + " => +2h offset in 'summer time' (DST on)"

df.setTimeZone(TimeZone.getTimeZone("GMT+00:00"))
println df.format(d)
df.setTimeZone(TimeZone.getTimeZone("GMT+01:00"))
println df.format(d)
df.setTimeZone(TimeZone.getTimeZone("GMT+02:00"))
println df.format(d)
df.setTimeZone(TimeZone.getTimeZone("Europe/Rome"))
println df.format(d)
println "---"

Date winterDate = new Date(1321382560000)
println winterDate
println df.getTimeZone().getOffset(1321382560000) + " => +1h offset in 'winter time' (DST off)"

Результат этого:

es_ES
Thu Sep 29 20:56:00 CEST 2011
it_IT
7200000 => +2h offset in 'summer time' (DST on)
giovedì 29 settembre 2011 18.56.00 GMT+00:00
giovedì 29 settembre 2011 19.56.00 GMT+01:00
giovedì 29 settembre 2011 20.56.00 GMT+02:00
giovedì 29 settembre 2011 20.56.00 CEST
---
Tue Nov 15 19:42:40 CET 2011
3600000 => +1h offset in 'winter time' (DST off)
person jalopaba    schedule 28.10.2011
comment
Вы также можете проверить stackoverflow.com/questions/308683/ - person jalopaba; 28.10.2011
comment
Это нормально, но если я хочу создать календарь из этого формата данных и когда я запрашиваю дату, результат будет 20,56. - person Gioacchino Del Prete; 28.10.2011
comment
Он будет отображать 18:56, если часовой пояс GMT+00:00, 19:56, если часовой пояс GMT+01:00, и 20:56, если часовой пояс GMT+02:00, как в вашем случае. Вы не сможете получить другой результат, если ваш часовой пояс GMT+2. Итак, я предполагаю, что когда вы получили 18:56, вы запускали код с часовым поясом, установленным на GMT+0. - person jalopaba; 29.10.2011

new Date(1317322560000l)

выходы

Thu Sep 29 20:56:00 CEST 2011

так же, как ваш календарь. Почему это должно быть 18:56?

person kgautron    schedule 28.10.2011
comment
Да, но результат не изменится - person Gioacchino Del Prete; 28.10.2011
comment
Почему эти миллисекунды были записаны ровно в 18:56 в Италии - person Gioacchino Del Prete; 28.10.2011
comment
Я думаю, что с System.currentTimeMillis() - person Gioacchino Del Prete; 28.10.2011
comment
Это означает, что если бы вы сделали новую дату (System.currentTimeMillis()) в 18:56, она отобразила бы 20:56. Можете ли вы попробовать сейчас, чтобы увидеть, есть ли такой же 2-часовой разрыв? - person kgautron; 28.10.2011
comment
Я пробую сейчас System.currentTimeMillis(), и результат: пятница, 28 октября, 11:32:24 по Гринвичу + 02:00 2011, и это нормальная дата !!! - person Gioacchino Del Prete; 28.10.2011
comment
Могу ли я преобразовать дату в миллисекундах GMT +0000 без учета летнего времени? - person Gioacchino Del Prete; 28.10.2011
comment
1317322560000 миллисекунд — это GMT+0000. - person Gioacchino Del Prete; 28.10.2011

Это действительно четверг, 29 сентября, 20:56:00 GMT+02:00. т. е. соответствующая дата-время в формате UTC: Thu Sep 29 18:56:00Z, где Z означает Zulu и обозначение часового пояса для нулевого смещения часового пояса (смещение +00:00 часов или часовой пояс Etc/UTC).

Решение с использованием java.time, современного API

import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        Instant instant = Instant.ofEpochMilli(1317322560000L);

        // In Rome
        ZonedDateTime zdtRome = instant.atZone(ZoneId.of("Europe/Rome"));
        System.out.println(zdtRome);

        // In UTC
        ZonedDateTime zdtUtc = instant.atZone(ZoneId.of("Etc/UTC"));
        System.out.println(zdtUtc);

        // Custom format
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("EEE MMM dd uuuu HH:mm:ssXXX", Locale.ENGLISH);
        System.out.println(zdtRome.format(dtf));
        System.out.println(zdtUtc.format(dtf));
    }
}

Вывод:

2011-09-29T20:56+02:00[Europe/Rome]
2011-09-29T18:56Z[Etc/UTC]
Thu Sep 29 2011 20:56:00+02:00
Thu Sep 29 2011 18:56:00Z

Узнайте больше о современном API даты и времени* из Trail: Date Time< /а>.


* По какой-либо причине, если вам нужно придерживаться Java 6 или Java 7, вы можете использовать ThreeTen-Backport, который переносит большую часть функций java.time на Java 6 и 7. Если вы работаете над проектом Android и ваш уровень Android API по-прежнему не соответствует Java-8, проверьте Java 8+ API доступно через дешугаринг и Как использовать ThreeTenABP в Android Project.

person Arvind Kumar Avinash    schedule 16.05.2021