]> source.dussan.org Git - vaadin-framework.git/commitdiff
Use ZoneId rather than ZoneOffset for conversion (#9620)
authorEzra Epstein <eepstein@users.noreply.github.com>
Mon, 3 Jul 2017 07:45:19 +0000 (00:45 -0700)
committerHenri Sara <henri.sara@gmail.com>
Mon, 3 Jul 2017 07:45:19 +0000 (10:45 +0300)
Use ZoneId rather than ZoneOffset for conversion between model (Date) and presentation of LocalDateTime.

LocalDateToDateConverter (correctly) uses ZoneId, whereas LocalDateTimeToDateConverter (incorrectly) used a ZoneOffset. This fix aligns the two Converter implementations and makes the latter one more robust.

A ZoneOffset is a fixed time difference, e.g., +07:00, whereas a time zone - represented by a ZoneId - is more dynamic, including features like Daylight-Savings Time. A ZoneId returns one or more ZoneOffsets via its ZoneRules method. (ZoneOffsets have trivial ZoneRules that simply return the ZoneOffset.)

Since the date/time being displayed may be from any date on the calendar, the ZoneOffset imposes a negative limitation. Using ZoneId instead gets us past that limitation and allows a more robust set of conversion rules.

Fixes #9594

server/src/main/java/com/vaadin/data/converter/LocalDateTimeToDateConverter.java

index e5fa45a3fb74df0cb52e16f09a6d1d2add4cfc98..167c452eafa8c6b620d3b449af1c15271834e429 100644 (file)
@@ -17,7 +17,7 @@ package com.vaadin.data.converter;
 
 import java.time.Instant;
 import java.time.LocalDateTime;
-import java.time.ZoneOffset;
+import java.time.ZoneId;
 import java.util.Date;
 import java.util.Objects;
 
@@ -35,41 +35,35 @@ import com.vaadin.ui.InlineDateTimeField;
  * @author Vaadin Ltd
  * @since 8.0
  */
-public class LocalDateTimeToDateConverter
-        implements Converter<LocalDateTime, Date> {
+public class LocalDateTimeToDateConverter implements Converter<LocalDateTime, Date> {
 
-    private ZoneOffset zoneOffset;
+    private ZoneId zoneId;
 
     /**
      * Creates a new converter using the given time zone.
      *
-     * @param zoneOffset
-     *            the time zone offset to use, not <code>null</code>
+     * @param zoneId the time zone to use, not <code>null</code>
      */
-    public LocalDateTimeToDateConverter(ZoneOffset zoneOffset) {
-        this.zoneOffset = Objects.requireNonNull(zoneOffset,
-                "Zone offset cannot be null");
+    public LocalDateTimeToDateConverter(ZoneId zoneId) {
+        this.zoneId = Objects.requireNonNull(zoneId, "Zone identifier cannot be null");
     }
 
     @Override
-    public Result<Date> convertToModel(LocalDateTime localDate,
-            ValueContext context) {
+    public Result<Date> convertToModel(LocalDateTime localDate, ValueContext context) {
         if (localDate == null) {
             return Result.ok(null);
         }
 
-        return Result.ok(Date.from(localDate.toInstant(zoneOffset)));
+        return Result.ok(Date.from(localDate.atZone(zoneId).toInstant()));
     }
 
     @Override
-    public LocalDateTime convertToPresentation(Date date,
-            ValueContext context) {
+    public LocalDateTime convertToPresentation(Date date, ValueContext context) {
         if (date == null) {
             return null;
         }
 
-        return Instant.ofEpochMilli(date.getTime()).atZone(zoneOffset)
-                .toLocalDateTime();
+        return Instant.ofEpochMilli(date.getTime()).atZone(zoneId).toLocalDateTime();
     }
 
 }