Repository: olingo-odata4 Updated Branches: refs/heads/master 187c229b6 -> 3c205f907
OLINGO-864 refining date time behavior Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/382ec16e Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/382ec16e Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/382ec16e Branch: refs/heads/master Commit: 382ec16ee12dda57aa0ab527b45a59cf9b32be54 Parents: fbdf9aa Author: shawkins <[email protected]> Authored: Wed Feb 3 09:46:24 2016 -0500 Committer: shawkins <[email protected]> Committed: Wed Feb 3 09:46:24 2016 -0500 ---------------------------------------------------------------------- .../commons/core/edm/primitivetype/EdmDate.java | 5 +- .../edm/primitivetype/EdmDateTimeOffset.java | 67 ++++++++++++++------ .../core/edm/primitivetype/EdmTimeOfDay.java | 19 ++---- .../core/edm/primitivetype/EdmDateTest.java | 1 - .../primitivetype/EdmDateTimeOffsetTest.java | 4 +- .../edm/primitivetype/EdmTimeOfDayTest.java | 41 +++++++++++- 6 files changed, 97 insertions(+), 40 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/382ec16e/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDate.java ---------------------------------------------------------------------- diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDate.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDate.java index 71b747f..fb3f4ad 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDate.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDate.java @@ -21,7 +21,6 @@ package org.apache.olingo.commons.core.edm.primitivetype; import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException; import java.util.Calendar; -import java.util.TimeZone; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -48,7 +47,7 @@ public final class EdmDate extends SingletonPrimitiveType { final Boolean isNullable, final Integer maxLength, final Integer precision, final Integer scale, final Boolean isUnicode, final Class<T> returnType) throws EdmPrimitiveTypeException { - final Calendar dateTimeValue = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + final Calendar dateTimeValue = Calendar.getInstance(EdmDateTimeOffset.getDefaultTimeZone()); dateTimeValue.clear(); final Matcher matcher = PATTERN.matcher(value); @@ -75,7 +74,7 @@ public final class EdmDate extends SingletonPrimitiveType { final Boolean isNullable, final Integer maxLength, final Integer precision, final Integer scale, final Boolean isUnicode) throws EdmPrimitiveTypeException { - final Calendar dateTimeValue = EdmDateTimeOffset.createDateTime(value); + final Calendar dateTimeValue = EdmDateTimeOffset.createDateTime(value, true); final StringBuilder result = new StringBuilder(10); // Ten characters are enough for "normal" dates. final int year = dateTimeValue.get(Calendar.YEAR); http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/382ec16e/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffset.java ---------------------------------------------------------------------- diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffset.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffset.java index 6646c83..95b0fa5 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffset.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffset.java @@ -20,6 +20,7 @@ package org.apache.olingo.commons.core.edm.primitivetype; import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException; +import java.sql.Time; import java.sql.Timestamp; import java.text.DecimalFormat; import java.util.Calendar; @@ -115,6 +116,7 @@ public final class EdmDateTimeOffset extends SingletonPrimitiveType { /** * Converts a {@link Calendar} value into the requested return type if possible. + * <br>It is expected that the {@link Calendar} value will already be in the desired time zone. * * @param dateTimeValue the value * @param nanoSeconds nanoseconds part of the value; only used for the {@link Timestamp} return type @@ -147,6 +149,20 @@ public final class EdmDateTimeOffset extends SingletonPrimitiveType { Timestamp timestamp = new Timestamp(dateTimeValue.getTimeInMillis()); timestamp.setNanos(nanoSeconds); return returnType.cast(timestamp); + } else if (returnType.isAssignableFrom(Time.class)) { + //normalize the value + dateTimeValue.set(Calendar.YEAR, 1970); + dateTimeValue.set(Calendar.MONTH, Calendar.JANUARY); + dateTimeValue.set(Calendar.DAY_OF_MONTH, 1); + dateTimeValue.set(Calendar.MILLISECOND, 0); + return returnType.cast(new Time(dateTimeValue.getTimeInMillis())); // may throw IllegalArgumentException + } else if (returnType.isAssignableFrom(java.sql.Date.class)) { + //normalize the value + dateTimeValue.set(Calendar.HOUR_OF_DAY, 0); + dateTimeValue.set(Calendar.MINUTE, 0); + dateTimeValue.set(Calendar.SECOND, 0); + dateTimeValue.set(Calendar.MILLISECOND, 0); + return returnType.cast(new java.sql.Date(dateTimeValue.getTimeInMillis())); // may throw IllegalArgumentException } else { throw new ClassCastException("unsupported return type " + returnType.getSimpleName()); } @@ -157,18 +173,8 @@ public final class EdmDateTimeOffset extends SingletonPrimitiveType { final Boolean isNullable, final Integer maxLength, final Integer precision, final Integer scale, final Boolean isUnicode) throws EdmPrimitiveTypeException { - final Calendar dateTimeValue; - final int fractionalSecs; - if (value instanceof Timestamp) { - final Calendar tmp = Calendar.getInstance(TimeZone.getTimeZone("GMT")); - tmp.setTimeInMillis(((Timestamp) value).getTime()); - dateTimeValue = createDateTime(tmp); - fractionalSecs = ((Timestamp) value).getNanos(); - } else { - dateTimeValue = createDateTime(value); - fractionalSecs = dateTimeValue.get(Calendar.MILLISECOND); - } - + final Calendar dateTimeValue = createDateTime(value, false); + final StringBuilder result = new StringBuilder(); final int year = dateTimeValue.get(Calendar.YEAR); appendTwoDigits(result, year / 100); @@ -186,8 +192,10 @@ public final class EdmDateTimeOffset extends SingletonPrimitiveType { try { if (value instanceof Timestamp) { + int fractionalSecs = ((Timestamp) value).getNanos(); appendFractionalSeconds(result, fractionalSecs, precision); } else { + int fractionalSecs = dateTimeValue.get(Calendar.MILLISECOND); appendMilliseconds(result, fractionalSecs, precision); } } catch (final IllegalArgumentException e) { @@ -211,18 +219,27 @@ public final class EdmDateTimeOffset extends SingletonPrimitiveType { * @return the value as {@link Calendar} * @throws EdmPrimitiveTypeException if the type of the value is not supported */ - protected static <T> Calendar createDateTime(final T value) throws EdmPrimitiveTypeException { + protected static <T> Calendar createDateTime(final T value, boolean isLocal) throws EdmPrimitiveTypeException { Calendar dateTimeValue; if (value instanceof Date) { - // Although java.util.Date, as stated in its documentation, - // "is intended to reflect coordinated universal time (UTC)", - // its toString() method uses the default time zone. And so do we. - dateTimeValue = Calendar.getInstance(); + TimeZone tz; + if (isLocal) { + tz = getDefaultTimeZone(); + } else { + tz = TimeZone.getTimeZone("GMT"); + } + dateTimeValue = Calendar.getInstance(tz); dateTimeValue.setTime((Date) value); } else if (value instanceof Calendar) { dateTimeValue = (Calendar) ((Calendar) value).clone(); } else if (value instanceof Long) { - dateTimeValue = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + TimeZone tz; + if (isLocal) { + tz = getDefaultTimeZone(); + } else { + tz = TimeZone.getTimeZone("GMT"); + } + dateTimeValue = Calendar.getInstance(tz); dateTimeValue.setTimeInMillis((Long) value); } else { throw new EdmPrimitiveTypeException("The value type " + value.getClass() + " is not supported."); @@ -300,4 +317,18 @@ public final class EdmDateTimeOffset extends SingletonPrimitiveType { result.append('.').append(formatted.substring(0, actualLength)); } } + + /** + * When the Timezone information is absent on the date time types, like EdmDate, EDMTimeOfDay, EdmDateTimeOffset + * this method defines the default timezone that should be used parse and output payload. + * User should set system property "defaultTimeZoneForEdmDateTypes" to control this. The default would be + * Java VM default if not defined. + * + * @return Timezone + */ + protected static TimeZone getDefaultTimeZone() { + String tz = System.getProperty("defaultTimeZoneForEdmDateTypes"); + return (tz != null)?TimeZone.getTimeZone(tz):TimeZone.getDefault(); + } + } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/382ec16e/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTimeOfDay.java ---------------------------------------------------------------------- diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTimeOfDay.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTimeOfDay.java index fb10e02..3090761 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTimeOfDay.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTimeOfDay.java @@ -22,7 +22,6 @@ import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException; import java.sql.Timestamp; import java.util.Calendar; -import java.util.TimeZone; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -52,7 +51,7 @@ public final class EdmTimeOfDay extends SingletonPrimitiveType { throw new EdmPrimitiveTypeException("The literal '" + value + "' has illegal content."); } - final Calendar dateTimeValue = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + final Calendar dateTimeValue = Calendar.getInstance(EdmDateTimeOffset.getDefaultTimeZone()); dateTimeValue.clear(); dateTimeValue.set(Calendar.HOUR_OF_DAY, Byte.parseByte(matcher.group(1))); dateTimeValue.set(Calendar.MINUTE, Byte.parseByte(matcher.group(2))); @@ -92,18 +91,8 @@ public final class EdmTimeOfDay extends SingletonPrimitiveType { final Boolean isNullable, final Integer maxLength, final Integer precision, final Integer scale, final Boolean isUnicode) throws EdmPrimitiveTypeException { - final Calendar dateTimeValue; - final int fractionalSecs; - if (value instanceof Timestamp) { - final Calendar tmp = Calendar.getInstance(); - tmp.setTimeInMillis(((Timestamp) value).getTime()); - dateTimeValue = EdmDateTimeOffset.createDateTime(tmp); - fractionalSecs = ((Timestamp) value).getNanos(); - } else { - dateTimeValue = EdmDateTimeOffset.createDateTime(value); - fractionalSecs = dateTimeValue.get(Calendar.MILLISECOND); - } - + final Calendar dateTimeValue = EdmDateTimeOffset.createDateTime(value, true); + final StringBuilder result = new StringBuilder(); EdmDateTimeOffset.appendTwoDigits(result, dateTimeValue.get(Calendar.HOUR_OF_DAY)); result.append(':'); @@ -113,8 +102,10 @@ public final class EdmTimeOfDay extends SingletonPrimitiveType { try { if (value instanceof Timestamp) { + int fractionalSecs = ((Timestamp) value).getNanos(); EdmDateTimeOffset.appendFractionalSeconds(result, fractionalSecs, precision); } else { + int fractionalSecs = dateTimeValue.get(Calendar.MILLISECOND); EdmDateTimeOffset.appendMilliseconds(result, fractionalSecs, precision); } } catch (final IllegalArgumentException e) { http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/382ec16e/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTest.java ---------------------------------------------------------------------- diff --git a/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTest.java b/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTest.java index 6e10d2b..26b6a49 100644 --- a/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTest.java +++ b/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTest.java @@ -67,7 +67,6 @@ public class EdmDateTest extends PrimitiveTypeBaseTest { public void valueOfString() throws Exception { Calendar dateTime = Calendar.getInstance(); dateTime.clear(); - dateTime.setTimeZone(TimeZone.getTimeZone("GMT")); dateTime.set(2012, 1, 29); assertEquals(dateTime, instance.valueOfString("2012-02-29", null, null, null, null, null, Calendar.class)); assertEquals(Long.valueOf(dateTime.getTimeInMillis()), instance.valueOfString("2012-02-29", null, null, null, null, http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/382ec16e/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffsetTest.java ---------------------------------------------------------------------- diff --git a/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffsetTest.java b/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffsetTest.java index 3013916..0b51925 100644 --- a/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffsetTest.java +++ b/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffsetTest.java @@ -28,7 +28,6 @@ import java.util.Date; import java.util.TimeZone; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; public class EdmDateTimeOffsetTest extends PrimitiveTypeBaseTest { @@ -77,8 +76,7 @@ public class EdmDateTimeOffsetTest extends PrimitiveTypeBaseTest { assertEquals("1969-12-31T23:59:59.98Z", instance.valueToString(-20L, null, null, 2, null, null)); final Date date = new Date(millis); - final String time = date.toString().substring(11, 19); - assertTrue(instance.valueToString(date, null, null, 3, null, null).contains(time)); + assertEquals("2012-02-29T23:32:03.007Z", instance.valueToString(date, null, null, 3, null, null)); expectFacetsErrorInValueToString(instance, millis, null, null, null, null, null); expectFacetsErrorInValueToString(instance, 3L, null, null, 2, null, null); http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/382ec16e/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTimeOfDayTest.java ---------------------------------------------------------------------- diff --git a/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTimeOfDayTest.java b/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTimeOfDayTest.java index 917814d..57dd5d9 100644 --- a/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTimeOfDayTest.java +++ b/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTimeOfDayTest.java @@ -22,6 +22,7 @@ import org.apache.olingo.commons.api.edm.EdmPrimitiveType; import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind; import org.junit.Test; +import java.sql.Time; import java.util.Calendar; import java.util.TimeZone; @@ -60,12 +61,50 @@ public class EdmTimeOfDayTest extends PrimitiveTypeBaseTest { expectTypeErrorInValueToString(instance, 0); } + + @Test + public void valueToStringWithGMT() throws Exception { + Calendar dateTime = Calendar.getInstance(); + dateTime.clear(); + dateTime.setTimeZone(TimeZone.getTimeZone("GMT+11:30")); + dateTime.set(1, 2, 3, 4, 5, 6); + assertEquals("04:05:06", instance.valueToString(dateTime, null, null, null, null, null)); + } + + @Test + public void testRoundTripTime() throws Exception { + java.sql.Time time = instance.valueOfString("04:05:06.002", true, + 4000, 3, 0, true, java.sql.Time.class); + String val = instance.valueToString(time, true, 4000, 3, 0, true); + assertEquals("04:05:06", val); + } + + @Test + public void toTimeObject() throws Exception { + Calendar dateTime = Calendar.getInstance(); + dateTime.clear(); + dateTime.set(Calendar.HOUR, 12); + + Time timeValue = instance.valueOfString("12:00:00", null, null, null, null, null, Time.class); + assertEquals(dateTime.getTimeInMillis(), timeValue.getTime()); + } + + @Test + public void fromTimeObject() throws Exception { + Calendar dateTime = Calendar.getInstance(); + dateTime.clear(); + dateTime.set(Calendar.HOUR, 5); + dateTime.set(Calendar.MINUTE, 59); + dateTime.set(Calendar.SECOND, 23); + + Time time = new Time(dateTime.getTimeInMillis()); + assertEquals("05:59:23", instance.valueToString(time, null, null, null, null, null)); + } @Test public void valueOfString() throws Exception { Calendar dateTime = Calendar.getInstance(); dateTime.clear(); - dateTime.setTimeZone(TimeZone.getTimeZone("GMT")); assertEquals(dateTime, instance.valueOfString("00:00", null, null, null, null, null, Calendar.class)); assertEquals(dateTime, instance.valueOfString("00:00:00", null, null, null, null, null, Calendar.class));
