The XSDDateTime constructor creates a datetime object which can be
incorrect depending on the timezone and proximity to either a daylight
savings or standard time change.

 

Below is a mix of datetimes around the Spring and Fall time changes in
different time zones.  I'm using Jena 2.6.4 but the XSDDateTime class
appears little changed in 2.7.0.  In these results, tstr is an input
string, date is a formatted Date, xsddt is the XSDDateTime instance and
'X' means the xsddt is incorrect:

 

tstr=03/10/2012 01:29 date=2012.03.10 01:29:00 GMT
xsddt=2012-03-10T01:29:00Z     offset=0

tstr=03/11/2012 00:29 date=2012.03.11 00:29:00 GMT
xsddt=2012-03-11T00:29:00Z     offset=0

tstr=03/11/2012 01:29 date=2012.03.11 01:29:00 GMT
xsddt=2012-03-11T01:29:00Z     offset=0

tstr=03/11/2012 02:29 date=2012.03.11 02:29:00 GMT
xsddt=2012-03-11T02:29:00Z     offset=0

tstr=03/11/2012 03:29 date=2012.03.11 03:29:00 GMT
xsddt=2012-03-11T03:29:00Z     offset=0

tstr=03/11/2012 04:29 date=2012.03.11 04:29:00 GMT
xsddt=2012-03-11T04:29:00Z     offset=0

tstr=03/12/2012 01:29 date=2012.03.12 01:29:00 GMT
xsddt=2012-03-12T01:29:00Z     offset=0

tstr=11/03/2012 23:29 date=2012.11.03 23:29:00 GMT
xsddt=2012-11-03T23:29:00Z     offset=0

tstr=11/04/2012 00:29 date=2012.11.04 00:29:00 GMT
xsddt=2012-11-04T00:29:00Z     offset=0

tstr=11/04/2012 01:29 date=2012.11.04 01:29:00 GMT
xsddt=2012-11-04T01:29:00Z     offset=0

tstr=11/04/2012 02:29 date=2012.11.04 02:29:00 GMT
xsddt=2012-11-04T02:29:00Z     offset=0

tstr=11/04/2012 03:29 date=2012.11.04 03:29:00 GMT
xsddt=2012-11-04T03:29:00Z     offset=0

 

tstr=03/10/2012 01:29 date=2012.03.10 01:29:00 EST
xsddt=2012-03-10T06:29:00Z     offset=-5

tstr=03/11/2012 00:29 date=2012.03.11 00:29:00 EST    X
xsddt=2012-03-11T06:29:00Z     offset=-5

tstr=03/11/2012 01:29 date=2012.03.11 01:29:00 EST    X
xsddt=2012-03-11T07:29:00Z     offset=-5

tstr=03/11/2012 02:29 date=2012.03.11 03:29:00 EDT
xsddt=2012-03-11T07:29:00Z     offset=-4

tstr=03/11/2012 03:29 date=2012.03.11 03:29:00 EDT
xsddt=2012-03-11T07:29:00Z     offset=-4

tstr=03/11/2012 04:29 date=2012.03.11 04:29:00 EDT
xsddt=2012-03-11T08:29:00Z     offset=-4

tstr=03/12/2012 01:29 date=2012.03.12 01:29:00 EDT
xsddt=2012-03-12T05:29:00Z     offset=-4

tstr=11/03/2012 23:29 date=2012.11.03 23:29:00 EDT    X
xsddt=2012-11-04T02:29:00Z     offset=-4

tstr=11/04/2012 00:29 date=2012.11.04 00:29:00 EDT    X
xsddt=2012-11-04T03:29:00Z     offset=-4

tstr=11/04/2012 01:29 date=2012.11.04 01:29:00 EST
xsddt=2012-11-04T06:29:00Z     offset=-5

tstr=11/04/2012 02:29 date=2012.11.04 02:29:00 EST
xsddt=2012-11-04T07:29:00Z     offset=-5

tstr=11/04/2012 03:29 date=2012.11.04 03:29:00 EST
xsddt=2012-11-04T08:29:00Z     offset=-5

 

tstr=03/10/2012 01:29 date=2012.03.10 01:29:00 CST
xsddt=2012-03-10T07:29:00Z     offset=-6

tstr=03/11/2012 00:29 date=2012.03.11 00:29:00 CST    X
xsddt=2012-03-11T07:29:00Z     offset=-6

tstr=03/11/2012 01:29 date=2012.03.11 01:29:00 CST    X
xsddt=2012-03-11T08:29:00Z     offset=-6

tstr=03/11/2012 02:29 date=2012.03.11 03:29:00 CDT
xsddt=2012-03-11T08:29:00Z     offset=-5

tstr=03/11/2012 03:29 date=2012.03.11 03:29:00 CDT
xsddt=2012-03-11T08:29:00Z     offset=-5

tstr=03/11/2012 04:29 date=2012.03.11 04:29:00 CDT
xsddt=2012-03-11T09:29:00Z     offset=-5

