From 21fe1417bb49bbdba8591377c221a4417a8851ee Mon Sep 17 00:00:00 2001 From: James Ahlborn Date: Sat, 15 Dec 2018 16:09:46 +0000 Subject: [PATCH] use interface to pass zone info into date/time conversion methods git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/branches/jdk8@1239 f203690c-595d-4dc9-a70b-905162fa7fd2 --- .../jackcess/expr/TemporalConfig.java | 4 +- .../jackcess/impl/ColumnImpl.java | 68 +++++++++++-------- .../jackcess/impl/DatabaseImpl.java | 2 +- .../jackcess/impl/ZoneContext.java | 32 +++++++++ .../jackcess/DatabaseTest.java | 4 +- .../jackcess/LocalDateTimeTest.java | 4 +- .../jackcess/TableTest.java | 2 +- 7 files changed, 81 insertions(+), 35 deletions(-) create mode 100644 src/main/java/com/healthmarketscience/jackcess/impl/ZoneContext.java diff --git a/src/main/java/com/healthmarketscience/jackcess/expr/TemporalConfig.java b/src/main/java/com/healthmarketscience/jackcess/expr/TemporalConfig.java index b441c88..cfe08e1 100644 --- a/src/main/java/com/healthmarketscience/jackcess/expr/TemporalConfig.java +++ b/src/main/java/com/healthmarketscience/jackcess/expr/TemporalConfig.java @@ -146,8 +146,8 @@ public class TemporalConfig /** * Instantiates a new TemporalConfig with the given configuration. Note * that the date/time format variants will be created by concatenating the - * relevant date and time formats, separated by a single space, e.g. "<date> - * <time>". + * relevant date and time formats, separated by a single space, + * e.g. "<date> <time>". * * @param dateFormat the date (no time) format * @param timeFormat12 the 12 hour time format diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/ColumnImpl.java b/src/main/java/com/healthmarketscience/jackcess/impl/ColumnImpl.java index 273a62a..8e67d60 100644 --- a/src/main/java/com/healthmarketscience/jackcess/impl/ColumnImpl.java +++ b/src/main/java/com/healthmarketscience/jackcess/impl/ColumnImpl.java @@ -76,7 +76,8 @@ import org.apache.commons.logging.LogFactory; * @author Tim McCune * @usage _intermediate_class_ */ -public class ColumnImpl implements Column, Comparable { +public class ColumnImpl implements Column, Comparable, ZoneContext +{ protected static final Log LOG = LogFactory.getLog(ColumnImpl.class); @@ -358,10 +359,12 @@ public class ColumnImpl implements Column, Comparable { // base does nothing } + @Override public TableImpl getTable() { return _table; } + @Override public DatabaseImpl getDatabase() { return getTable().getDatabase(); } @@ -380,14 +383,17 @@ public class ColumnImpl implements Column, Comparable { return getDatabase().getPageChannel(); } + @Override public String getName() { return _name; } + @Override public boolean isVariableLength() { return _variableLength; } + @Override public boolean isAutoNumber() { return _autoNumber; } @@ -399,6 +405,7 @@ public class ColumnImpl implements Column, Comparable { return _columnNumber; } + @Override public int getColumnIndex() { return _columnIndex; } @@ -417,22 +424,27 @@ public class ColumnImpl implements Column, Comparable { return _displayIndex; } + @Override public DataType getType() { return _type; } + @Override public int getSQLType() throws SQLException { return _type.getSQLType(); } + @Override public boolean isCompressedUnicode() { return false; } + @Override public byte getPrecision() { return (byte)getType().getDefaultPrecision(); } + @Override public byte getScale() { return (byte)getType().getDefaultScale(); } @@ -451,14 +463,17 @@ public class ColumnImpl implements Column, Comparable { return 0; } + @Override public short getLength() { return _columnLength; } + @Override public short getLengthInUnits() { return (short)getType().toUnitSize(getLength()); } + @Override public boolean isCalculated() { return _calculated; } @@ -481,11 +496,13 @@ public class ColumnImpl implements Column, Comparable { return getDatabase().getCharset(); } - protected TimeZone getTimeZone() { + @Override + public TimeZone getTimeZone() { return getDatabase().getTimeZone(); } - protected ZoneId getZoneId() { + @Override + public ZoneId getZoneId() { return getDatabase().getZoneId(); } @@ -493,10 +510,12 @@ public class ColumnImpl implements Column, Comparable { return getDatabase().getDateTimeFactory(); } + @Override public boolean isAppendOnly() { return (getVersionHistoryColumn() != null); } + @Override public ColumnImpl getVersionHistoryColumn() { return null; } @@ -516,10 +535,12 @@ public class ColumnImpl implements Column, Comparable { throw new UnsupportedOperationException(); } + @Override public boolean isHyperlink() { return false; } + @Override public ComplexColumnInfo getComplexInfo() { return null; } @@ -610,12 +631,14 @@ public class ColumnImpl implements Column, Comparable { reloadPropertiesValidators(); } + @Override public ColumnValidator getColumnValidator() { // unwrap any "internal" validator return ((_validator instanceof InternalColumnValidator) ? ((InternalColumnValidator)_validator).getExternal() : _validator); } + @Override public void setColumnValidator(ColumnValidator newValidator) { if(isAutoNumber()) { @@ -676,6 +699,7 @@ public class ColumnImpl implements Column, Comparable { return _autoNumberGenerator; } + @Override public PropertyMap getProperties() throws IOException { if(_props == null) { _props = getTable().getPropertyMaps().get(getName()); @@ -683,20 +707,24 @@ public class ColumnImpl implements Column, Comparable { return _props; } + @Override public Object setRowValue(Object[] rowArray, Object value) { rowArray[_columnIndex] = value; return value; } + @Override public Object setRowValue(Map rowMap, Object value) { rowMap.put(_name, value); return value; } + @Override public Object getRowValue(Object[] rowArray) { return rowArray[_columnIndex]; } + @Override public Object getRowValue(Map rowMap) { return rowMap.get(_name); } @@ -997,43 +1025,32 @@ public class ColumnImpl implements Column, Comparable { throws InvalidValueException { try { - return toDateDouble(value, getTimeZone(), getZoneId()); + return toDateDouble(value, this); } catch(IllegalArgumentException iae) { throw new InvalidValueException(withErrorContext(iae.getMessage()), iae); } } - /** - * Returns an access date double converted from a java Date/Calendar/Number - * time value. - * @usage _advanced_method_ - */ - private static double toDateDouble(Object value, DatabaseImpl db) - { - return toDateDouble(value, db.getTimeZone(), db.getZoneId()); - } - /** * Returns an access date double converted from a java * Date/Calendar/Number/Temporal time value. * @usage _advanced_method_ */ - private static double toDateDouble(Object value, TimeZone tz, ZoneId zoneId) + private static double toDateDouble(Object value, ZoneContext zc) { if(value instanceof TemporalAccessor) { - return toDateDouble( - toLocalDateTime((TemporalAccessor)value, tz, zoneId)); + return toDateDouble(toLocalDateTime((TemporalAccessor)value, zc)); } // seems access stores dates in the local timezone. guess you just // hope you read it in the same timezone in which it was written! long time = toDateLong(value); - time += getToLocalTimeZoneOffset(time, tz); + time += getToLocalTimeZoneOffset(time, zc.getTimeZone()); return toLocalDateDouble(time); } private static LocalDateTime toLocalDateTime( - TemporalAccessor value, TimeZone tz, ZoneId zoneId) { + TemporalAccessor value, ZoneContext zc) { // handle some common Temporal types if(value instanceof LocalDateTime) { @@ -1042,10 +1059,10 @@ public class ColumnImpl implements Column, Comparable { if(value instanceof ZonedDateTime) { // if the temporal value has a timezone, convert it to this db's timezone return ((ZonedDateTime)value).withZoneSameInstant( - getZoneId(tz, zoneId)).toLocalDateTime(); + zc.getZoneId()).toLocalDateTime(); } if(value instanceof Instant) { - return LocalDateTime.ofInstant((Instant)value, getZoneId(tz, zoneId)); + return LocalDateTime.ofInstant((Instant)value, zc.getZoneId()); } if(value instanceof LocalDate) { return ((LocalDate)value).atTime(BASE_LT); @@ -1069,7 +1086,7 @@ public class ColumnImpl implements Column, Comparable { if(zone != null) { // the Temporal has a zone, see if it is the right zone. if not, // adjust it - zoneId = getZoneId(tz, zoneId); + ZoneId zoneId = zc.getZoneId(); if(!zoneId.equals(zone)) { return ZonedDateTime.of(ld, lt, zone).withZoneSameInstant(zoneId) .toLocalDateTime(); @@ -1084,10 +1101,6 @@ public class ColumnImpl implements Column, Comparable { } } - private static ZoneId getZoneId(TimeZone tz, ZoneId zoneId) { - return ((zoneId != null) ? zoneId : tz.toZoneId()); - } - static double toLocalDateDouble(long time) { time += MILLIS_BETWEEN_EPOCH_AND_1900; @@ -1692,6 +1705,7 @@ public class ColumnImpl implements Column, Comparable { * Orders Columns by column number. * @usage _general_method_ */ + @Override public int compareTo(ColumnImpl other) { if (_columnNumber > other.getColumnNumber()) { return 1; @@ -2707,7 +2721,7 @@ public class ColumnImpl implements Column, Comparable { @Override public Object toInternalValue(DatabaseImpl db, Object value) { if(value instanceof TemporalAccessor) { - return toLocalDateTime((TemporalAccessor)value, null, db.getZoneId()); + return toLocalDateTime((TemporalAccessor)value, db); } Instant inst = Instant.ofEpochMilli(toDateLong(value)); return LocalDateTime.ofInstant(inst, db.getZoneId()); diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/DatabaseImpl.java b/src/main/java/com/healthmarketscience/jackcess/impl/DatabaseImpl.java index 2ff624e..c5f5481 100644 --- a/src/main/java/com/healthmarketscience/jackcess/impl/DatabaseImpl.java +++ b/src/main/java/com/healthmarketscience/jackcess/impl/DatabaseImpl.java @@ -89,7 +89,7 @@ import org.apache.commons.logging.LogFactory; * @author Tim McCune * @usage _intermediate_class_ */ -public class DatabaseImpl implements Database +public class DatabaseImpl implements Database, ZoneContext { private static final Log LOG = LogFactory.getLog(DatabaseImpl.class); diff --git a/src/main/java/com/healthmarketscience/jackcess/impl/ZoneContext.java b/src/main/java/com/healthmarketscience/jackcess/impl/ZoneContext.java new file mode 100644 index 0000000..0134e1f --- /dev/null +++ b/src/main/java/com/healthmarketscience/jackcess/impl/ZoneContext.java @@ -0,0 +1,32 @@ +/* +Copyright (c) 2018 James Ahlborn + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package com.healthmarketscience.jackcess.impl; + +import java.time.ZoneId; +import java.util.TimeZone; + +/** + * Provider of zone related info for date/time conversions. + * + * @author James Ahlborn + */ +interface ZoneContext +{ + public ZoneId getZoneId(); + + public TimeZone getTimeZone(); +} diff --git a/src/test/java/com/healthmarketscience/jackcess/DatabaseTest.java b/src/test/java/com/healthmarketscience/jackcess/DatabaseTest.java index de6bd94..209a63d 100644 --- a/src/test/java/com/healthmarketscience/jackcess/DatabaseTest.java +++ b/src/test/java/com/healthmarketscience/jackcess/DatabaseTest.java @@ -991,9 +991,9 @@ public class DatabaseTest extends TestCase { ColumnImpl col = new ColumnImpl(null, null, DataType.SHORT_DATE_TIME, 0, 0, 0) { @Override - protected TimeZone getTimeZone() { return tz; } + public TimeZone getTimeZone() { return tz; } @Override - protected ZoneId getZoneId() { return null; } + public ZoneId getZoneId() { return null; } }; SimpleDateFormat df = new SimpleDateFormat("yyyy.MM.dd"); diff --git a/src/test/java/com/healthmarketscience/jackcess/LocalDateTimeTest.java b/src/test/java/com/healthmarketscience/jackcess/LocalDateTimeTest.java index 5dde831..637629a 100644 --- a/src/test/java/com/healthmarketscience/jackcess/LocalDateTimeTest.java +++ b/src/test/java/com/healthmarketscience/jackcess/LocalDateTimeTest.java @@ -127,9 +127,9 @@ public class LocalDateTimeTest extends TestCase final TimeZone tz = TimeZone.getTimeZone(zoneId); ColumnImpl col = new ColumnImpl(null, null, DataType.SHORT_DATE_TIME, 0, 0, 0) { @Override - protected TimeZone getTimeZone() { return tz; } + public TimeZone getTimeZone() { return tz; } @Override - protected ZoneId getZoneId() { return zoneId; } + public ZoneId getZoneId() { return zoneId; } }; SimpleDateFormat df = new SimpleDateFormat("yyyy.MM.dd"); diff --git a/src/test/java/com/healthmarketscience/jackcess/TableTest.java b/src/test/java/com/healthmarketscience/jackcess/TableTest.java index 3bc2dbd..eaae617 100644 --- a/src/test/java/com/healthmarketscience/jackcess/TableTest.java +++ b/src/test/java/com/healthmarketscience/jackcess/TableTest.java @@ -185,7 +185,7 @@ public class TableTest extends TestCase { return getFormat().CHARSET; } @Override - protected TimeZone getTimeZone() { + public TimeZone getTimeZone() { return TimeZone.getDefault(); } @Override -- 2.39.5