aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/changes/changes.xml5
-rw-r--r--src/main/java/com/healthmarketscience/jackcess/DatabaseBuilder.java28
-rw-r--r--src/main/java/com/healthmarketscience/jackcess/impl/DatabaseImpl.java7
-rwxr-xr-xsrc/test/data/V2007/oldDatesV2007.accdbbin0 -> 483328 bytes
-rw-r--r--src/test/java/com/healthmarketscience/jackcess/DatabaseTest.java51
-rw-r--r--src/test/java/com/healthmarketscience/jackcess/impl/JetFormatTest.java3
6 files changed, 90 insertions, 4 deletions
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 6da5920..2350392 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -9,6 +9,11 @@
Throw a prettier exception when maxing out the row size during row
creation.
</action>
+ <action dev="jahlborn" type="update" system="SourceForge2" issue="128">
+ Add some utility methods (DatabaseBuilder.createDateFormat and
+ DatabaseBuilder.toCompatibleCalendar) for handling Dates in an Access
+ compatible manner.
+ </action>
<action dev="jahlborn" type="update">
New site style!
</action>
diff --git a/src/main/java/com/healthmarketscience/jackcess/DatabaseBuilder.java b/src/main/java/com/healthmarketscience/jackcess/DatabaseBuilder.java
index aa81855..c5e0252 100644
--- a/src/main/java/com/healthmarketscience/jackcess/DatabaseBuilder.java
+++ b/src/main/java/com/healthmarketscience/jackcess/DatabaseBuilder.java
@@ -20,6 +20,10 @@ import java.io.File;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Map;
import java.util.TimeZone;
@@ -302,4 +306,28 @@ public class DatabaseBuilder
{
return new DatabaseBuilder(mdbFile).setFileFormat(fileFormat).create();
}
+
+ /**
+ * Returns a SimpleDateFormat for the given format string which is
+ * configured with a compatible Calendar instance (see
+ * {@link #toCompatibleCalendar}).
+ */
+ public static SimpleDateFormat createDateFormat(String formatStr) {
+ SimpleDateFormat sdf = new SimpleDateFormat(formatStr);
+ toCompatibleCalendar(sdf.getCalendar());
+ return sdf;
+ }
+
+ /**
+ * Ensures that the given {@link Calendar} is configured to be compatible
+ * with how Access handles dates. Specifically, alters the gregorian change
+ * (the java default gregorian change switches to julian dates for dates pre
+ * 1582-10-15, whereas Access uses <a href="https://en.wikipedia.org/wiki/Proleptic_Gregorian_calendar">proleptic gregorian dates</a>).
+ */
+ public static Calendar toCompatibleCalendar(Calendar cal) {
+ if(cal instanceof GregorianCalendar) {
+ ((GregorianCalendar)cal).setGregorianChange(new Date(Long.MIN_VALUE));
+ }
+ return cal;
+ }
}
diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/DatabaseImpl.java b/src/main/java/com/healthmarketscience/jackcess/impl/DatabaseImpl.java
index 26a7f1b..1984dc3 100644
--- a/src/main/java/com/healthmarketscience/jackcess/impl/DatabaseImpl.java
+++ b/src/main/java/com/healthmarketscience/jackcess/impl/DatabaseImpl.java
@@ -52,6 +52,7 @@ import com.healthmarketscience.jackcess.Cursor;
import com.healthmarketscience.jackcess.CursorBuilder;
import com.healthmarketscience.jackcess.DataType;
import com.healthmarketscience.jackcess.Database;
+import com.healthmarketscience.jackcess.DatabaseBuilder;
import com.healthmarketscience.jackcess.IndexBuilder;
import com.healthmarketscience.jackcess.IndexCursor;
import com.healthmarketscience.jackcess.PropertyMap;
@@ -702,10 +703,10 @@ public class DatabaseImpl implements Database
/**
* @usage _advanced_method_
*/
- Calendar getCalendar()
- {
+ Calendar getCalendar() {
if(_calendar == null) {
- _calendar = Calendar.getInstance(_timeZone);
+ _calendar = DatabaseBuilder.toCompatibleCalendar(
+ Calendar.getInstance(_timeZone));
}
return _calendar;
}
diff --git a/src/test/data/V2007/oldDatesV2007.accdb b/src/test/data/V2007/oldDatesV2007.accdb
new file mode 100755
index 0000000..0e96b91
--- /dev/null
+++ b/src/test/data/V2007/oldDatesV2007.accdb
Binary files differ
diff --git a/src/test/java/com/healthmarketscience/jackcess/DatabaseTest.java b/src/test/java/com/healthmarketscience/jackcess/DatabaseTest.java
index 918271a..5b0aff6 100644
--- a/src/test/java/com/healthmarketscience/jackcess/DatabaseTest.java
+++ b/src/test/java/com/healthmarketscience/jackcess/DatabaseTest.java
@@ -681,6 +681,57 @@ public class DatabaseTest extends TestCase
}
}
+ public void testAncientDates() throws Exception
+ {
+ TimeZone tz = TimeZone.getTimeZone("America/New_York");
+ SimpleDateFormat sdf = DatabaseBuilder.createDateFormat("yyyy-MM-dd");
+ sdf.getCalendar().setTimeZone(tz);
+
+ List<String> dates = Arrays.asList("1582-10-15", "1582-10-14",
+ "1492-01-10", "1392-01-10");
+
+
+ for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
+ Database db = createMem(fileFormat);
+ db.setTimeZone(tz);
+
+ Table table = new TableBuilder("test")
+ .addColumn(new ColumnBuilder("name", DataType.TEXT))
+ .addColumn(new ColumnBuilder("date", DataType.SHORT_DATE_TIME))
+ .toTable(db);
+
+ for(String dateStr : dates) {
+ Date d = sdf.parse(dateStr);
+ table.addRow("row " + dateStr, d);
+ }
+
+ List<String> foundDates = new ArrayList<String>();
+ for(Row row : table) {
+ foundDates.add(sdf.format(row.getDate("date")));
+ }
+
+ assertEquals(dates, foundDates);
+
+ db.close();
+ }
+
+ for (final TestDB testDB : TestDB.getSupportedForBasename(Basename.OLD_DATES)) {
+ Database db = openCopy(testDB);
+
+ Table t = db.getTable("Table1");
+
+ List<String> foundDates = new ArrayList<String>();
+ for(Row row : t) {
+ foundDates.add(sdf.format(row.getDate("DateField")));
+ }
+
+ assertEquals(dates, foundDates);
+
+ db.close();
+ }
+
+ }
+
public void testSystemTable() throws Exception
{
for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
diff --git a/src/test/java/com/healthmarketscience/jackcess/impl/JetFormatTest.java b/src/test/java/com/healthmarketscience/jackcess/impl/JetFormatTest.java
index f84cc16..e8a5287 100644
--- a/src/test/java/com/healthmarketscience/jackcess/impl/JetFormatTest.java
+++ b/src/test/java/com/healthmarketscience/jackcess/impl/JetFormatTest.java
@@ -49,7 +49,8 @@ public class JetFormatTest extends TestCase {
LINKED("linkerTest"),
BLOB("testOle"),
CALC_FIELD("calcFieldTest"),
- BINARY_INDEX("binIdxTest");
+ BINARY_INDEX("binIdxTest"),
+ OLD_DATES("oldDates");
private final String _basename;