Hi Peter,

On 14 May 2012 20:49, Peter Bigot <big...@acm.org> wrote:
> I'm not sure.  As you saw, http://www.w3.org/TR/xmlschema-2/#dateTime
> is pretty clear that anything that had a timezone is to be treated as
> UTC.  If the original lexical space didn't have a timezone, I think I
> set it up to be given the local timezone; it might be argued that that
> is a mistake, but it might also have been necessary for consistency.
>
> If you would file this as a trac request I'll see what I can do.
> Please make it clear whether you just want xsd.dateTime.now() to be
> symmetrical or whether you need values that lack a timezone to do
> something other than what they do now.

Ok, so I wrote a Java / JAXB version of my python test posted late
yesterday to the mailing list. I'm using Python 2.7.3, PyXB 1.1.3,
Java 7u4 (which includes JAXB 2.2.4). The code reads in an XML string,
prints out the value it got, then converts it back to XML and prints
out that string. Here's the result - first in Python/PyXB, then
Java/JAXB:

(pyenv-zktraining)nathanr@gionta:~/work/junkcode/pyxb-datetime-test>
python test2.py
datetime.datetime.now() prints 2012-05-15 15:16:12.167164
<?xml version="1.0" ?><ns1:timestamp
xmlns:ns1="http://test.com/test";>2012-05-14T16:36:02.157+10:00</ns1:timestamp>
--> 2012-05-14 06:36:02.157000 --> <?xml version="1.0"
?><ns1:timestamp
xmlns:ns1="http://test.com/test";>2012-05-14T06:36:02.157Z</ns1:timestamp>
<?xml version="1.0" ?><ns1:timestamp
xmlns:ns1="http://test.com/test";>2012-05-14T06:36:02.157Z</ns1:timestamp>
--> 2012-05-14 06:36:02.157000 --> <?xml version="1.0"
?><ns1:timestamp
xmlns:ns1="http://test.com/test";>2012-05-14T06:36:02.157Z</ns1:timestamp>
<?xml version="1.0" ?><ns1:timestamp
xmlns:ns1="http://test.com/test";>2012-05-14T16:36:02.157</ns1:timestamp>
--> 2012-05-14 16:36:02.157000 --> <?xml version="1.0"
?><ns1:timestamp
xmlns:ns1="http://test.com/test";>2012-05-14T16:36:02.157</ns1:timestamp>

(pyenv-zktraining)nathanr@gionta:~/work/junkcode/pyxb-datetime-test> java Test2
Calendar.getInstance() prints: 2012-05-15 15:16:14.612
<?xml version="1.0" ?><ns1:timestamp
xmlns:ns1="http://test.com/test";>2012-05-14T16:36:02.157+10:00</ns1:timestamp>
--> 2012-05-14 16:36:02.157 --> <?xml version="1.0" encoding="UTF-8"
standalone="yes"?><timestamp
xmlns="http://test.com/test";>2012-05-14T16:36:02.157+10:00</timestamp>
<?xml version="1.0" ?><ns1:timestamp
xmlns:ns1="http://test.com/test";>2012-05-14T06:36:02.157Z</ns1:timestamp>
--> 2012-05-14 06:36:02.157 --> <?xml version="1.0" encoding="UTF-8"
standalone="yes"?><timestamp
xmlns="http://test.com/test";>2012-05-14T06:36:02.157Z</timestamp>
<?xml version="1.0" ?><ns1:timestamp
xmlns:ns1="http://test.com/test";>2012-05-14T16:36:02.157</ns1:timestamp>
--> 2012-05-14 16:36:02.157 --> <?xml version="1.0" encoding="UTF-8"
standalone="yes"?><timestamp
xmlns="http://test.com/test";>2012-05-14T16:36:02.157+10:00</timestamp>
(pyenv-zktraining)nathanr@gionta:~/work/junkcode/pyxb-datetime-test>


So, for the purposes of below:

- I will call yyyy-mm-ddThh:mm:ss.mmm+TZ:TZ "format 1" (timestamp with
+timezone on the end)
- I will call yyyy-mm-ddThh:mm:ss.mmmZ "format 2" (Z on the end,
signifying GMT time)
- I will call yyyy-mm-ddThh:mm:ss.mmm "format 3" (no time zone)

- Given an xsd:dateTime with format 1, PyXB will print the object out
in format 3, in GMT time, and marshal the date back out to XML in
format 2.
- Given an xsd:dateTime with format 1, JAXB will print the object out
in format 3, in local time, and marshal the date back out to XML in
format 1.

- Given an xsd:dateTime with format 2, PyXB will print the object out
in format 3, in GMT time, and marshal the date back out to XML in
format 2.
- Given an xsd:dateTime with format 2, JAXB will print the object out
in format 3, in GMT time, and marshal the date back out to XML in
format 2.