tstr=03/12/2012 01:29 date=2012.03.12 01:29:00 CDT
xsddt=2012-03-12T06:29:00Z     offset=-5

tstr=11/03/2012 23:29 date=2012.11.03 23:29:00 CDT    X
xsddt=2012-11-04T03:29:00Z     offset=-5

tstr=11/04/2012 00:29 date=2012.11.04 00:29:00 CDT    X
xsddt=2012-11-04T04:29:00Z     offset=-5

tstr=11/04/2012 01:29 date=2012.11.04 01:29:00 CST
xsddt=2012-11-04T07:29:00Z     offset=-6

tstr=11/04/2012 02:29 date=2012.11.04 02:29:00 CST
xsddt=2012-11-04T08:29:00Z     offset=-6

tstr=11/04/2012 03:29 date=2012.11.04 03:29:00 CST
xsddt=2012-11-04T09:29:00Z     offset=-6

 

 

The XSDDateTime convertCalendar(Calendar date) method, called by
XSDDateTime(Calendar date), can be changed to produce correct results by
replacing:

 

                     cal.add(Calendar.MILLISECOND, -offset);

 

with:

 

                     cal.setTimeZone(TimeZone.getTimeZone("GMT"));

 

 

Here are the test results with the suggested code replacement--no
incorrect results:

 

tstr=03/10/2012 01:29 date=2012.03.10 01:29:00 GMT
xsddt=2012-03-10T01:29:00Z     offset=0

tstr=03/11/2012 00:29 date=2012.03.11 00:29:00 GMT
xsddt=2012-03-11T00:29:00Z     offset=0

tstr=03/11/2012 01:29 date=2012.03.11 01:29:00 GMT
xsddt=2012-03-11T01:29:00Z     offset=0

tstr=03/11/2012 02:29 date=2012.03.11 02:29:00 GMT
xsddt=2012-03-11T02:29:00Z     offset=0

tstr=03/11/2012 03:29 date=2012.03.11 03:29:00 GMT
xsddt=2012-03-11T03:29:00Z     offset=0

tstr=03/11/2012 04:29 date=2012.03.11 04:29:00 GMT
xsddt=2012-03-11T04:29:00Z     offset=0

tstr=03/12/2012 01:29 date=2012.03.12 01:29:00 GMT
xsddt=2012-03-12T01:29:00Z     offset=0

tstr=11/03/2012 23:29 date=2012.11.03 23:29:00 GMT
xsddt=2012-11-03T23:29:00Z     offset=0

tstr=11/04/2012 00:29 date=2012.11.04 00:29:00 GMT
xsddt=2012-11-04T00:29:00Z     offset=0

tstr=11/04/2012 01:29 date=2012.11.04 01:29:00 GMT
xsddt=2012-11-04T01:29:00Z     offset=0

tstr=11/04/2012 02:29 date=2012.11.04 02:29:00 GMT
xsddt=2012-11-04T02:29:00Z     offset=0

tstr=11/04/2012 03:29 date=2012.11.04 03:29:00 GMT
xsddt=2012-11-04T03:29:00Z     offset=0

 

tstr=03/10/2012 01:29 date=2012.03.10 01:29:00 EST
xsddt=2012-03-10T06:29:00Z     offset=-5

tstr=03/11/2012 00:29 date=2012.03.11 00:29:00 EST
xsddt=2012-03-11T05:29:00Z     offset=-5

tstr=03/11/2012 01:29 date=2012.03.11 01:29:00 EST
xsddt=2012-03-11T06:29:00Z     offset=-5

tstr=03/11/2012 02:29 date=2012.03.11 03:29:00 EDT
xsddt=2012-03-11T07:29:00Z     offset=-4

tstr=03/11/2012 03:29 date=2012.03.11 03:29:00 EDT
xsddt=2012-03-11T07:29:00Z     offset=-4

tstr=03/11/2012 04:29 date=2012.03.11 04:29:00 EDT
xsddt=2012-03-11T08:29:00Z     offset=-4

tstr=03/12/2012 01:29 date=2012.03.12 01:29:00 EDT
xsddt=2012-03-12T05:29:00Z     offset=-4

tstr=11/03/2012 23:29 date=2012.11.03 23:29:00 EDT
xsddt=2012-11-04T03:29:00Z     offset=-4

tstr=11/04/2012 00:29 date=2012.11.04 00:29:00 EDT
xsddt=2012-11-04T04:29:00Z     offset=-4

tstr=11/04/2012 01:29 date=2012.11.04 01:29:00 EST
xsddt=2012-11-04T06:29:00Z     offset=-5

tstr=11/04/2012 02:29 date=2012.11.04 02:29:00 EST
xsddt=2012-11-04T07:29:00Z     offset=-5

tstr=11/04/2012 03:29 date=2012.11.04 03:29:00 EST
xsddt=2012-11-04T08:29:00Z     offset=-5

 

tstr=03/10/2012 01:29 date=2012.03.10 01:29:00 CST
xsddt=2012-03-10T07:29:00Z     offset=-6

