You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by "apollo13@tin.it" <ap...@tin.it> on 2014/05/03 17:04:14 UTC

R: Re: Julian to Gregorian calendar Switch. CXF behavior managing dates before 15/10/1582

Hi,
I tried the following JUnit test, based on your example:
    @Test
    public void parseDateTest() {
        String dateToParse = "1582-10-14";
        System.out.println("initial string to parse: " + dateToParse);
        
        Calendar calendar = parseDateTime(dateToParse);
        System.out.println("parsed GregorianCalendar: DAY_OF_MONTH ["+calendar.get(Calendar.DAY_OF_MONTH)+"], MONTH ["+calendar.get(Calendar.MONTH)+"], YEAR ["+calendar.get(Calendar.YEAR)+"]");
        
        Date date = calendar.getTime();
        System.out.println("parsed java.util.Date: " + date);
    }
    private Calendar parseDateTime(String lexicalXSDDateTime) {
        return  _parseDateTime(lexicalXSDDateTime);
    }
    private static GregorianCalendar _parseDateTime(CharSequence s) {
        DatatypeFactory datatypeFactory = null;
        try {
            datatypeFactory = DatatypeFactory.newInstance();
        } catch (DatatypeConfigurationException e) {
            e.printStackTrace();
        }
        
        String val = WhiteSpaceProcessor.trim(s).toString();
        return datatypeFactory.newXMLGregorianCalendar(val).toGregorianCalendar();
    }

The result was:
initial string to parse: 1582-10-14
parsed GregorianCalendar: DAY_OF_MONTH [14], MONTH [9], YEAR [1582]
parsed java.util.Date: Thu Oct 04 00:00:00 CET 1582

Now, the gregorian calendar starts on 15 Oct 1582 and in this example we see that the parsed GregorianCalendar correctly represents in the gregorian calendar system a date preceding its start date.
We see also that when the GregorianCalendar is converted into java.util.Date the date is correctly represented in julian calendar system, at that epoch 10 days less. 

The following is an extract from java.util.GregorianCalendar where the change date is defined.
"
    /**
     * The point at which the Gregorian calendar rules are used, measured in
     * milliseconds from the standard epoch.  Default is October 15, 1582
     * (Gregorian) 00:00:00 UTC or -12219292800000L.  For this value, October 4,
     * 1582 (Julian) is followed by October 15, 1582 (Gregorian).  This
     * corresponds to Julian day number 2299161.
     * @serial
     */
    private long gregorianCutover = DEFAULT_GREGORIAN_CUTOVER;
"

Anyway, I didn't understand yet what apache cxf unmarshaller does and the logic used by the JDK.
What do you think?
Is the code extract you posted a part of the apache cxf real code, or very similar?
Is it normal that a date prior then 15 Oct 1582 is automatically converted in Date using the julian calendar system?




----Messaggio originale----
Da: dkulp@apache.org
Data: 30-apr-2014 18.52
A: <us...@cxf.apache.org>, <ap...@tin.it>
Ogg: Re: Julian to Gregorian calendar Switch. CXF behavior managing dates before 15/10/1582


On Apr 29, 2014, at 3:04 PM, Marco <ap...@tin.it> wrote:

> Thank you very much. This canbe a good solution.
> Do you know if some documentation exists that explain the CXF unmarshal  behaviour?
> Do you think this can be a bug?
> 

This may be a bug in JAXB or possibly even in the JDK.    In this case, the code that SHOULD be called would be in javax.xml.bind.DatatypeConverterImpl:  (in the JDK or jaxb-api jars)

    public Calendar parseDateTime(String lexicalXSDDateTime) {
        return _parseDateTime(lexicalXSDDateTime);
    }
    public static GregorianCalendar _parseDateTime(CharSequence s) {
        String val = WhiteSpaceProcessor.trim(s).toString();
        return datatypeFactory.newXMLGregorianCalendar(val).toGregorianCalendar();
    }

That would then in turn call the javax.xml.datatype.DatatypeFactory methods (again, in the JDK or possibly xerces jar or similar).

You could try sending in your strings into those methods and seeing what results.  If the result is the incorrect dates, you could log a bug with Oracle about them.


Dan










