You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2018/10/09 15:14:32 UTC

[isis] 01/01: ISIS-2005: fixes java.sql.Date rendered with -1 day offset

This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a commit to branch ISIS-2005_temporal-type-rendering
in repository https://gitbox.apache.org/repos/asf/isis.git

commit 1a427745ed8561ff542f789fc541dd9e28b0645e
Author: Andi Huber <ah...@apache.org>
AuthorDate: Tue Oct 9 17:14:12 2018 +0200

    ISIS-2005: fixes java.sql.Date rendered with -1 day offset
    
    also provides de-duplication and constructor simplification
    
    Task-Url: https://issues.apache.org/jira/browse/ISIS-2005
---
 .../datesql/JavaSqlDateValueSemanticsProvider.java | 11 ++-
 .../components/scalars/DateConverterAbstract.java  | 20 ++---
 .../ui/components/scalars/DateFormatSettings.java  | 86 ++++++++++++++++++++++
 .../ui/components/scalars/TextFieldValueModel.java |  3 +
 .../scalars/datepicker/DateTimeConfig.java         |  2 +
 .../datepicker/TextFieldWithDateTimePicker.java    | 12 ++-
 .../jdk8time/DateConverterForJdk8Abstract.java     | 17 +++--
 .../jdk8time/DateConverterForJdk8LocalDate.java    |  6 +-
 .../DateConverterForJdk8LocalDateTime.java         |  7 +-
 .../DateConverterForJdk8OffsetDateTime.java        |  6 +-
 .../jdkdates/DateConverterForJavaAbstract.java     | 76 +++++++++++++++++--
 .../jdkdates/DateConverterForJavaSqlDate.java      | 43 +++++------
 .../jdkdates/DateConverterForJavaSqlTimestamp.java | 41 ++++-------
 .../jdkdates/DateConverterForJavaUtilDate.java     | 39 +++-------
 .../scalars/jdkdates/JavaSqlDatePanel.java         |  6 ++
 .../scalars/jdkdates/JavaUtilDatePanel.java        |  5 ++
 .../jodatime/DateConverterForJodaAbstract.java     | 17 ++---
 .../jodatime/DateConverterForJodaDateTime.java     |  8 +-
 .../jodatime/DateConverterForJodaLocalDate.java    |  7 +-
 .../DateConverterForJodaLocalDateTime.java         |  9 +--
 20 files changed, 280 insertions(+), 141 deletions(-)

diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datesql/JavaSqlDateValueSemanticsProvider.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datesql/JavaSqlDateValueSemanticsProvider.java
index a240e27..87a6a28 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datesql/JavaSqlDateValueSemanticsProvider.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datesql/JavaSqlDateValueSemanticsProvider.java
@@ -68,7 +68,6 @@ public class JavaSqlDateValueSemanticsProvider extends DateValueSemanticsProvide
         cal.add(Calendar.YEAR, years);
         cal.add(Calendar.MONTH, months);
         cal.add(Calendar.DAY_OF_MONTH, days);
-
         return setDate(cal.getTime());
     }
 
@@ -86,5 +85,15 @@ public class JavaSqlDateValueSemanticsProvider extends DateValueSemanticsProvide
     protected Date now() {
         return new Date(Clock.getTime());
     }
