DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG 
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://nagoya.apache.org/bugzilla/show_bug.cgi?id=12541>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND 
INSERTED IN THE BUG DATABASE.

http://nagoya.apache.org/bugzilla/show_bug.cgi?id=12541

Calendar de/serializer does not preserve TimeZone

[EMAIL PROTECTED] changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |REOPENED
         Resolution|WONTFIX                     |



------- Additional Comments From [EMAIL PROTECTED]  2002-09-20 06:46 -------
OTHER ISSUES
=============

The current version of CalendarDeserializer does not work correctly for local 
times (everything ends up GMT whether it should be or not) or all valid time 
zones (minutes are meant to be optional according to the spec).  In addition, 
the current version of the code spends much of its time performing validation 
that is already within the scope of the java DateFormat class.

I have replaced the class in my own tree, and offer it here for your use if you 
are so inclined.  My code includes test cases that you may wish to execute 
against the prior code.

Regards,

Neil Brennan


============

package org.apache.axis.encoding.ser;

import org.apache.axis.utils.JavaUtils;

import javax.xml.namespace.QName;

import java.text.SimpleDateFormat;
import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;


/**
 * The CalendarSerializer deserializes a dateTime.
 * Much of the work is done in the base class.
 *
 * @author Sam Ruby ([EMAIL PROTECTED])
 * Modified for JAX-RPC @author Rich Scheuerle ([EMAIL PROTECTED])
 */
public class CalendarDeserializer extends SimpleDeserializer
{

    // used for local time parsing
    private static SimpleDateFormat LOCAL = new SimpleDateFormat("yyyy-MM-
dd'T'HH:mm:ss.SSS");
    // used for GMT time parsing
    private static SimpleDateFormat ZULU = new SimpleDateFormat("yyyy-MM-
dd'T'HH:mm:ss.SSS");
    // minimum length of a valid datetime string
    private static int MINLENGTH = 19;


    /**
     * The Deserializer is constructed with the xmlType and
     * javaType
     */
    public CalendarDeserializer(Class javaType, QName xmlType)
    {
        super(javaType, xmlType);
    }


    /**
     * The simple deserializer provides most of the stuff.
     * We just need to override makeValue().
     */
    public Object makeValue(String source)
    {
        // sanity
        if (source == null || source.length() == 0)
        {
            return null;
        }

        // init
        Calendar calendar = Calendar.getInstance();

        // parse for BC
        boolean bc = false;
        if (source.charAt(0) == '+')
            source = source.substring(1);
        else if (source.charAt(0) == '-')
        {
            source = source.substring(1);
            bc = true;
        }

        // parse all valid dates
        try
        {
            calendar.setTime(parseDate(source));
        }
        catch (ParseException e)
        {
            throw new NumberFormatException(JavaUtils.getMessage
("badDateTime00"));
        }

        // handle BC
        if (bc)
            calendar.set(Calendar.ERA, GregorianCalendar.BC);

        if (super.javaType == Date.class)
        {
            return calendar.getTime();
        }

        return calendar;
    }


    /**
     * Parses all valid date formats using abilities of DateFormat class.
     *
     * @return date specified.
     */
    private static Date parseDate(String source) throws ParseException
    {
        Date date = null;
        boolean bc = false;

        if (source == null || source.length() < MINLENGTH)
            throw new NumberFormatException(JavaUtils.getMessage
("badDateTime00"));

        if (source.charAt(0) == '+')
            source = source.substring(1);
        else if (source.charAt(0) == '-')
        {
            source = source.substring(1);
            bc = true;
        }

        // handle milliseconds
        if (source.indexOf(".") < 0)
            source = source.substring(0, MINLENGTH) + ".000" + source.substring
(MINLENGTH);

        // handle GMT
        if (source.toUpperCase().indexOf("Z") >= 0)
            synchronized(ZULU)
            {
                return ZULU.parse(source);
            }

        // handle local time
        synchronized(LOCAL)
        {
            date = LOCAL.parse(source);
        }

        // time zones only apply to local time
        date.setTime(date.getTime() + parseTimeZone(source.substring
(MINLENGTH)));

        return date;
    }

    /**
     * Parses time zone information.
     *
     * @return time zone offset in milliseconds.
     */
    private static int parseTimeZone(String source)
    {
        int hours = 0;
        int minutes = 0;
        int pos = 0;

        if ((pos = source.indexOf("+")) >= 0 ||
            (pos = source.indexOf("-")) >= 0)
        {
            if (source.length() < pos+2 || !Character.isDigit(source.charAt
(pos+1)) || !Character.isDigit(source.charAt(pos+2)))
                throw new NumberFormatException(JavaUtils.getMessage
("badTimezone00"));

            hours = (source.charAt(pos+1)-'0')*10 + source.charAt(pos+2)-'0';

            if (source.length() > pos+5)
            {
                if (source.charAt(pos+3) != ':' || !Character.isDigit
(source.charAt(pos+4)) || !Character.isDigit(source.charAt(pos+5)))
                    throw new NumberFormatException(JavaUtils.getMessage
("badTimezone00"));

                minutes = (source.charAt(pos+4)-'0')*10 + source.charAt(pos+5)-
'0';
            }
        }

        int milliseconds = (hours * 60 + minutes)* 60 * 1000;

        return ((pos = source.indexOf("+")) >= 0) ? -milliseconds : 
milliseconds;
    }


    /**
     * Test cases.
     */
    public static void main(String[] args) throws Exception
    {
        SimpleDateFormat DEFAULT = new SimpleDateFormat("dd/MM/yyyy 
HH:mm:ss.SSS");

        System.out.println("date: " + DEFAULT.format(parseDate("2002-09-
16T12:01:07")));
        System.out.println("date: " + DEFAULT.format(parseDate("2002-09-
16T12:02:06.123")));
        System.out.println("date: " + DEFAULT.format(parseDate("2002-09-
16T12:03:05Z")));
        System.out.println("date: " + DEFAULT.format(parseDate("2002-09-
16T12:04:04.123Z")));
        System.out.println("date: " + DEFAULT.format(parseDate("2002-09-
16T12:05:03.123-05:00")));
        System.out.println("date: " + DEFAULT.format(parseDate("2002-09-
16T12:06:02+10:33")));
        System.out.println("date: " + DEFAULT.format(parseDate("2002-09-
16T12:07:01+03")));
    }

}

Reply via email to