Время Joda DateTime конвертировано в java.util.Date странная проблема

У меня возникла странная проблема. Вот фрагмент кода, который описывает его:

DateTimeZone dtz = DateTimeZone.forOffsetHours(0);

DateTime dt = new DateTime(dtz);

System.out.println(dt);
System.out.println(dt.toDate());

вывод:

2012-02-29T17:24:39.055Z
Wed Feb 29 19:24:39 EET 2012

Я нахожусь UTC + 2, но это действие должно создать объект java.util.Date, который инициализируется для времени UTC. Что мне не хватает?

Ответ 1

Date вообще не знает о часовом поясе - он представляет только момент времени (например, тип времени Joda Instant). Это всего лишь миллисекунды с эпохи Unix. Когда вы вызываете Date.toString(), он всегда использует локальный часовой пояс системы для преобразования этого в читаемую текстовую форму.

Таким образом, здесь нет ничего плохого - просто неудача ожиданий по значению java.util.Date или его поведения toString() или того и другого.

(В стороне, предпочитайте DateTimeZone.UTC над созданием собственного.)

Ответ 2

Чтобы получить JDK Date, который соответствует Joda DateTime, сначала конвертировать в LocalDateTime.

Как объясняется в других ответах, время в миллисекундах не изменяется в зависимости от часового пояса:

DateTime local = DateTime.now()
Date localJDK = local.toDate()
assert localJDK.getTime() == local.toInstant().getMillis()

DateTime differentTimeZone = DateTime.now(DateTimeZone.forID('America/Chicago'))
Date localJDK2 = differentTimeZone.toDate()
assert differentTimeZone.toInstant().getMillis() == localJDK2.getTime()
assert localJDK.getTime() == localJDK2.getTime()

Преобразование a LocalDateTime в Date изменит это:

Date differentTimeZoneJDK = differentTimeZone.toLocalDateTime().toDate()
assert localJDK.getTime() != differentTimeZoneJDK.getTime()

Ответ 3

Поведение, которое вы хотите, следующее:

Дата jdkDate = new SimpleDateFormat ( "yyyy-MM-dd HH: mm: ss" ). parse (dt.toString( "yyyy-MM-dd HH: mm: ss" ));

Как отметил Джон, дата JDK является часовым поясом агностиком. Надеюсь, это поможет кому-то.