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