tstr=03/11/2012 00:29 date=2012.03.11 00:29:00 CST
xsddt=2012-03-11T06:29:00Z     offset=-6

tstr=03/11/2012 01:29 date=2012.03.11 01:29:00 CST
xsddt=2012-03-11T07:29:00Z     offset=-6

tstr=03/11/2012 02:29 date=2012.03.11 03:29:00 CDT
xsddt=2012-03-11T08:29:00Z     offset=-5

tstr=03/11/2012 03:29 date=2012.03.11 03:29:00 CDT
xsddt=2012-03-11T08:29:00Z     offset=-5

tstr=03/11/2012 04:29 date=2012.03.11 04:29:00 CDT
xsddt=2012-03-11T09:29:00Z     offset=-5

tstr=03/12/2012 01:29 date=2012.03.12 01:29:00 CDT
xsddt=2012-03-12T06:29:00Z     offset=-5

tstr=11/03/2012 23:29 date=2012.11.03 23:29:00 CDT
xsddt=2012-11-04T04:29:00Z     offset=-5

tstr=11/04/2012 00:29 date=2012.11.04 00:29:00 CDT
xsddt=2012-11-04T05:29:00Z     offset=-5

tstr=11/04/2012 01:29 date=2012.11.04 01:29:00 CST
xsddt=2012-11-04T07:29:00Z     offset=-6

tstr=11/04/2012 02:29 date=2012.11.04 02:29:00 CST
xsddt=2012-11-04T08:29:00Z     offset=-6

tstr=11/04/2012 03:29 date=2012.11.04 03:29:00 CST
xsddt=2012-11-04T09:29:00Z     offset=-6

 

 

Can somebody verify these results?

 

 

Thanks,

Rick

 

 

The test code:

 

 

package test;

 

 

import java.text.SimpleDateFormat;

import java.util.Calendar;

import java.util.Date;

import java.util.TimeZone;

 

import org.junit.Test;

 

import com.hp.hpl.jena.datatypes.xsd.XSDDateTime;

 

public class TestXSDDateTime {

 

     public static Date getDateFromPattern(String ts, String format,
String timezoneid) throws Exception {

           return getDateFromPattern(ts, new String[]{format},
TimeZone.getTimeZone(timezoneid));

     }

     public static Date getDateFromPattern(String ts, String[] formats,
TimeZone tz) throws Exception {

           java.util.Date date = null;

           java.text.DateFormat sdf =
java.text.DateFormat.getInstance();

           {

                sdf.setTimeZone(tz == null ?
java.util.TimeZone.getDefault() : tz);

                for (int i=0; date == null && i<formats.length;i++){

 
((java.text.SimpleDateFormat)sdf).applyPattern(formats[i]);

                     try {

                           date = sdf.parse(ts);

                     } catch (java.text.ParseException pe){} // keep
trying

                }

           }

           return date;

     }

 

     @Test

     public void test() throws Exception {

           

           String[] timezonelist = {

                     "GMT",

                     "America/New_York",

                     "America/Chicago",

           };

 

           for (String timezoneid : timezonelist) {

                

                TimeZone tz = TimeZone.getTimeZone(timezoneid);

                String[] sampletimelist = {

                           "03/10/2012 01:29", // 03/11/2012 DST time
change at 2 am

                           "03/11/2012 00:29",

                           "03/11/2012 01:29",

                           "03/11/2012 02:29",

                           "03/11/2012 03:29",

                           "03/11/2012 04:29",

                           "03/12/2012 01:29",

                           

                           "11/03/2012 23:29", // 11/04/2012 standard
time change at 2 am

                           "11/04/2012 00:29",

                           "11/04/2012 01:29",

                           "11/04/2012 02:29",

                           "11/04/2012 03:29",

                };

                

                String format = "MM/dd/yyy HH:mm";

                

                for (String tstr : sampletimelist){

 

                     Date dt=getDateFromPattern(tstr, format,
timezoneid);

                     SimpleDateFormat df = new
SimpleDateFormat("yyyy.MM.dd HH:mm:ss z");

                     df.setTimeZone(tz);

                     Calendar cal = Calendar.getInstance();

                     cal.setTimeZone(tz);

                     cal.setTime(dt);

                     XSDDateTime xdt = new XSDDateTime(cal);

                     int offset = tz.getOffset(dt.getTime()) /( 60 * 60
* 1000);

                     int xhr = xdt.getHours();

                     int dhr = cal.get(Calendar.HOUR_OF_DAY);

                     int dif = (xhr -dhr + offset) % 24;

 
//System.out.println("xhr="+xhr+",dhr="+dhr+",dif="+dif);

                     System.out.println(""

                                +"tstr="+tstr

                                +"\tdate="+df.format(dt)

                                +(dif==0?"\t ":"\tX")

                                +" xsddt="+xdt

                                +"\toffset="+offset);

                }

                System.out.println();

           }

     }

}

 

 

 

Reply via email to