diff options
-rw-r--r-- | src/changes/changes.xml | 5 | ||||
-rw-r--r-- | src/main/java/com/healthmarketscience/jackcess/DatabaseBuilder.java | 28 | ||||
-rw-r--r-- | src/main/java/com/healthmarketscience/jackcess/impl/DatabaseImpl.java | 7 | ||||
-rwxr-xr-x | src/test/data/V2007/oldDatesV2007.accdb | bin | 0 -> 483328 bytes | |||
-rw-r--r-- | src/test/java/com/healthmarketscience/jackcess/DatabaseTest.java | 51 | ||||
-rw-r--r-- | src/test/java/com/healthmarketscience/jackcess/impl/JetFormatTest.java | 3 |
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 Binary files differnew file mode 100755 index 0000000..0e96b91 --- /dev/null +++ b/src/test/data/V2007/oldDatesV2007.accdb 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; |