diff options
author | James Ahlborn <jtahlborn@yahoo.com> | 2008-01-24 04:07:46 +0000 |
---|---|---|
committer | James Ahlborn <jtahlborn@yahoo.com> | 2008-01-24 04:07:46 +0000 |
commit | f96fd8b8dc0adbfea1d5a84ced5b56b499037f2e (patch) | |
tree | 03954a82dde704c5221e6a0b0d0152c9a840c83d | |
parent | 3534af761572c618c3d5a82f34e7e81a677b5590 (diff) | |
download | jackcess-f96fd8b8dc0adbfea1d5a84ced5b56b499037f2e.tar.gz jackcess-f96fd8b8dc0adbfea1d5a84ced5b56b499037f2e.zip |
Resolve more edge cases around date handling
git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@224 f203690c-595d-4dc9-a70b-905162fa7fd2
-rw-r--r-- | src/changes/changes.xml | 5 | ||||
-rw-r--r-- | src/java/com/healthmarketscience/jackcess/Column.java | 42 | ||||
-rw-r--r-- | test/src/java/com/healthmarketscience/jackcess/DatabaseTest.java | 45 |
3 files changed, 66 insertions, 26 deletions
diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 727ebd6..f00f27d 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -5,6 +5,11 @@ <author email="jahlborn@users.sf.net">James Ahlborn</author> </properties> <body> + <release version="1.1.12" date="TBD"> + <action dev="jahlborn" type="fix"> + Resolve more edge cases around date handling. + </action> + </release> <release version="1.1.11" date="2008-01-20"> <action dev="jahlborn" type="fix"> Support reading inline usage maps with more than 512 pages. diff --git a/src/java/com/healthmarketscience/jackcess/Column.java b/src/java/com/healthmarketscience/jackcess/Column.java index 3cfd4fe..73fa511 100644 --- a/src/java/com/healthmarketscience/jackcess/Column.java +++ b/src/java/com/healthmarketscience/jackcess/Column.java @@ -37,7 +37,6 @@ import java.sql.SQLException; import java.util.Calendar; import java.util.Date; import java.util.List; -import java.util.TimeZone; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -640,19 +639,14 @@ public class Column implements Comparable<Column> { { // seems access stores dates in the local timezone. guess you just hope // you read it in the same timezone in which it was written! - double dval = buffer.getDouble(); - dval *= MILLISECONDS_PER_DAY; - dval -= (DAYS_BETWEEN_EPOCH_AND_1900 * MILLISECONDS_PER_DAY); - long time = (long)dval; - TimeZone tz = TimeZone.getDefault(); - Date date = new Date(time - tz.getRawOffset()); - if (tz.inDaylightTime(date)) - { - date = new Date(date.getTime() - tz.getDSTSavings()); - } - return date; + double dTime = buffer.getDouble(); + dTime *= MILLISECONDS_PER_DAY; + dTime -= (DAYS_BETWEEN_EPOCH_AND_1900 * MILLISECONDS_PER_DAY); + long time = (long)dTime; + time -= getTimeZoneOffset(time); + return new Date(time); } - + /** * Writes a date value. */ @@ -663,16 +657,26 @@ public class Column implements Comparable<Column> { } else { // seems access stores dates in the local timezone. guess you just // hope you read it in the same timezone in which it was written! - Calendar cal = Calendar.getInstance(); - cal.setTime((Date) value); - long ms = cal.getTimeInMillis(); - ms += (long) TimeZone.getDefault().getOffset(ms); - buffer.putDouble((double) ms / MILLISECONDS_PER_DAY + - DAYS_BETWEEN_EPOCH_AND_1900); + long time = ((Date)value).getTime(); + time += getTimeZoneOffset(time); + + double dTime = (((double)time) / MILLISECONDS_PER_DAY) + + DAYS_BETWEEN_EPOCH_AND_1900; + buffer.putDouble(dTime); } } /** + * Gets the timezone offset from UTC for the given time (including DST). + */ + private static long getTimeZoneOffset(long time) + { + Calendar c = Calendar.getInstance(); + c.setTimeInMillis(time); + return ((long)c.get(Calendar.ZONE_OFFSET) + c.get(Calendar.DST_OFFSET)); + } + + /** * Decodes a GUID value. */ private String readGUIDValue(ByteBuffer buffer) diff --git a/test/src/java/com/healthmarketscience/jackcess/DatabaseTest.java b/test/src/java/com/healthmarketscience/jackcess/DatabaseTest.java index 11b42d9..2d6185a 100644 --- a/test/src/java/com/healthmarketscience/jackcess/DatabaseTest.java +++ b/test/src/java/com/healthmarketscience/jackcess/DatabaseTest.java @@ -190,6 +190,10 @@ public class DatabaseTest extends TestCase { assertEquals(Calendar.SEPTEMBER, cal.get(Calendar.MONTH)); assertEquals(21, cal.get(Calendar.DAY_OF_MONTH)); assertEquals(1974, cal.get(Calendar.YEAR)); + assertEquals(0, cal.get(Calendar.HOUR_OF_DAY)); + assertEquals(0, cal.get(Calendar.MINUTE)); + assertEquals(0, cal.get(Calendar.SECOND)); + assertEquals(0, cal.get(Calendar.MILLISECOND)); assertEquals(Boolean.TRUE, row.get("I")); row = table.getNextRow(); @@ -204,6 +208,10 @@ public class DatabaseTest extends TestCase { assertEquals(Calendar.DECEMBER, cal.get(Calendar.MONTH)); assertEquals(12, cal.get(Calendar.DAY_OF_MONTH)); assertEquals(1981, cal.get(Calendar.YEAR)); + assertEquals(0, cal.get(Calendar.HOUR_OF_DAY)); + assertEquals(0, cal.get(Calendar.MINUTE)); + assertEquals(0, cal.get(Calendar.SECOND)); + assertEquals(0, cal.get(Calendar.MILLISECOND)); assertEquals(Boolean.FALSE, row.get("I")); } @@ -792,12 +800,26 @@ public class DatabaseTest extends TestCase { DateFormat df = new SimpleDateFormat("yyyyMMdd HH:mm:ss"); List<Date> dates = - Arrays.asList( - df.parse("19801231 00:00:00"), - df.parse("19930513 14:43:27"), - null, - df.parse("20210102 02:37:00"), - new Date()); + new ArrayList<Date>( + Arrays.asList( + df.parse("19801231 00:00:00"), + df.parse("19930513 14:43:27"), + null, + df.parse("20210102 02:37:00"), + new Date())); + + Calendar c = Calendar.getInstance(); + for(int year = 1801; year < 2050; year +=3) { + for(int month = 0; month <= 12; ++month) { + for(int day = 1; day < 29; day += 3) { + c.clear(); + c.set(Calendar.YEAR, year); + c.set(Calendar.MONTH, month); + c.set(Calendar.DAY_OF_MONTH, day); + dates.add(c.getTime()); + } + } + } for(Date d : dates) { table.addRow("row " + d, d); @@ -808,7 +830,16 @@ public class DatabaseTest extends TestCase { foundDates.add((Date)row.get("date")); } - assertEquals(dates, foundDates); + assertEquals(dates.size(), foundDates.size()); + for(int i = 0; i < dates.size(); ++i) { + try { + assertEquals(dates.get(i), foundDates.get(i)); + } catch(Error e) { + System.err.println("Expected " + dates.get(i).getTime() + ", found " + + foundDates.get(i).getTime()); + throw e; + } + } } static Object[] createTestRow(String col1Val) { |