- Given an xsd:dateTime with format 3, PyXB will print the object out
in format 3, in local time, and marshal the date back out to XML in
format 3.
- Given an xsd:dateTime with format 3, JAXB will print the object out
in format 3, in local time, and marshal the date back out to XML in
format 1 (assuming local time by default)


Notes on the above:

1. JAXB handling of format 2 ("GMT time with trailing Z") appears
inconsistent. Why they would represent the object to client code in
GMT in that case, but as local time in the case of format 1 input,
I'll never know, and makes JAXB Calendar's inconsistent with the rest
of the Java platform when using format 2 input. I think this is
probably a JAXB bug. So, as a JAXB consumer, it is better to have
format 1 input, as JAXB Calendar's with format 1 input are symmetrical
and compatible with Calendar.getInstance() generated (standard
platform) calendars.

2. Python printing out pyxb.binding.datatypes.dateTime's as GMT when
it prints out datetime.datetime's as local time is inconsistent. It
should represent itself to code (and print out its value) as local
time, not GMT. It should be compatible with datetime.datetime, which
it extends, and hence can be (and does get) used in place of in client
code. For mine, this is a PyXB bug, and is causing us problems in our
code at the moment.

3. It's debatable what to do with format 3, but at least PyXB and JAXB
read it in the same. I think the current decision on handling format 3
in PyXB is probably the right one. My personal opinion is that JAXB
printing out in format 1 and not format 3 in the case of format 3
input is a mistake, but I can see arguments both ways. The argument
that "it's because JAXB always outputs format 1" is actually wrong,
because it doesn't do that for format 2 input.


So, there are two things I think need to be looked at for changing:

1. For interoperability, it would be nice if PyXB could print out in
format 1. Whether it be by default, or outputting in format 1 as a
configurable option. Those interoperating with JAXB code will want to
have PyXB output format 1, for sure.

2. pyxb.binding.datatypes.dateTime should represent itself to client
code in a compatible way to datetime.datetime such that it can be a
drop in replacement (particularly given it subclasses it). That means
it should represent itself to client code as local time, not GMT.

Peter - are you ok with me opening two Trac tickets for the above two
suggestions? Both are issues that will cause us problems for our July
production release I referenced in another email earlier today.

The Python code was in a previous posting - I'm providing the
Java/JAXB code below for completeness / mailing list archiving
purposes.

Regards,
Nathan.

--

import generated.*;
import javax.xml.*;
import javax.xml.bind.*;
import javax.xml.datatype.*;
import javax.xml.validation.*;
import java.io.*;
import java.net.*;
import java.util.*;

/*
$ xjc -d . -p generated schema.xsd
$ javac Test2.java
$ java Test2

schema.xsd is:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema";
targetNamespace="http://test.com/test";
xmlns:zenkai="http://test.com/test";>
    <xsd:element name="timestamp" type="xsd:dateTime"/>
</xsd:schema>
*/

public class Test2 {
        private static final String[] XML_LIST = {
                "<?xml version=\"1.0\" ?><ns1:timestamp
xmlns:ns1=\"http://test.com/test\";>2012-05-14T16:36:02.157+10:00</ns1:timestamp>",
                "<?xml version=\"1.0\" ?><ns1:timestamp
xmlns:ns1=\"http://test.com/test\";>2012-05-14T06:36:02.157Z</ns1:timestamp>",
                "<?xml version=\"1.0\" ?><ns1:timestamp
xmlns:ns1=\"http://test.com/test\";>2012-05-14T16:36:02.157</ns1:timestamp>"
        };

        public static void main(String args[]) throws Exception {
                Calendar c = Calendar.getInstance();
                System.out.format("Calendar.getInstance() prints: %1$tF
%1$tR:%1$tS.%1$tL", c);
                System.out.println("");

                ObjectFactory of = new ObjectFactory();
                JAXBContext jc = JAXBContext.newInstance("generated");
                Unmarshaller u = jc.createUnmarshaller();
                Marshaller m = jc.createMarshaller();
                m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.FALSE);

                URL url = new 
Test2().getClass().getClassLoader().getResource("schema.xsd");
                SchemaFactory sf =
SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
                Schema schema = sf.newSchema(url);
                u.setSchema(schema);

                for (String xml: XML_LIST) {
                        System.out.print(xml);
                        
                        GregorianCalendar timestampIn = ((XMLGregorianCalendar)
((JAXBElement<?>) u.unmarshal(new
ByteArrayInputStream(xml.getBytes()))).getValue()).toGregorianCalendar();
                        System.out.format(" --> %1$tF %1$tR:%1$tS.%1$tL --> ", 
timestampIn);

                        StringWriter sw = new StringWriter();
                        
m.marshal(of.createTimestamp(DatatypeFactory.newInstance().newXMLGregorianCalendar(timestampIn)),
sw);
                        System.out.println(sw.toString());
                }
        }
}

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
pyxb-users mailing list
pyxb-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/pyxb-users

Reply via email to