Menu

#18 Newly implemented / re-implemented EXSLT date-time functions

open
nobody
None
5
2012-10-08
2009-04-28
Joe Fenton
No

Created new implementations of the following EXSLT date-time functions:
add
difference
seconds

Re-implemented the following functions to improve correspondence with the EXSLT spec
(mostly returning empty strings or NaN when the input is not in a correct date/time format):
date
year
day-in-month

Discussion

  • Joe Fenton

    Joe Fenton - 2009-04-28

    Patch for EXSLT Date class

     
  • Michael Kay

    Michael Kay - 2009-04-28

    Thanks.

    A few points:

    (a) I can't say I'm happy with the dependency on a com.sun.org.apache class. Are you sure this is present in every JVM, e.g. in the OpenJDK library? Is there any reason you can't use Saxon's own implementation of XMLGregorianCalendar instead?

    (b) Would you be happy to sign a release agreement confirming (on behalf of yourself and your employer) that you agree to release this code under MPL?

    (c) Could you supply your test cases?

     
  • Nobody/Anonymous

    Thanks for your quick response.

    (a) We've removed this explicit dependency by using javax.xml.datatype.DatatypeFactory.newInstance() rather than a particular implementation of DatatypeFactory. A new patch is attached.

    (b) That'll be fine.

    (c) Attached will be a set of inputs, control files and a JUnit test class in a zip file. We couldn't find an existing test framework into which we could place these - please direct us to such a framework if it is available.

     
  • Joe Fenton

    Joe Fenton - 2009-04-29

    New patch file that removes apache class dependency

     
  • Joe Fenton

    Joe Fenton - 2009-04-29

    Zip file of test cases and JUnit test

     
  • Michael Kay

    Michael Kay - 2009-04-29

    I've integrated the code and the tests. (Now I just need your signoff!) I converted the tests to run in my test framework and to deliver reproducible results (basically by comparing the result of the EXSLT date() with the XSLT 2.0 current-date()). I also ran my regression tests - three of them delivered different results and I'm satisfied that the new results are correct.

    The code relies heavily on JDK 1.5 but you're in luck because I've essentially already decided that the next Saxon release will no longer support JDK 1.4.

    Having said that, I'd feel more comfortable supporting this code if it were built on the Saxon implementation of the date/time data types in XSD, rather than the Sun/Apache implementation. Don't be disappointed if you find one day that I've rewritten it.

     
  • Michael Kay

    Michael Kay - 2009-04-29

    The supplied test for day-in-month('--04-31Z') gives 31, I believe the correct answer is NaN because this is not a valid lexical representation of a gYearMonth. The XSD 1.1 spec is much more explicit on this point, but it's only a clarification, not a substantive change.

    I have recoded the relevant method to use the Saxon date/time classes rather than the Sun/Apache implementation, which results in this error being caught.

     
  • Michael Kay

    Michael Kay - 2009-04-30

    The EXSLT specification for difference() doesn't say much about how timezones are handled. It's not even clear as to whether the inputs can have a timezone or not. I've decided to follow XPath 2.0 and make the timezone optional, using the implicit timezone where necessary. I've recoded the logic to use the underlying Saxon date/time classes. The only effect on the supplied tests is that a zero-length yearMonthDuration displays as P0M rather than P0Y. This is the correct canonical representation (see http://www.w3.org/TR/xpath-functions/#dt-yearMonthDuration, section 10.3.1.3).

     
  • Michael Kay

    Michael Kay - 2009-04-30

    My reading of the spec is that date:difference('2000Z', '2001-01-02Z') should be P1Y1M. I believe your test result of P1Y is incorrect. Agreed, the spec is hardly very precise on the point.

     
  • Michael Kay

    Michael Kay - 2009-04-30

    My reading of the spec is that date:difference('2000Z', '2001-01-02Z')
    should be P1Y1M.

    Sorry, I missed the bit about the more specific being converted to the less specific (well, it's actually garbled in the spec, but that's what it means!). So P1Y is correct.

    Only other changes I needed to make were to use canonical form for durations such as P1DT0S - should be simply P1D.

     

Anonymous
Anonymous

Add attachments
Cancel