summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Ahlborn <jtahlborn@yahoo.com>2008-01-24 04:07:46 +0000
committerJames Ahlborn <jtahlborn@yahoo.com>2008-01-24 04:07:46 +0000
commitf96fd8b8dc0adbfea1d5a84ced5b56b499037f2e (patch)
tree03954a82dde704c5221e6a0b0d0152c9a840c83d
parent3534af761572c618c3d5a82f34e7e81a677b5590 (diff)
downloadjackcess-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.xml5
-rw-r--r--src/java/com/healthmarketscience/jackcess/Column.java42
-rw-r--r--test/src/java/com/healthmarketscience/jackcess/DatabaseTest.java45
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) {