Khi thử nghiệm dịch vụ web ánh xạ các loại ngày giờ giữa các hệ thống, tôi nhận thấy rằng việc gửi bất kỳ ngày nào trước thời gian bắt đầu của lịch Gregorian dẫn đến mất độ chính xác khi truyền sang loại cuối cùng kết quả cuối cùng luôn đi trước một chút trong khoảng thời gian vài ngày.Thay đổi ngày khi chuyển đổi từ XMLGregorianCalendar sang Lịch
tôi thu hẹp vấn đề vào dòng chính xác, nhưng tôi vẫn không thể tìm ra tại sao nó được đúc như vậy, từ documentation nó khẳng định rằng lịch Julian được sử dụng cho datetimes trước khi bắt đầu lịch Gregorian: 15 tháng 10, 1582.
dòng vấn đề là tại các diễn viên từ XMLGregorianCalendar
để GregorianCalendar
, dòng 78: calendarDate = argCal.toGregorianCalendar();
Khi thời gian được lấy từ calendarDate
trên dòng 86: cal.setTime(calendarDate.getTime());
Hiện trở lại 2 ngày trước những gì nó phải được , Ngày 03 tháng 1 thay vì ngày 01 tháng 1, như bạn sẽ thấy từ đầu ra trong chương trình bên dưới.
Dưới đây là một chương trình mẫu tôi đã thực hiện để hiển thị các quá trình đúc kết thúc để kết thúc:
import java.sql.Date;
import java.util.Calendar;
import java.util.GregorianCalendar;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
public class TestDateConversions {
public static void main(String[] args)
{
TestDateConversions testDates = new TestDateConversions();
try
{
XMLGregorianCalendar testDate1 = DatatypeFactory.newInstance().newXMLGregorianCalendar();
testDate1.setYear(0001);
testDate1.setMonth(01);
testDate1.setDay(01);
System.out.println("Start date: "+testDate1.toString() +"\n**********************");
testDates.setXMLGregorianCalendar(testDate1);
System.out.println("\nNull given \n"+ "**********");
testDates.setXMLGregorianCalendar(null);
}
catch(Exception e)
{
System.out.println(e);
}
}
public void setXMLGregorianCalendar(XMLGregorianCalendar argCal)
{
GregorianCalendar calendarDate;
if (argCal != null)
{
calendarDate = argCal.toGregorianCalendar();
System.out.println("XMLGregorianCalendar time: " + argCal.getHour() + ":"+argCal.getMinute()+":"+argCal.getSecond());
System.out.println("XMLGregorianCalendar time(ms): "+argCal.getMillisecond());
System.out.println("XMLGregorianCalendar -> GregorianCalendar: "+calendarDate.get(GregorianCalendar.YEAR) + "-"+(calendarDate.get(GregorianCalendar.MONTH)+1) + "-"+calendarDate.get(GregorianCalendar.DAY_OF_MONTH));
System.out.println("!!!!PROBLEM AREA!!!!");
Calendar cal = Calendar.getInstance();
System.out.println("-- New Calendar instance: "+cal.get(Calendar.YEAR) + "-"+(cal.get(Calendar.MONTH)+1)+"-"+cal.get(Calendar.DAY_OF_MONTH));
System.out.println("-- Calling Calendar.setTime(GregorianCalendar.getTime())");
cal.setTime(calendarDate.getTime());
System.out.println("-- calendarDate.getTime() = " + calendarDate.getTime() + " <-- time is incorrect");
System.out.println("-- Calendar with time set from GregorianCalendar: "+cal.get(Calendar.YEAR) + "-"+(cal.get(Calendar.MONTH)+1)+"-"+cal.get(Calendar.DAY_OF_MONTH) + " <-- day is increased here");
setCalendar(cal);
}
else
{
setCalendar(null);
}
}
public void setCalendar(Calendar argCal)
{
if (argCal != null)
{
Date date = new Date(argCal.getTimeInMillis());
System.out.println("Calendar to Date: "+date);
setDate(date);
}
else
{
setDate(null);
}
}
public void setDate(Date argDate)
{
try
{
if (argDate == null)
{
Calendar cal = new GregorianCalendar(1,0,1);
Date nullDate = new Date(cal.getTimeInMillis());
System.out.println("Null Calendar created: "+cal.get(Calendar.YEAR) + "-"+(cal.get(Calendar.MONTH)+1)+"-"+cal.get(Calendar.DAY_OF_MONTH));
System.out.println("Null Date created: "+nullDate);
}
else
{
System.out.println("Final date type: "+argDate);
}
}
catch (Exception ex)
{
System.out.println(ex);
}
}
}
FWIW: Lịch Julian không biến mất ngay lập tức vào năm 1582. Có thể phần mềm này thực sự làm điều đó (một ý tưởng tồi IMO), nhưng mã hệ thống cơ bản có thể không. Xin vui lòng cho chúng tôi một ví dụ chính xác (ngày cũ, ngày dự kiến, ngày kết quả). –
@jimmcnamara Tôi không nói bất cứ điều gì đã biến mất, tôi chỉ ra rằng bất kỳ ngày nào * trước * thời gian Gregorian đang được thay đổi. Ví dụ chính xác của tôi là khá rõ ràng có trong mã chương trình, ngày '0001-01-01' đang được thay đổi thành' 0001-01-03', và nó không nên. – JWiley
Được rồi - nói thật, điều này có vẻ như là một vấn đề trong thư viện. Như một giả thuyết, giả sử nó đang cố gắng sử dụng lịch Proleptic. Nó vẫn còn từ Julian bởi số tiền sai. Bạn hoàn toàn chính xác. http://calendars.wikia.com/wiki/Proleptic_Gregorian_calendar - –