> ...
> 
> 
> Il 28/04/2014 16:30, Hart, Andrew B. ha scritto:
>> I believe that it is JAXB that defaults to a Gregorian calendar.
>> In any case, I think the best way to get full control of this is to create an XMLAdapter and annotate your field like this:
>> 
>>     /**
>>      * @return the allergyStartDate
>>      */
>>     @XmlJavaTypeAdapter(com.akimeka.ws.common.DateAdapter.class)
>> 
>> So, here is an example of an XmlAdapter that accepts dates in a variety of acceptable formats.   It uses org.apache.commons.lang.time.DateUtils.
>> As seen in the marshal method, it emits dates using the DEFAULT_DATEFORMAT_STRING format.
>> 
>> You can change this up as needed.  You just need to implement the marshal and unmarshal methods.
>> Hope this helps.
>> 
>> -- Andy
>> 
>> /**********************************************************************/
>> public class DateAdapter extends XmlAdapter<String, Date>
>> {
>> 
>>     private static final Logger log = Logger.getLogger(DateAdapter.class);
>>     final static protected String DEFAULT_DATEFORMAT_STRING = "MM-dd-yyyy";
>>     final static protected String[] ACCEPTABLE_INPUT_FORMATS = {DEFAULT_DATEFORMAT_STRING, "yyyy-MM-dd", "MM/dd/yyyy", "yyyy-MM-dd HH:mm", "yyyy-MM-dd HH:mm:ss","yyyy-MM-dd'T'HH:mm:ss"};
>> 
>>     @Override
>>     public Date unmarshal(String v) throws Exception
>>     {
>> 
>>         if (log.isDebugEnabled())
>>             log.debug("com.akimeka.ws.common.DateAdapter unmarshalling [" + v + "]");
>>         Date returnDate = DateUtils.parseDateStrictly(v, ACCEPTABLE_INPUT_FORMATS);
>>         if (log.isDebugEnabled())
>>                 log.debug("com.akimeka.ws.common.DateAdapter parsed date: " + returnDate);
>>         return returnDate;
>>     }
>> 
>>     @Override
>>     public String marshal(Date v) throws Exception
>>     {
>>         if (log.isDebugEnabled())
>>             log.debug("com.akimeka.ws.common.DateAdapter marshalling [" + v + "]");
>>         if (v == null) return "";
>>         DateFormat outputFormat = new SimpleDateFormat(DEFAULT_DATEFORMAT_STRING);
>>         return outputFormat.format(v);
>>     }
>> 
>> }
>> /**********************************************************************/
>> 
>> -----Original Message-----
>> From: Perelum [mailto:apollo13@tin.it]
>> Sent: Sunday, April 27, 2014 10:36 AM
>> To: users@cxf.apache.org
>> Subject: Julian to Gregorian calendar Switch. CXF behavior managing dates before 15/10/1582
>> 
>> I'm building a web service in java, deploying it under Jboss-as-7.1.1.Final, based on org.apache.cxf 2.4.6.
>> 
>> I need to expose a web method that takes in input a date field that can reach many centuries in the past. At the moment I'm using java.util.Date in my request bean. So, my web method is
>> 
>> /public UpdatePersonResponse updatePerson(UpdatePersonRequest request) { ...
>> }/
>> 
>> The request bean UpdatePersonRequest has the date field, with getter and
>> setter:
>> 
>> /...
>> private Date birthday;
>> .../
>> 
>> In the soap request that I'm testing I put:
>> 
>> /
>> <birthday>1452-04-15</birthday>/
>> 
>> The apache cxf logs show:
>> 
>> /16:07:36,568 INFO  [org.apache.cxf.interceptor.LoggingInInterceptor] ...
>> Inbound Message
>> [...]
>> <birthday>1452-04-15</birthday>/
>> 
>> (this is correct)
>> 
>> A custom log I added into the set method of the request bean shows:
>> /
>> 16:07:36,843 DEBUG  com.xxx.xxx.service.request.UpdatePersonRequest ...
>> called setBirthday with argument [06/04/52 0.00]/
>> 
>> (this is wrong)
>> 
>> Then the request bean is valorized as follows:
>> 
>> /UpdatePersonRequest [... birthday=Thu Apr 06 00:00:00 CET 1452, ...]/
>> 
>> (this is wrong)
>> 
>> So I obtain 1452 April 06, and not 1452 April 15.
>> 
>> I tried with different dates, for example, soap:
>> 
>> /<birthday>1452-04-30</birthday>/
>> 
>> custom log:
>> 
>> /21:11:51,607 DEBUG  [com.xxx.xxx.service.request.UpdatePersonRequest]  ...
>> called setBirthday with argument [21/04/52 0.00]/
>> 
>> (wrong)
>> 
>> The bean is valorized with:
>> 
>> /UpdatePersonRequest [... birthday=Fri Apr 21 00:00:00 CET 1452 ...]/
>> 
>> (again wrong)
>> 
>> *I obtain April 21 and not April 30*, with *9 days of difference*.
>> 
>> I tried with several dates and noticed that this behavior occurs for dates prior then *15/10/1582*, that is the historical start date for the Gregorian Calendar.
>> >From 15/10/1582 onward the request bean is valorized with the exact date I enter in the soap request.
>> 
>> So, I don't understand what is the logic used by Apache Cxf. Does it assume that the incoming request contains a date expressed in Gregorian calendar and then convert it into Julian date for dates prior that 15/10/1582? If it is so, why does such a conversion is performed?
>> 
>> Thank you very much.
>> 
>> 
>> 
>> 
>> 
>> 
>> 
>> --
>> View this message in context: http://cxf.547215.n5.nabble.com/Julian-to-Gregorian-calendar-Switch-CXF-behavior-managing-dates-before-15-10-1582-tp5743333.html
>> Sent from the cxf-user mailing list archive at Nabble.com.
>> 
> 

-- 
Daniel Kulp
dkulp@apache.org - http://dankulp.com/blog
Talend Community Coder - http://coders.talend.com