+    
+    @Override //[ISIS-2005] java.sql.Date requires special treatment, so overriding the default
+    protected String doEncode(final Object pojo) {
+        return ((Date)pojo).toString();
+    }
+
+    @Override //[ISIS-2005] java.sql.Date requires special treatment, so overriding the default
+    protected Date doRestore(final String enString) {
+        return Date.valueOf(enString);
+    }
 
 }
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/DateConverterAbstract.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/DateConverterAbstract.java
index 8297f2a..15f494d 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/DateConverterAbstract.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/DateConverterAbstract.java
@@ -30,17 +30,11 @@ public abstract class DateConverterAbstract<T> implements DateConverter<T> {
     private static final long serialVersionUID = 1L;
 
     private final Class<T> cls;
-    protected final String datePattern;
-    protected final String dateTimePattern;
+    protected final DateFormatSettings dateFormatSettings;
 
-    protected final int adjustBy;
-
-
-    protected DateConverterAbstract(Class<T> cls, String datePattern, String dateTimePattern, int adjustBy) {
+    protected DateConverterAbstract(Class<T> cls, DateFormatSettings dateFormatSettings) {
         this.cls = cls;
-        this.datePattern = datePattern;
-        this.dateTimePattern = dateTimePattern;
-        this.adjustBy = adjustBy;
+        this.dateFormatSettings = dateFormatSettings;
     }
 
     @Override
@@ -50,20 +44,20 @@ public abstract class DateConverterAbstract<T> implements DateConverter<T> {
 
     @Override
     public String getDatePattern(Locale locale) {
-        return datePattern;
+        return dateFormatSettings.getDatePattern();
     }
 
     @Override
     public String getDateTimePattern(Locale locale) {
-        return dateTimePattern;
+        return dateFormatSettings.getDateTimePattern();
     }
 
     protected DateTimeFormatter getFormatterForDatePattern() {
-        return DateTimeFormat.forPattern(datePattern);
+        return DateTimeFormat.forPattern(dateFormatSettings.getDatePattern());
     }
 
     protected DateTimeFormatter getFormatterForDateTimePattern() {
-        return DateTimeFormat.forPattern(dateTimePattern);
+        return DateTimeFormat.forPattern(dateFormatSettings.getDateTimePattern());
     }
 
     @Override
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/DateFormatSettings.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/DateFormatSettings.java
new file mode 100644
index 0000000..6308321
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/DateFormatSettings.java
@@ -0,0 +1,86 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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 org.apache.isis.viewer.wicket.ui.components.scalars;
+
+import java.io.Serializable;
+
+import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
+
+public class DateFormatSettings implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+    
+    private final String datePattern;
+    private final String dateTimePattern;
+    private final int adjustBy;
+    
+    // -- FACTORIES
+    
+    public static DateFormatSettings of(String datePattern, String dateTimePattern, int adjustBy) {
+        return new DateFormatSettings(datePattern, dateTimePattern, adjustBy);
+    }
+    
+    public static DateFormatSettings of(String datePattern, String dateTimePattern) {
+        return of(datePattern, dateTimePattern, /*adjustBy*/ 0);
+    }
+    
+    public static DateFormatSettings of(String datePattern) {
+        return of(datePattern, /*dateTimePattern same as*/ datePattern, /*adjustBy*/ 0);
+    }
+    
+    public static DateFormatSettings ofDateAndTime(WicketViewerSettings settings, int adjustBy) {
+        return of(settings.getDatePattern(), settings.getDateTimePattern(), adjustBy);
+    }
+    
+    public static DateFormatSettings ofDateOnly(WicketViewerSettings settings, int adjustBy) {
+        return of(settings.getDatePattern(), settings.getDatePattern(), adjustBy);
+    }
+    
+    // -- IMPLEMENTATION
+    
+    private DateFormatSettings(String datePattern, String dateTimePattern, int adjustBy) {
+        this.datePattern = datePattern;
+        this.dateTimePattern = dateTimePattern;
+        this.adjustBy = adjustBy;
+    }
+
+    public String getDatePattern() {
+        return datePattern;
+    }
+
+    public String getDateTimePattern() {
+        return dateTimePattern;
+    }
+
+    /**
+     * day offset
+     */
+    public int getAdjustBy() {
+        return adjustBy;
+    }
+
+    @Override
+    public String toString() {
+        return "DateFormatSettings [datePattern=" + datePattern + ", dateTimePattern=" + dateTimePattern + ", adjustBy="
+                + adjustBy + "]";
+    }
+
+    
+    
+}
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/TextFieldValueModel.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/TextFieldValueModel.java
index 4db0201..a0835e0 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/TextFieldValueModel.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/TextFieldValueModel.java
@@ -43,6 +43,9 @@ public class TextFieldValueModel<T extends Serializable> extends Model<T> {
     private final ScalarModelProvider scalarModelProvider;
 
     public TextFieldValueModel(ScalarModelProvider scalarModelProvider) {
+        
+        System.out.println("!!! TextFieldValueModel: "+scalarModelProvider.getModel().getObjectAsString());
+        
         this.scalarModelProvider = scalarModelProvider;
     }
 
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/datepicker/DateTimeConfig.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/datepicker/DateTimeConfig.java
index 1f37b49..f7ee109 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/datepicker/DateTimeConfig.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/datepicker/DateTimeConfig.java
@@ -38,6 +38,8 @@ import org.joda.time.format.DateTimeFormatter;
  * JavaScript widget
  */
 public class DateTimeConfig extends AbstractConfig {
+    private static final long serialVersionUID = 1L;
+
     /**
      * The earliest date that may be selected; all earlier dates will be disabled.
      */
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/datepicker/TextFieldWithDateTimePicker.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/datepicker/TextFieldWithDateTimePicker.java
index 2d270bb..4b500d4 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/datepicker/TextFieldWithDateTimePicker.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/datepicker/TextFieldWithDateTimePicker.java
@@ -68,6 +68,8 @@ public class TextFieldWithDateTimePicker<T> extends TextField<T> implements ICon
 
     public TextFieldWithDateTimePicker(String id, IModel<T> model, Class<T> type, DateConverter<T> converter) {
         super(id, model, type);
+        
+        System.out.println("!!! model("+id+"): "+model.getObject());
 
         DateTimeConfig config = new DateTimeConfig();
 
@@ -110,11 +112,17 @@ public class TextFieldWithDateTimePicker<T> extends TextField<T> implements ICon
 
     @Override
     public T convertToObject(String value, Locale locale) {
+        
+        System.out.println("!!! picker toObject: "+value);
+        
         return converter.convertToObject(value, locale);
     }
 
     @Override
     public String convertToString(T value, Locale locale) {
+        
+        System.out.println("!!! picker toString: "+value);
+        
         return converter.convertToString(value, locale);
     }
 
@@ -162,7 +170,9 @@ public class TextFieldWithDateTimePicker<T> extends TextField<T> implements ICon
 
     IsisConfiguration getConfiguration() {
         return getIsisSessionFactory().getConfiguration();
-    }IsisSessionFactory getIsisSessionFactory() {
+    }
+    
+    IsisSessionFactory getIsisSessionFactory() {
         return IsisContext.getSessionFactory();
     }
 
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/DateConverterForJdk8Abstract.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/DateConverterForJdk8Abstract.java
index a40e5c5..7ad9018 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/DateConverterForJdk8Abstract.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/DateConverterForJdk8Abstract.java
@@ -20,6 +20,7 @@ package org.apache.isis.viewer.wicket.ui.components.scalars.jdk8time;
 
 import org.apache.wicket.util.convert.ConversionException;
 import org.apache.isis.viewer.wicket.ui.components.scalars.DateConverterAbstract;
+import org.apache.isis.viewer.wicket.ui.components.scalars.DateFormatSettings;
 
 import java.time.format.DateTimeFormatter;
 import java.util.Locale;
@@ -28,29 +29,29 @@ abstract class DateConverterForJdk8Abstract<T> extends DateConverterAbstract<T>
 
     private static final long serialVersionUID = 1L;
 
-    DateConverterForJdk8Abstract(Class<T> cls, String datePattern, String dateTimePattern, int adjustBy) {
-        super(cls, datePattern, dateTimePattern, adjustBy);
+    DateConverterForJdk8Abstract(Class<T> cls, DateFormatSettings dateFormatSettings) {
+        super(cls, dateFormatSettings);
     }
-
+    
     @Override
     protected final T doConvertToObject(String value, Locale locale) {
         T dateTime = convert(value);
-        return minusDays(dateTime, adjustBy);
+        return minusDays(dateTime, dateFormatSettings.getAdjustBy());
     }
 
     @Override
     protected String doConvertToString(T value, Locale locale) {
         // for JodaLocalDate, the date time pattern is same as date pattern, so can use either to convert to string.
-        T t = plusDays(value, adjustBy);
-        return toString(t, DateTimeFormatter.ofPattern(dateTimePattern));
+        T t = plusDays(value, dateFormatSettings.getAdjustBy());
+        return toString(t, DateTimeFormatter.ofPattern(dateFormatSettings.getDateTimePattern()));
     }
 
     protected DateTimeFormatter getFormatterForDatePattern8() {
-        return DateTimeFormatter.ofPattern(datePattern);
+        return DateTimeFormatter.ofPattern(dateFormatSettings.getDatePattern());
     }
 
     protected DateTimeFormatter getFormatterForDateTimePattern8() {
-        return DateTimeFormatter.ofPattern(dateTimePattern);
+        return DateTimeFormatter.ofPattern(dateFormatSettings.getDateTimePattern());
     }
 
     protected abstract T minusDays(T value, int adjustBy);
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/DateConverterForJdk8LocalDate.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/DateConverterForJdk8LocalDate.java
index 2e26654..33c575f 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/DateConverterForJdk8LocalDate.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/DateConverterForJdk8LocalDate.java
@@ -21,9 +21,11 @@ package org.apache.isis.viewer.wicket.ui.components.scalars.jdk8time;
 import java.time.LocalDate;
 import java.time.format.DateTimeFormatter;
 
-import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
 import org.apache.wicket.util.convert.ConversionException;
 
+import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
+import org.apache.isis.viewer.wicket.ui.components.scalars.DateFormatSettings;
+
 /**
  * Uses the same pattern for both date and date/time.  The only real consequence of this is that when converting a
  * string value to the date value, only a single pattern is used.
@@ -33,7 +35,7 @@ public class DateConverterForJdk8LocalDate extends DateConverterForJdk8Abstract<
     private static final long serialVersionUID = 1L;
 
     public DateConverterForJdk8LocalDate(WicketViewerSettings settings, int adjustBy) {
-        super(LocalDate.class, settings.getDatePattern(), settings.getDatePattern(), adjustBy);
+        super(LocalDate.class, DateFormatSettings.ofDateOnly(settings, adjustBy));
     }
 
     @Override
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/DateConverterForJdk8LocalDateTime.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/DateConverterForJdk8LocalDateTime.java
index 380600d..e545317 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/DateConverterForJdk8LocalDateTime.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/DateConverterForJdk8LocalDateTime.java
@@ -24,6 +24,8 @@ import java.time.LocalTime;
 import java.time.format.DateTimeFormatter;
 
 import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
+import org.apache.isis.viewer.wicket.ui.components.scalars.DateFormatSettings;
+
 import org.apache.wicket.util.convert.ConversionException;
 
 public class DateConverterForJdk8LocalDateTime extends DateConverterForJdk8Abstract<LocalDateTime> {
@@ -31,10 +33,9 @@ public class DateConverterForJdk8LocalDateTime extends DateConverterForJdk8Abstr
     private static final long serialVersionUID = 1L;
 
     public DateConverterForJdk8LocalDateTime(WicketViewerSettings settings, int adjustBy) {
-        super(LocalDateTime.class, settings.getDatePattern(), settings.getDateTimePattern(), adjustBy);
+        super(LocalDateTime.class, DateFormatSettings.ofDateAndTime(settings, adjustBy));
     }
 
-
     @Override
     protected LocalDateTime minusDays(LocalDateTime value, int adjustBy) {
         return value.minusDays(adjustBy);
@@ -63,7 +64,7 @@ public class DateConverterForJdk8LocalDateTime extends DateConverterForJdk8Abstr
                 throw new ConversionException(
                         String.format(
                                 "Cannot convert '%s' into a date/time using pattern '%s' or '%s'",
-                                value, dateTimePattern, datePattern),
+                                value, dateFormatSettings.getDateTimePattern(), dateFormatSettings.getDatePattern()),
                         ex2	);
             }
         }
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/DateConverterForJdk8OffsetDateTime.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/DateConverterForJdk8OffsetDateTime.java
index 18ae7be..8cc581a 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/DateConverterForJdk8OffsetDateTime.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/DateConverterForJdk8OffsetDateTime.java
@@ -26,6 +26,8 @@ import java.time.ZoneOffset;
 import java.time.format.DateTimeFormatter;
 
 import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
+import org.apache.isis.viewer.wicket.ui.components.scalars.DateFormatSettings;
+
 import org.apache.wicket.util.convert.ConversionException;
 
 public class DateConverterForJdk8OffsetDateTime extends DateConverterForJdk8Abstract<OffsetDateTime> {
@@ -33,7 +35,7 @@ public class DateConverterForJdk8OffsetDateTime extends DateConverterForJdk8Abst
     private static final long serialVersionUID = 1L;
 
     public DateConverterForJdk8OffsetDateTime(WicketViewerSettings settings, int adjustBy) {
-        super(OffsetDateTime.class, settings.getDatePattern(), settings.getDateTimePattern(), adjustBy);
+        super(OffsetDateTime.class, DateFormatSettings.ofDateAndTime(settings, adjustBy));
     }
 
     @Override
@@ -79,7 +81,7 @@ public class DateConverterForJdk8OffsetDateTime extends DateConverterForJdk8Abst
                 throw new ConversionException(
                         String.format(
                                 "Cannot convert '%s' into a date/time using pattern '%s' or '%s'",
-                                value, dateTimePattern, datePattern),
+                                value, dateFormatSettings.getDateTimePattern(), dateFormatSettings.getDatePattern()),
                         ex2	);
             }
         }
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/DateConverterForJavaAbstract.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/DateConverterForJavaAbstract.java
index 7d20b62..748582b 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/DateConverterForJavaAbstract.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/DateConverterForJavaAbstract.java
@@ -18,24 +18,88 @@
  */
 package org.apache.isis.viewer.wicket.ui.components.scalars.jdkdates;
 
+import java.text.ParseException;
 import java.text.SimpleDateFormat;
+import java.util.Calendar;
+
+import org.apache.wicket.util.convert.ConversionException;
 
 import org.apache.isis.viewer.wicket.ui.components.scalars.DateConverterAbstract;
+import org.apache.isis.viewer.wicket.ui.components.scalars.DateFormatSettings;
 
 public abstract class DateConverterForJavaAbstract<T extends java.util.Date> extends DateConverterAbstract<T> {
     private static final long serialVersionUID = 1L;
+    
+    private transient SimpleDateFormat dateOnlyPattern;
+    private transient SimpleDateFormat dateTimePattern;
 
-    public DateConverterForJavaAbstract(final Class<T> cls, final String datePattern, String dateTimePattern, String datePickerPattern, int adjustBy) {
-        super(cls, datePattern, dateTimePattern, adjustBy);
+    public DateConverterForJavaAbstract(Class<T> cls, DateFormatSettings dateFormatSettings) {
+        super(cls, dateFormatSettings);
     }
 
-    protected SimpleDateFormat newSimpleDateFormatUsingDatePattern() {
-        return new SimpleDateFormat(datePattern);
+    protected SimpleDateFormat getDateOnlyFormat() {
+        if(dateOnlyPattern==null) {
+            dateOnlyPattern = new SimpleDateFormat(dateFormatSettings.getDatePattern()); 
+        }
+        return dateOnlyPattern;
     }
 
-    protected SimpleDateFormat newSimpleDateFormatUsingDateTimePattern() {
-        return new SimpleDateFormat(dateTimePattern);
+    protected SimpleDateFormat getDateTimeFormat() {
+        if(dateTimePattern==null) {
+            dateTimePattern = new SimpleDateFormat(dateFormatSettings.getDateTimePattern()); 
+        }
+        return dateTimePattern;
     }
 
+    protected <X extends java.util.Date> T adjustDaysForward(X value) {
+        final int days = dateFormatSettings.getAdjustBy();
+        if(days==0) {
+            return temporalValueOf(value);
+        }
+        return temporalValueOf(addDaysTo(value, days));
+    }
+    
+    protected <X extends java.util.Date> T adjustDaysBackward(X value) {
+        final int days = dateFormatSettings.getAdjustBy();
+        if(days==0) {
+            return temporalValueOf(value);
+        }
+        return temporalValueOf(addDaysTo(value, -days));
+    }    
+    
+    protected T parseDateTime(String valueStr) {
+        try {
+            java.util.Date parsed = getDateTimeFormat().parse(valueStr);
+            return temporalValueOf(parsed);
+        } catch (ParseException ex) {
+            try {
+                java.util.Date parsed = getDateOnlyFormat().parse(valueStr);
+                return temporalValueOf(parsed);
+            } catch (ParseException ex2) {
+                throw new ConversionException("Value cannot be converted as a date/time", ex);
+            }
+        }
+    }
+    
+    protected T parseDateOnly(String valueStr) {
+        try {
+            java.util.Date parsed =  getDateOnlyFormat().parse(valueStr);
+            return temporalValueOf(parsed);
+        } catch (ParseException e) {
+            throw new ConversionException("Cannot convert into a date", e);
+        }
+    }
+    
+    protected abstract T temporalValueOf(java.util.Date date);
+    
+    // -- HELPER
+    
+    private final <X extends java.util.Date> T addDaysTo(X value, final int days) {
+        final Calendar cal = Calendar.getInstance();
+        cal.setTime(value);
+        cal.add(Calendar.DATE, days);
+        final java.util.Date adjusted = cal.getTime();
+        return temporalValueOf(adjusted);
+    }
 
 }
\ No newline at end of file
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/DateConverterForJavaSqlDate.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/DateConverterForJavaSqlDate.java
index 5b9e0ec..1217515 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/DateConverterForJavaSqlDate.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/DateConverterForJavaSqlDate.java
@@ -18,54 +18,47 @@
  */
 package org.apache.isis.viewer.wicket.ui.components.scalars.jdkdates;
 
-import java.text.ParseException;
-import java.util.Calendar;
-import java.util.Date;
 import java.util.Locale;
 
 import org.apache.wicket.util.convert.ConversionException;
 
 import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
+import org.apache.isis.viewer.wicket.ui.components.scalars.DateFormatSettings;
 
 
 public class DateConverterForJavaSqlDate extends DateConverterForJavaAbstract<java.sql.Date> {
     private static final long serialVersionUID = 1L;
 
     public DateConverterForJavaSqlDate(WicketViewerSettings settings, int adjustBy) {
-        this(settings.getDatePattern(), settings.getDatePattern(), adjustBy);
+        this(DateFormatSettings.ofDateOnly(settings, adjustBy));
     }
 
-    private DateConverterForJavaSqlDate(String datePattern, String datePickerPattern, int adjustBy) {
-        super(java.sql.Date.class, datePattern, datePattern, datePickerPattern, adjustBy);
+    private DateConverterForJavaSqlDate(DateFormatSettings dateFormatSettings) {
+        super(java.sql.Date.class, dateFormatSettings);
     }
 
     @Override
     protected java.sql.Date doConvertToObject(String value, Locale locale) throws ConversionException {
-        final Date date = convert(value);
-        final java.util.Date adjustedDate = addDays(date, 0-adjustBy);
-        return new java.sql.Date(adjustedDate.getTime());
-    }
-
-    private java.util.Date convert(String value) {
-        try {
-            return newSimpleDateFormatUsingDatePattern().parse(value);
-        } catch (ParseException e) {
-            throw new ConversionException("Cannot convert into a date", e);
-        }
+        
+        System.out.println("!!! toObject: "+value+" -> "+parseDateOnly(value)+" -> "+adjustDaysBackward(parseDateOnly(value)));
+        
+        final java.sql.Date date = parseDateOnly(value);
+        final java.sql.Date adjustedDate = adjustDaysBackward(date);
+        return adjustedDate;
     }
 
     @Override
     protected String doConvertToString(java.sql.Date value, Locale locale) {
-        return newSimpleDateFormatUsingDatePattern().format(addDays(value, adjustBy));
+        
+        final java.sql.Date adjustedDate = adjustDaysForward(value);
+        System.out.println("!!! toString: "+value+" -> "+adjustedDate+" -> "+getDateOnlyFormat().format(adjustedDate));
+        
+        return getDateOnlyFormat().format(adjustedDate);
     }
 
-    private static Date addDays(java.util.Date value, final int days) {
-        final Calendar cal = Calendar.getInstance();
-        cal.setTime(value);
-        cal.add(Calendar.DATE, days);
-        final Date adjusted = cal.getTime();
-        return adjusted;
+    @Override
+    protected java.sql.Date temporalValueOf(java.util.Date date) {
+        return new java.sql.Date(date.getTime());
     }
 
-
 }
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/DateConverterForJavaSqlTimestamp.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/DateConverterForJavaSqlTimestamp.java
index 717c94e..eb485c8 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/DateConverterForJavaSqlTimestamp.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/DateConverterForJavaSqlTimestamp.java
@@ -18,58 +18,43 @@
  */
 package org.apache.isis.viewer.wicket.ui.components.scalars.jdkdates;
 
-import java.text.ParseException;
-import java.util.Calendar;
+import java.sql.Timestamp;
 import java.util.Date;
 import java.util.Locale;
 
 import org.apache.wicket.util.convert.ConversionException;
 
 import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
+import org.apache.isis.viewer.wicket.ui.components.scalars.DateFormatSettings;
 
 
 public class DateConverterForJavaSqlTimestamp extends DateConverterForJavaAbstract<java.sql.Timestamp> {
     private static final long serialVersionUID = 1L;
 
     public DateConverterForJavaSqlTimestamp(WicketViewerSettings settings, int adjustBy) {
-        this(settings.getDatePattern(), settings.getTimestampPattern(), adjustBy);
+        this(DateFormatSettings.ofDateAndTime(settings, adjustBy));
     }
-    public DateConverterForJavaSqlTimestamp(final String datePattern, String timestampPattern, int adjustBy) {
-        super(java.sql.Timestamp.class, datePattern, timestampPattern, timestampPattern, adjustBy);
+
+    private DateConverterForJavaSqlTimestamp(DateFormatSettings dateFormatSettings) {
+        super(java.sql.Timestamp.class, dateFormatSettings);
     }
 
     @Override
     protected java.sql.Timestamp doConvertToObject(String value, Locale locale) throws ConversionException {
-        final java.sql.Timestamp date = convert(value);
-        final java.sql.Timestamp adjustedDate = addDays(date, 0-adjustBy);
+        final java.sql.Timestamp date = parseDateTime(value);
+        final java.sql.Timestamp adjustedDate = adjustDaysBackward(date);
         return adjustedDate;
     }
 
-    private java.sql.Timestamp convert(String valueStr) {
-        try {
-            Date parsed = newSimpleDateFormatUsingDateTimePattern().parse(valueStr);
-            return new java.sql.Timestamp(parsed.getTime());
-        } catch (ParseException ex) {
-            try {
-                return new java.sql.Timestamp(newSimpleDateFormatUsingDatePattern().parse(valueStr).getTime());
-            } catch (ParseException ex2) {
-                throw new ConversionException("Value cannot be converted as a date/time", ex);
-            }
-        }
-    }
-
     @Override
     protected String doConvertToString(java.sql.Timestamp value, Locale locale) throws ConversionException {
-        final java.sql.Timestamp adjustedDate = addDays(value, adjustBy);
-        return newSimpleDateFormatUsingDateTimePattern().format(adjustedDate);
+        final java.sql.Timestamp adjustedDate = adjustDaysForward(value);
+        return getDateTimeFormat().format(adjustedDate);
     }
 
-    private static java.sql.Timestamp addDays(java.util.Date value, final int days) {
-        final Calendar cal = Calendar.getInstance();
-        cal.setTime(value);
-        cal.add(Calendar.DATE, days);
-        final java.sql.Timestamp adjusted = new java.sql.Timestamp(cal.getTime().getTime());
-        return adjusted;
+    @Override
+    protected Timestamp temporalValueOf(Date date) {
+        return new java.sql.Timestamp(date.getTime());
     }
 
 }
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/DateConverterForJavaUtilDate.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/DateConverterForJavaUtilDate.java
index bebf54f..6a633bb 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/DateConverterForJavaUtilDate.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/DateConverterForJavaUtilDate.java
@@ -18,57 +18,42 @@
  */
 package org.apache.isis.viewer.wicket.ui.components.scalars.jdkdates;
 
-import java.text.ParseException;
-import java.util.Calendar;
 import java.util.Date;
 import java.util.Locale;
 
 import org.apache.wicket.util.convert.ConversionException;
 
 import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
+import org.apache.isis.viewer.wicket.ui.components.scalars.DateFormatSettings;
 
 
 public class DateConverterForJavaUtilDate extends DateConverterForJavaAbstract<java.util.Date> {
     private static final long serialVersionUID = 1L;
 
     public DateConverterForJavaUtilDate(WicketViewerSettings settings, int adjustBy) {
-        this(settings.getDatePattern(), settings.getDateTimePattern(), settings.getDateTimePattern(), adjustBy);
-    }
-    public DateConverterForJavaUtilDate(String datePattern, String dateTimePattern, String datePickerPattern, int adjustBy) {
-        super(java.util.Date.class, datePattern, dateTimePattern, datePickerPattern, adjustBy);
+        this(DateFormatSettings.ofDateAndTime(settings, adjustBy));
     }
 
+    private DateConverterForJavaUtilDate(DateFormatSettings dateFormatSettings) {
+        super(java.util.Date.class, dateFormatSettings);
+    }
 
     @Override
     protected java.util.Date doConvertToObject(String value, Locale locale) throws ConversionException {
-        final Date date = convert(value);
-        final Date adjustedDate = addDays(date, 0-adjustBy);
+        final Date date = parseDateTime(value);
+        final Date adjustedDate = adjustDaysBackward(date);
         return adjustedDate;
     }
-    private java.util.Date convert(String valueStr) {
-        try {
-            return newSimpleDateFormatUsingDateTimePattern().parse(valueStr);
-        } catch (ParseException ex) {
-            try {
-                return newSimpleDateFormatUsingDatePattern().parse(valueStr);
-            } catch (ParseException ex2) {
-                throw new ConversionException("Value cannot be converted as a date/time", ex);
-            }
-        }
-    }
 
     @Override
     protected String doConvertToString(java.util.Date value, Locale locale) throws ConversionException {
-        final Date adjustedDate = addDays(value, adjustBy);
-        return newSimpleDateFormatUsingDateTimePattern().format(adjustedDate);
+        final Date adjustedDate = adjustDaysForward(value);
+        return getDateTimeFormat().format(adjustedDate);
     }
 
-    private static Date addDays(java.util.Date value, final int days) {
-        final Calendar cal = Calendar.getInstance();
-        cal.setTime(value);
-        cal.add(Calendar.DATE, days);
-        final Date adjusted = cal.getTime();
-        return adjusted;
+    @Override
+    protected Date temporalValueOf(Date date) {
+        return date; //[ahuber] immutable, so just returning the same object
     }
 
 }
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/JavaSqlDatePanel.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/JavaSqlDatePanel.java
index e8a977a..11787c2 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/JavaSqlDatePanel.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/JavaSqlDatePanel.java
@@ -21,6 +21,7 @@ package org.apache.isis.viewer.wicket.ui.components.scalars.jdkdates;
 
 import java.sql.Date;
 
+import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.viewer.wicket.model.models.ScalarModel;
 import org.apache.isis.viewer.wicket.ui.components.scalars.ScalarPanelTextFieldDatePickerAbstract;
 
@@ -33,6 +34,11 @@ public class JavaSqlDatePanel extends ScalarPanelTextFieldDatePickerAbstract<jav
 
     public JavaSqlDatePanel(final String id, final ScalarModel scalarModel) {
         super(id, scalarModel, java.sql.Date.class);
+        
+        System.out.println("!!! JavaSqlDatePanel ("+scalarModel.getClass()+"): "+scalarModel.getObjectAsString());
+        
+        _Exceptions.dumpStackTrace(System.out, 0, 10);
+        
         init(new DateConverterForJavaSqlDate(getSettings(), getAdjustBy()));
     }
 
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/JavaUtilDatePanel.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/JavaUtilDatePanel.java
index e430835..cec292e 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/JavaUtilDatePanel.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdkdates/JavaUtilDatePanel.java
@@ -35,6 +35,11 @@ public class JavaUtilDatePanel extends ScalarPanelTextFieldDatePickerAbstract<ja
         super(id, scalarModel, java.util.Date.class);
         init(new DateConverterForJavaUtilDate(getSettings(), getAdjustBy()));
     }
+    
+    @Override
+    protected Integer getLengthAdjustHint() {
+        return +3;
+    }
 
     @Override
     protected String getScalarPanelType() {
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/DateConverterForJodaAbstract.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/DateConverterForJodaAbstract.java
index b3cf907..998e52a 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/DateConverterForJodaAbstract.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/DateConverterForJodaAbstract.java
@@ -18,35 +18,32 @@
  */
 package org.apache.isis.viewer.wicket.ui.components.scalars.jodatime;
 
+import java.util.Locale;
+
 import org.apache.wicket.util.convert.ConversionException;
-import org.joda.time.DateTime;
-import org.joda.time.LocalDate;
-import org.joda.time.LocalDateTime;
-import org.joda.time.format.DateTimeFormat;
 import org.joda.time.format.DateTimeFormatter;
 
 import org.apache.isis.viewer.wicket.ui.components.scalars.DateConverterAbstract;
-
-import java.util.Locale;
+import org.apache.isis.viewer.wicket.ui.components.scalars.DateFormatSettings;
 
 abstract class DateConverterForJodaAbstract<T> extends DateConverterAbstract<T> {
 
     private static final long serialVersionUID = 1L;
 
-    DateConverterForJodaAbstract(Class<T> cls, String datePattern, String dateTimePattern, int adjustBy) {
-        super(cls, datePattern, dateTimePattern, adjustBy);
+    DateConverterForJodaAbstract(Class<T> cls, DateFormatSettings dateFormatSettings) {
+        super(cls, dateFormatSettings);
     }
 
     @Override
     protected final T doConvertToObject(String value, Locale locale) {
         T dateTime = convert(value);
-        return minusDays(dateTime, adjustBy);
+        return minusDays(dateTime, dateFormatSettings.getAdjustBy());
     }
 
     @Override
     protected String doConvertToString(T value, Locale locale) {
         // for JodaLocalDate, the date time pattern is same as date pattern, so can use either to convert to string.
-        T t = plusDays(value, adjustBy);
+        T t = plusDays(value, dateFormatSettings.getAdjustBy());
         return toString(t, getFormatterForDateTimePattern());
     }
 
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/DateConverterForJodaDateTime.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/DateConverterForJodaDateTime.java
index c65f6bc..621e0ef 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/DateConverterForJodaDateTime.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/DateConverterForJodaDateTime.java
@@ -18,21 +18,19 @@
  */
 package org.apache.isis.viewer.wicket.ui.components.scalars.jodatime;
 
-import java.util.Locale;
-
 import org.apache.wicket.util.convert.ConversionException;
 import org.joda.time.DateTime;
+import org.joda.time.format.DateTimeFormatter;
 
 import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
-import org.joda.time.LocalDate;
-import org.joda.time.format.DateTimeFormatter;
+import org.apache.isis.viewer.wicket.ui.components.scalars.DateFormatSettings;
 
 public class DateConverterForJodaDateTime extends DateConverterForJodaAbstract<DateTime> {
 
     private static final long serialVersionUID = 1L;
 
     public DateConverterForJodaDateTime(WicketViewerSettings settings, int adjustBy) {
-        super(DateTime.class, settings.getDatePattern(), settings.getDateTimePattern(), adjustBy);
+        super(DateTime.class, DateFormatSettings.ofDateAndTime(settings, adjustBy));
     }
 
     @Override
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/DateConverterForJodaLocalDate.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/DateConverterForJodaLocalDate.java
index 9feb34a..8402468 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/DateConverterForJodaLocalDate.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/DateConverterForJodaLocalDate.java
@@ -18,13 +18,12 @@
  */
 package org.apache.isis.viewer.wicket.ui.components.scalars.jodatime;
 
-import java.util.Locale;
-
 import org.apache.wicket.util.convert.ConversionException;
 import org.joda.time.LocalDate;
+import org.joda.time.format.DateTimeFormatter;
 
 import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
-import org.joda.time.format.DateTimeFormatter;
+import org.apache.isis.viewer.wicket.ui.components.scalars.DateFormatSettings;
 
 /**
  * Uses the same pattern for both date and date/time.  The only real consequence of this is that when converting a
@@ -35,7 +34,7 @@ public class DateConverterForJodaLocalDate extends DateConverterForJodaAbstract<
     private static final long serialVersionUID = 1L;
 
     public DateConverterForJodaLocalDate(WicketViewerSettings settings, int adjustBy) {
-        super(LocalDate.class, settings.getDatePattern(), settings.getDatePattern(), adjustBy);
+        super(LocalDate.class, DateFormatSettings.ofDateOnly(settings, adjustBy));
     }
 
     @Override
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/DateConverterForJodaLocalDateTime.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/DateConverterForJodaLocalDateTime.java
index aaeb11e..a366847 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/DateConverterForJodaLocalDateTime.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/DateConverterForJodaLocalDateTime.java
@@ -18,24 +18,21 @@
  */
 package org.apache.isis.viewer.wicket.ui.components.scalars.jodatime;
 
-import java.util.Locale;
-
 import org.apache.wicket.util.convert.ConversionException;
-import org.joda.time.LocalDate;
 import org.joda.time.LocalDateTime;
+import org.joda.time.format.DateTimeFormatter;
 
 import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
-import org.joda.time.format.DateTimeFormatter;
+import org.apache.isis.viewer.wicket.ui.components.scalars.DateFormatSettings;
 
 public class DateConverterForJodaLocalDateTime extends DateConverterForJodaAbstract<LocalDateTime> {
 
     private static final long serialVersionUID = 1L;
 
     public DateConverterForJodaLocalDateTime(WicketViewerSettings settings, int adjustBy) {
-        super(LocalDateTime.class, settings.getDatePattern(), settings.getDateTimePattern(), adjustBy);
+        super(LocalDateTime.class, DateFormatSettings.ofDateAndTime(settings, adjustBy));
     }
 
-
     @Override
     protected LocalDateTime minusDays(LocalDateTime value, int adjustBy) {
         return value.minusDays(adjustBy);