Благодаря ответу VGR мне удалось выяснить, что пошло не так внутри XMLGregorianCalendarImpl
.
Взгляните на конструктор:
public XMLGregorianCalendarImpl(GregorianCalendar cal) {
int year = cal.get(Calendar.YEAR);
if (cal.get(Calendar.ERA) == GregorianCalendar.BC) {
year = -year;
}
this.setYear(year);
// Calendar.MONTH is zero based, XSD Date datatype's month field starts
// with JANUARY as 1.
this.setMonth(cal.get(Calendar.MONTH) + 1);
this.setDay(cal.get(Calendar.DAY_OF_MONTH));
this.setTime(
cal.get(Calendar.HOUR_OF_DAY),
cal.get(Calendar.MINUTE),
cal.get(Calendar.SECOND),
cal.get(Calendar.MILLISECOND));
// Calendar ZONE_OFFSET and DST_OFFSET fields are in milliseconds.
int offsetInMinutes = (cal.get(Calendar.ZONE_OFFSET) + cal.get(Calendar.DST_OFFSET)) / (60 * 1000);
this.setTimezone(offsetInMinutes);
}
В основном, что он делает, - сопоставить все внутренние поля GregorianCalendar
с внутренними полями.например, год, месяц, день, час, минута, секунда, миллисекунда.
И, наконец, он отображает часовой пояс.Обратите внимание, что объект GregorianCalendar
сохраняет свой часовой пояс в миллисекундах, в то время как XMLGregorianCalendarImpl
сохраняет его в минутах. Во время этого преобразования он просто отбрасывает оставшиеся секунды и миллисекунды. И вот в чем проблема, у календаря может быть часовой пояс с секундами.
И это подводит нас к следующему примеру:дата "1900-01-01T12:00:00"
в часовом поясе ECT.Это фактически имеет смещение зоны 561000 миллисекунд.т.е. 9 минут и 21 секунда.Но xml григорианский просто игнорирует 21 секунду.
Если у часового пояса есть миллисекунды, лучше вывести дату без часового пояса.
private String toXml(Date dts) {
DatatypeFactory df = DatatypeFactory.newInstance();
GregorianCalendar gc = new GregorianCalendar();
gc.setTime(dts);
XMLGregorianCalendar xc = df.newXMLGregorianCalendar(gc2);
int zoneOffsetInMillis = gc.get(Calendar.ZONE_OFFSET);
boolean zoneHasMillis zoneOffsetInMillis % (60 * 1000) != 0;
if (zoneHasMillis) xc.setTimezone(0);
return xc.toXMLFormat();
}
Пример:
1900-01-01T12:00:00+02:00
становится 1900-01-01T10:09:21.000
РЕДАКТИРОВАТЬ:
Я на самом деле нашел историческую причину этого изменения времени 9 минут и 21 секунд:
В Британии 'Железнодорожное время »было введено в 1840-х годах для синхронизации местных часов с расписанием поездов, которое в 1880 году было заменено единым временем по Гринвичу. В 1891 году Франция приняла Парижское среднее время в качестве стандартного национального времени.Часы на железнодорожных станциях и расписание поездов были установлены на пять минут позже, чтобы пассажиры не опоздали на свои поезда.
В 1911 году парижское среднее время было изменено на 9 минут 21 секунду для синхронизации со средним временем по Гринвичу.Он по-прежнему назывался Парижским средним временем, в котором не использовалось слово «Гринвич».
источник: https://vanessafrance.wordpress.com/2012/03/25/a-brief-history-of-french-time/