You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2018/01/05 09:49:22 UTC

[isis] 01/04: ISIS-1636 UI enhancement - java 8 Time

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

danhaywood pushed a commit to branch ISIS-1740-where-am-i
in repository https://gitbox.apache.org/repos/asf/isis.git

commit 18562c46c8ab91cac592db86fe7298dde59d082d
Author: Andi Huber <ah...@apache.org>
AuthorDate: Fri Oct 6 22:49:37 2017 +0200

    ISIS-1636 UI enhancement - java 8 Time
---
 .../value/datejdk8local/Jdk8LocalDateUtil.java     | 169 +++++++++++++
 .../datejdk8local/Jdk8LocalDateValueFacet.java     |  33 +++
 ...ateValueFacetUsingSemanticsProviderFactory.java |  45 ++++
 .../Jdk8LocalDateValueSemanticsProvider.java       | 274 ++++++++++++++++++++
 .../facets/value/datejdk8local/TimeFormatter.java  |  27 ++
 .../facets/value/datejdk8local/TimeParser.java     |  27 ++
 .../datetimejdk8local/Jdk8LocalDateTimeUtil.java   | 157 ++++++++++++
 .../Jdk8LocalDateTimeValueFacet.java               |  33 +++
 ...imeValueFacetUsingSemanticsProviderFactory.java |  45 ++++
 .../Jdk8LocalDateTimeValueSemanticsProvider.java   | 275 +++++++++++++++++++++
 .../value/datetimejdk8local/TimeFormatter.java     |  27 ++
 .../facets/value/datetimejdk8local/TimeParser.java |  27 ++
 .../Jdk8OffsetDateTimeValueFacet.java              |  33 +++
 ...imeValueFacetUsingSemanticsProviderFactory.java |  45 ++++
 .../Jdk8OffsetDateTimeValueSemanticsProvider.java  | 104 ++++++++
 ...fsetDateTimeValueSemanticsProviderAbstract.java | 120 +++++++++
 .../dflt/ProgrammingModelFacetsJava5.java          |  10 +-
 .../ComponentFactoryRegistrarDefault.java          |   7 +
 .../jdk8time/DateConverterForJdk8Abstract.java     |  62 +++++
 .../jdk8time/DateConverterForJdk8LocalDate.java    |  64 +++++
 .../DateConverterForJdk8LocalDateTime.java         |  76 ++++++
 .../DateConverterForJdk8OffsetDateTime.java        |  92 +++++++
 .../scalars/jdk8time/Jdk8LocalDatePanel.java       |  42 ++++
 .../jdk8time/Jdk8LocalDatePanelFactory.java        |  47 ++++
 .../scalars/jdk8time/Jdk8LocalDateTimePanel.java   |  52 ++++
 .../jdk8time/Jdk8LocalDateTimePanelFactory.java    |  45 ++++
 .../scalars/jdk8time/Jdk8OffsetDateTimePanel.java  |  51 ++++
 .../jdk8time/Jdk8OffsetDateTimePanelFactory.java   |  45 ++++
 .../DateConverterForJdk8LocalDateTest.java         |  75 ++++++
 .../DateConverterForJdk8LocalDateTimeTest.java     |  97 ++++++++
 .../DateConverterForJdk8OffsetDateTimeTest.java    | 107 ++++++++
 31 files changed, 2311 insertions(+), 2 deletions(-)

diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datejdk8local/Jdk8LocalDateUtil.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datejdk8local/Jdk8LocalDateUtil.java
new file mode 100644
index 0000000..bff3e30
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datejdk8local/Jdk8LocalDateUtil.java
@@ -0,0 +1,169 @@
+/*
+ *  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.core.metamodel.facets.value.datejdk8local;
+
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.List;
+import java.util.Locale;
+import java.util.StringTokenizer;
+
+import org.apache.isis.core.metamodel.facets.object.parseable.TextEntryParseException;
+import org.joda.time.format.DateTimeFormat;
+
+final class Jdk8LocalDateUtil  {
+
+	private Jdk8LocalDateUtil(){}
+
+	// -- CONVERSION (LEGACY OF JODA TIME LIBRARY)
+	
+	static TimeParser parserOfStyle(String style) {
+		return parserOf(DateTimeFormat.forStyle(style));
+	}
+
+	private static TimeParser parserOf(org.joda.time.format.DateTimeFormatter jodaFormatter) {
+		return t->
+		toJava8(jodaFormatter.withLocale(Locale.getDefault()).parseLocalDate(t));
+	}
+
+	private static LocalDate toJava8(org.joda.time.LocalDate x) {
+		return LocalDate.of(x.getYear(), x.getMonthOfYear(), x.getDayOfMonth());
+	}
+
+	static TimeFormatter formatterOfStyle(String style) {
+		return formatterOf(DateTimeFormat.forStyle(style));
+	}
+
+	private static TimeFormatter formatterOf(org.joda.time.format.DateTimeFormatter jodaFormatter) {
+		return t->
+		jodaFormatter.withLocale(Locale.getDefault()).print(toJoda(t));
+	}
+
+	private static org.joda.time.LocalDate toJoda(LocalDate x) {
+		return new org.joda.time.LocalDate(x.getYear(), x.getMonthValue(), x.getDayOfMonth());
+	}
+	
+	// -- PARSING AND FORMATING GENERALIZATION 
+
+	static TimeFormatter formatterOf(DateTimeFormatter formatter) {
+		return t->
+		formatter.withLocale(Locale.getDefault()).format(t);
+	}
+
+	static TimeParser parserOf(DateTimeFormatter formatter) {
+		return text->
+		LocalDate.parse(text, formatter.withLocale(Locale.getDefault()));
+	}
+
+	// //////////////////////////////////////
+
+	static LocalDate parseDate(
+			final String dateStr,
+			List<TimeParser> parsers) {
+		LocalDate parsedDate = _parseDate(dateStr, parsers);
+		return parsedDate;
+	}
+
+	private static LocalDate _parseDate(String dateStr, Iterable<TimeParser> parsers) {
+		for(TimeParser parser: parsers) {
+			try {
+				return parser.apply(dateStr);
+			} catch (final IllegalArgumentException e) {
+				// continue to next
+			}
+		}
+		throw new TextEntryParseException("Not recognised as a date: " + dateStr);
+	}
+
+	// //////////////////////////////////////
+
+	static LocalDate relativeDate(final LocalDate contextDate, final String str, final boolean add) {
+		LocalDate relativeDate = contextDate;
+		if (str.equals("")) {
+			return contextDate;
+		}
+
+		try {
+			final StringTokenizer st = new StringTokenizer(str.substring(1), " ");
+			while (st.hasMoreTokens()) {
+				final String token = st.nextToken();
+				relativeDate = adjustDate(relativeDate, token, add);
+			}
+			return relativeDate;
+		} catch (final Exception e) {
+			return contextDate;
+		}
+	}
+
+	private static LocalDate adjustDate(final LocalDate contextDate, String str, final boolean add) {
+		int hours = 0;
+		int minutes = 0;
+		int days = 0;
+		int months = 0;
+		int years = 0;
+
+		if (str.endsWith("H")) {
+			str = str.substring(0, str.length() - 1);
+			hours = Integer.valueOf(str).intValue();
+		} else if (str.endsWith("M")) {
+			str = str.substring(0, str.length() - 1);
+			minutes = Integer.valueOf(str).intValue();
+		} else if (str.endsWith("w")) {
+			str = str.substring(0, str.length() - 1);
+			days = 7 * Integer.valueOf(str).intValue();
+		} else if (str.endsWith("y")) {
+			str = str.substring(0, str.length() - 1);
+			years = Integer.valueOf(str).intValue();
+		} else if (str.endsWith("m")) {
+			str = str.substring(0, str.length() - 1);
+			months = Integer.valueOf(str).intValue();
+		} else if (str.endsWith("d")) {
+			str = str.substring(0, str.length() - 1);
+			days = Integer.valueOf(str).intValue();
+		} else {
+			days = Integer.valueOf(str).intValue();
+		}
+
+		if (add) {
+			return add(contextDate, years, months, days, hours, minutes);
+		} else {
+			return add(contextDate, -years, -months, -days, -hours, -minutes);
+		}
+	}
+
+	private static LocalDate add(final LocalDate original, final int years, final int months, final int days, final int hours, final int minutes) {
+		if(hours != 0 || minutes != 0) {
+			throw new IllegalArgumentException("cannot add non-zero hours or minutes to a LocalDate");
+		}
+		return original.plusYears(years).plusMonths(months).plusDays(days);
+	}
+
+
+	// //////////////////////////////////////
+
+	public static String titleString(final TimeFormatter formatter, final LocalDate date) {
+		return date == null ? "" : formatter.apply(date);
+	}
+
+
+
+
+
+}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datejdk8local/Jdk8LocalDateValueFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datejdk8local/Jdk8LocalDateValueFacet.java
new file mode 100644
index 0000000..4deedc3
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datejdk8local/Jdk8LocalDateValueFacet.java
@@ -0,0 +1,33 @@
+/*
+ *  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.core.metamodel.facets.value.datejdk8local;
+
+import java.time.LocalDate;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.facetapi.Facet;
+
+public interface Jdk8LocalDateValueFacet extends Facet {
+
+    LocalDate dateValue(ObjectAdapter object);
+
+    ObjectAdapter createValue(LocalDate date);
+
+}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datejdk8local/Jdk8LocalDateValueFacetUsingSemanticsProviderFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datejdk8local/Jdk8LocalDateValueFacetUsingSemanticsProviderFactory.java
new file mode 100644
index 0000000..65aa714
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datejdk8local/Jdk8LocalDateValueFacetUsingSemanticsProviderFactory.java
@@ -0,0 +1,45 @@
+/*
+ *  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.core.metamodel.facets.value.datejdk8local;
+
+import java.time.LocalDate;
+
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.object.value.vsp.ValueFacetUsingSemanticsProviderFactory;
+
+public class Jdk8LocalDateValueFacetUsingSemanticsProviderFactory extends ValueFacetUsingSemanticsProviderFactory<LocalDate> {
+
+    public Jdk8LocalDateValueFacetUsingSemanticsProviderFactory() {
+     // as per inherited DateTimeValueSemanticsProvider#facetType
+        super(); 
+    }
+
+    @Override
+    public void process(final ProcessClassContext processClassContext) {
+        final Class<?> type = processClassContext.getCls();
+        final FacetHolder holder = processClassContext.getFacetHolder();
+
+        if (type != LocalDate.class) {
+            return;
+        }
+        addFacets(new Jdk8LocalDateValueSemanticsProvider(holder, getContext()));
+    }
+
+}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datejdk8local/Jdk8LocalDateValueSemanticsProvider.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datejdk8local/Jdk8LocalDateValueSemanticsProvider.java
new file mode 100644
index 0000000..a1e1e21
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datejdk8local/Jdk8LocalDateValueSemanticsProvider.java
@@ -0,0 +1,274 @@
+/*
+ *  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.core.metamodel.facets.value.datejdk8local;
+
+import static org.apache.isis.core.metamodel.facets.value.datejdk8local.Jdk8LocalDateUtil.formatterOf;
+import static org.apache.isis.core.metamodel.facets.value.datejdk8local.Jdk8LocalDateUtil.formatterOfStyle;
+import static org.apache.isis.core.metamodel.facets.value.datejdk8local.Jdk8LocalDateUtil.parserOf;
+import static org.apache.isis.core.metamodel.facets.value.datejdk8local.Jdk8LocalDateUtil.parserOfStyle;
+
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.isis.applib.adapters.EncoderDecoder;
+import org.apache.isis.applib.adapters.EncodingException;
+import org.apache.isis.core.commons.config.ConfigurationConstants;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.object.value.vsp.ValueSemanticsProviderAndFacetAbstract;
+import org.apache.isis.core.metamodel.facets.value.datejodalocal.JodaLocalDateValueFacet;
+import org.apache.isis.core.metamodel.services.ServicesInjector;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+public class Jdk8LocalDateValueSemanticsProvider extends ValueSemanticsProviderAndFacetAbstract<LocalDate> implements Jdk8LocalDateValueFacet {
+
+    public static final int MAX_LENGTH = 12;
+    public static final int TYPICAL_LENGTH = MAX_LENGTH;
+
+    /**
+     * Introduced to allow BDD tests to provide a different format string "mid-flight".
+     * 
+     * <p>
+     * REVIEW: This seems only to have any effect if 'propertyType' is set to 'date'.
+     * 
+     * @see #setTitlePatternOverride(String)
+     * @deprecated - because 'propertyType' parameter is never used
+     */
+    @Deprecated
+    public static void setFormat(final String propertyType, final String pattern) {
+        setTitlePatternOverride(pattern);
+    }
+    /**
+     * A replacement for {@link #setFormat(String, String)}.
+     */
+    public static void setTitlePatternOverride(final String pattern) {
+        OVERRIDE_TITLE_PATTERN.set(pattern);
+    }
+    
+    /**
+     * Key to indicate how LocalDate should be parsed/rendered.
+     * 
+     * <p>
+     * eg:
+     * <pre>
+     * isis.value.format.date=iso
+     * </pre>
+     * 
+     * <p>
+     * A pre-determined list of values is available, specifically 'iso_encoding', 'iso' and 'medium' (see 
+     * {@link #NAMED_TITLE_FORMATTERS}).  Alternatively,  can also specify a mask, eg <tt>dd-MMM-yyyy</tt>.
+     * 
+     * @see #NAMED_TITLE_FORMATTERS  
+     */
+    public final static String CFG_FORMAT_KEY = ConfigurationConstants.ROOT + "value.format.date";
+    
+    
+    /**
+     * Keys represent the values which can be configured, and which are used for the rendering of dates.
+     * 
+     */
+    private static Map<String, TimeFormatter> NAMED_TITLE_FORMATTERS = Maps.newHashMap();
+    static {
+        NAMED_TITLE_FORMATTERS.put("iso_encoding", formatterOf(DateTimeFormatter.ofPattern("yyyyMMdd")));
+        NAMED_TITLE_FORMATTERS.put("iso", formatterOf(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
+        NAMED_TITLE_FORMATTERS.put("long", formatterOfStyle("L-"));
+        NAMED_TITLE_FORMATTERS.put("medium", formatterOfStyle("M-"));
+        NAMED_TITLE_FORMATTERS.put("short", formatterOfStyle("S-"));
+    }
+    
+    private final static ThreadLocal<String> OVERRIDE_TITLE_PATTERN = new ThreadLocal<String>() {
+        @Override
+        protected String initialValue() {
+            return null;
+        }
+    };
+
+    
+    private final static List<TimeParser> PARSE_FORMATTERS = Lists.newArrayList();
+    static {
+        PARSE_FORMATTERS.add(parserOfStyle("L-"));
+        PARSE_FORMATTERS.add(parserOfStyle("M-"));
+        PARSE_FORMATTERS.add(parserOfStyle("S-"));
+        PARSE_FORMATTERS.add(parserOf(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
+        PARSE_FORMATTERS.add(parserOf(DateTimeFormatter.ofPattern("yyyyMMdd")));
+    }
+
+    public static Class<? extends Facet> type() {
+        return JodaLocalDateValueFacet.class;
+    }
+
+
+    // no default
+    private static final LocalDate DEFAULT_VALUE = null;
+
+
+    private final DateTimeFormatter encodingFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
+    
+    private TimeFormatter titleStringFormatter;
+    private String titleStringFormatNameOrPattern;
+
+    
+    // //////////////////////////////////////
+    // constructor
+    // //////////////////////////////////////
+
+    /**
+     * Required because implementation of {@link TimeParser} and
+     * {@link EncoderDecoder}.
+     */
+    public Jdk8LocalDateValueSemanticsProvider() {
+        this(null, null);
+    }
+
+    /**
+     * Uses {@link #type()} as the facet type.
+     */
+    public Jdk8LocalDateValueSemanticsProvider(final FacetHolder holder, final ServicesInjector context) {
+        super(type(), holder, LocalDate.class, TYPICAL_LENGTH, MAX_LENGTH, Immutability.IMMUTABLE, EqualByContent.HONOURED, DEFAULT_VALUE, context);
+
+        String configuredNameOrPattern = getConfiguration().getString(CFG_FORMAT_KEY, "medium").trim();
+        updateTitleStringFormatter(configuredNameOrPattern);
+    }
+
+
+    private void updateTitleStringFormatter(String titleStringFormatNameOrPattern) {
+        titleStringFormatter = NAMED_TITLE_FORMATTERS.get(titleStringFormatNameOrPattern);
+        if (titleStringFormatter == null) {
+            titleStringFormatter = formatterOf(DateTimeFormatter.ofPattern(titleStringFormatNameOrPattern));
+        }
+        this.titleStringFormatNameOrPattern = titleStringFormatNameOrPattern; 
+    }
+    
+
+    // //////////////////////////////////////////////////////////////////
+    // Parsing
+    // //////////////////////////////////////////////////////////////////
+
+    @Override
+    protected LocalDate doParse(
+            final String entry,
+            final Object context) {
+
+        updateTitleStringFormatterIfOverridden();
+        
+        LocalDate contextDate = (LocalDate) context;
+
+        final String dateString = entry.trim().toUpperCase();
+        if (dateString.startsWith("+") && contextDate != null) {
+            return Jdk8LocalDateUtil.relativeDate(contextDate, dateString, true);
+        } else if (dateString.startsWith("-")  && contextDate != null) {
+            return Jdk8LocalDateUtil.relativeDate(contextDate, dateString, false);
+        } else {
+            return parseDate(dateString, contextDate);
+        }
+    }
+
+    private void updateTitleStringFormatterIfOverridden() {
+        final String overridePattern = OVERRIDE_TITLE_PATTERN.get();
+        if (overridePattern == null || 
+            titleStringFormatNameOrPattern.equals(overridePattern)) {
+            return;
+        } 
+        
+        // (re)create format
+        updateTitleStringFormatter(overridePattern);
+    }
+
+    private LocalDate parseDate(final String dateStr, final Object original) {
+        return Jdk8LocalDateUtil.parseDate(dateStr, PARSE_FORMATTERS);
+    }
+    
+
+    // ///////////////////////////////////////////////////////////////////////////
+    // TitleProvider
+    // ///////////////////////////////////////////////////////////////////////////
+
+    @Override
+    public String titleString(final Object value) {
+        if (value == null) {
+            return null;
+        }
+        final LocalDate date = (LocalDate) value;
+        //DateTimeFormatter f = titleStringFormatter.withLocale(Locale.getDefault());
+        return Jdk8LocalDateUtil.titleString(titleStringFormatter, date);
+    }
+
+    @Override
+    public String titleStringWithMask(final Object value, final String usingMask) {
+        final LocalDate date = (LocalDate) value;
+        return Jdk8LocalDateUtil.titleString(formatterOf(DateTimeFormatter.ofPattern(usingMask)), date);
+    }
+
+
+    // //////////////////////////////////////////////////////////////////
+    // EncoderDecoder
+    // //////////////////////////////////////////////////////////////////
+
+    @Override
+    protected String doEncode(final Object object) {
+        final LocalDate date = (LocalDate) object;
+        return encode(date);
+    }
+
+    private synchronized String encode(final LocalDate date) {
+        return encodingFormatter.format(date);
+    }
+
+    @Override
+    protected LocalDate doRestore(final String data) {
+        try {
+            return parse(data);
+        } catch (final IllegalArgumentException e) {
+            throw new EncodingException(e);
+        }
+    }
+
+    private synchronized LocalDate parse(final String data) {
+        return LocalDate.parse(data, encodingFormatter);
+    }
+
+    // //////////////////////////////////////////////////////////////////
+    // Jdk8LocalDateValueFacet
+    // //////////////////////////////////////////////////////////////////
+
+    @Override
+    public final LocalDate dateValue(final ObjectAdapter object) {
+        return (LocalDate) (object == null ? null : object.getObject());
+    }
+
+    @Override
+    public final ObjectAdapter createValue(final LocalDate date) {
+        return getAdapterManager().adapterFor(date);
+    }
+
+
+    // //////////////////////////////////////
+    
+    @Override
+    public String toString() {
+        return "Jdk8LocalDateValueSemanticsProvider: " + titleStringFormatter;
+    }
+
+}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datejdk8local/TimeFormatter.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datejdk8local/TimeFormatter.java
new file mode 100644
index 0000000..0769108
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datejdk8local/TimeFormatter.java
@@ -0,0 +1,27 @@
+/*
+ *  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.core.metamodel.facets.value.datejdk8local;
+
+import java.time.LocalDate;
+import java.util.function.Function;
+
+interface TimeFormatter extends Function<LocalDate, String> {
+
+}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datejdk8local/TimeParser.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datejdk8local/TimeParser.java
new file mode 100644
index 0000000..b8d945a
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datejdk8local/TimeParser.java
@@ -0,0 +1,27 @@
+/*
+ *  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.core.metamodel.facets.value.datejdk8local;
+
+import java.time.LocalDate;
+import java.util.function.Function;
+
+interface TimeParser extends Function<String, LocalDate> {
+
+}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datetimejdk8local/Jdk8LocalDateTimeUtil.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datetimejdk8local/Jdk8LocalDateTimeUtil.java
new file mode 100644
index 0000000..951440c
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datetimejdk8local/Jdk8LocalDateTimeUtil.java
@@ -0,0 +1,157 @@
+/*
+ *  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.core.metamodel.facets.value.datetimejdk8local;
+
+import java.time.Instant;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+import java.util.StringTokenizer;
+
+import org.apache.isis.core.metamodel.facets.object.parseable.TextEntryParseException;
+
+final class Jdk8LocalDateTimeUtil  {
+
+    private Jdk8LocalDateTimeUtil(){}
+    
+    // -- CONVERSION (LEGACY OF JODA TIME LIBRARY)
+    
+    private final static ZoneId zId = ZoneId.systemDefault();
+
+	static TimeParser parserOf(org.joda.time.format.DateTimeFormatter jodaFormatter) {
+		return t->
+			toJava8(jodaFormatter.withLocale(Locale.getDefault()).parseLocalDateTime(t));
+	}
+
+	private static LocalDateTime toJava8(org.joda.time.LocalDateTime x){
+		if(x==null)
+			return null;
+		return toLocalDateTime(x.toDate().getTime());
+	}
+	
+	private static LocalDateTime toLocalDateTime(long epochMilli) { 
+		return LocalDateTime.ofInstant(Instant.ofEpochMilli(epochMilli),zId);
+	}
+
+	static TimeFormatter formatterOf(org.joda.time.format.DateTimeFormatter jodaFormatter) {
+		return t->
+			jodaFormatter.withLocale(Locale.getDefault()).print(toJoda(t));
+		
+	}
+	
+	private static org.joda.time.LocalDateTime toJoda(LocalDateTime x){
+		if(x==null)
+			return null;
+		return org.joda.time.LocalDateTime.fromDateFields(new Date(toEpochMilli(x)));
+	}
+	
+	private static long toEpochMilli(LocalDateTime localDateTime){
+		return localDateTime.atZone(zId).toInstant().toEpochMilli();
+	}
+	
+	// //////////////////////////////////////
+	
+    static LocalDateTime parseDate(
+            final String dateStr,
+            List<TimeParser> parseFormatters) {
+        return parseDateTime(dateStr, parseFormatters);
+    }
+    
+    private static LocalDateTime parseDateTime(String dateStr, Iterable<TimeParser> parsers) {
+        for(TimeParser parser: parsers) {
+            try {
+                return parser.apply(dateStr);
+            } catch (final IllegalArgumentException e) {
+                // continue to next
+            }
+        }
+        throw new TextEntryParseException("Not recognised as a date: " + dateStr);
+    }
+
+    // //////////////////////////////////////
+
+    
+    static LocalDateTime relativeDateTime(final LocalDateTime contextDate, final String str, final boolean add) {
+        LocalDateTime relativeDate = contextDate;
+        if (str.equals("")) {
+            return contextDate;
+        }
+
+        try {
+            final StringTokenizer st = new StringTokenizer(str.substring(1), " ");
+            while (st.hasMoreTokens()) {
+                final String token = st.nextToken();
+                relativeDate = adjustDateTime(relativeDate, token, add);
+            }
+            return relativeDate;
+        } catch (final Exception e) {
+            return contextDate;
+        }
+    }
+
+    private static LocalDateTime adjustDateTime(final LocalDateTime contextDateTime, String str, final boolean add) {
+        int hours = 0;
+        int minutes = 0;
+        int days = 0;
+        int months = 0;
+        int years = 0;
+
+        if (str.endsWith("H")) {
+            str = str.substring(0, str.length() - 1);
+            hours = Integer.valueOf(str).intValue();
+        } else if (str.endsWith("M")) {
+            str = str.substring(0, str.length() - 1);
+            minutes = Integer.valueOf(str).intValue();
+        } else if (str.endsWith("w")) {
+            str = str.substring(0, str.length() - 1);
+            days = 7 * Integer.valueOf(str).intValue();
+        } else if (str.endsWith("y")) {
+            str = str.substring(0, str.length() - 1);
+            years = Integer.valueOf(str).intValue();
+        } else if (str.endsWith("m")) {
+            str = str.substring(0, str.length() - 1);
+            months = Integer.valueOf(str).intValue();
+        } else if (str.endsWith("d")) {
+            str = str.substring(0, str.length() - 1);
+            days = Integer.valueOf(str).intValue();
+        } else {
+            days = Integer.valueOf(str).intValue();
+        }
+
+        if (add) {
+            return add(contextDateTime, years, months, days, hours, minutes);
+        } else {
+            return add(contextDateTime, -years, -months, -days, -hours, -minutes);
+        }
+    }
+
+    private static LocalDateTime add(final LocalDateTime original, final int years, final int months, final int days, final int hours, final int minutes) {
+        return original.plusYears(years).plusMonths(months).plusDays(days).plusHours(hours).plusMinutes(minutes);
+    }
+    
+    // //////////////////////////////////////
+
+	static String titleString(TimeFormatter titleFormatter, LocalDateTime dateTime) {
+		return dateTime == null ? "" : titleFormatter.apply(dateTime);
+	}
+
+}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datetimejdk8local/Jdk8LocalDateTimeValueFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datetimejdk8local/Jdk8LocalDateTimeValueFacet.java
new file mode 100644
index 0000000..4276129
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datetimejdk8local/Jdk8LocalDateTimeValueFacet.java
@@ -0,0 +1,33 @@
+/*
+ *  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.core.metamodel.facets.value.datetimejdk8local;
+
+import java.time.LocalDateTime;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.facetapi.Facet;
+
+public interface Jdk8LocalDateTimeValueFacet extends Facet {
+
+    LocalDateTime dateValue(ObjectAdapter object);
+
+    ObjectAdapter createValue(LocalDateTime date);
+
+}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datetimejdk8local/Jdk8LocalDateTimeValueFacetUsingSemanticsProviderFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datetimejdk8local/Jdk8LocalDateTimeValueFacetUsingSemanticsProviderFactory.java
new file mode 100644
index 0000000..4f17b73
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datetimejdk8local/Jdk8LocalDateTimeValueFacetUsingSemanticsProviderFactory.java
@@ -0,0 +1,45 @@
+/*
+ *  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.core.metamodel.facets.value.datetimejdk8local;
+
+import java.time.LocalDateTime;
+
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.object.value.vsp.ValueFacetUsingSemanticsProviderFactory;
+
+public class Jdk8LocalDateTimeValueFacetUsingSemanticsProviderFactory extends ValueFacetUsingSemanticsProviderFactory<LocalDateTime> {
+
+    public Jdk8LocalDateTimeValueFacetUsingSemanticsProviderFactory() {
+     // as per inherited DateTimeValueSemanticsProvider#facetType
+        super(); 
+    }
+
+    @Override
+    public void process(final ProcessClassContext processClassContext) {
+        final Class<?> type = processClassContext.getCls();
+        final FacetHolder holder = processClassContext.getFacetHolder();
+
+        if (type != LocalDateTime.class) {
+            return;
+        }
+        addFacets(new Jdk8LocalDateTimeValueSemanticsProvider(holder, getContext()));
+    }
+
+}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datetimejdk8local/Jdk8LocalDateTimeValueSemanticsProvider.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datetimejdk8local/Jdk8LocalDateTimeValueSemanticsProvider.java
new file mode 100644
index 0000000..fd04f37
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datetimejdk8local/Jdk8LocalDateTimeValueSemanticsProvider.java
@@ -0,0 +1,275 @@
+/*
+ *  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.core.metamodel.facets.value.datetimejdk8local;
+
+import static org.apache.isis.core.metamodel.facets.value.datetimejdk8local.Jdk8LocalDateTimeUtil.formatterOf;
+import static org.apache.isis.core.metamodel.facets.value.datetimejdk8local.Jdk8LocalDateTimeUtil.parserOf;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.isis.applib.adapters.EncoderDecoder;
+import org.apache.isis.applib.adapters.EncodingException;
+import org.apache.isis.core.commons.config.ConfigurationConstants;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.facetapi.Facet;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.object.value.vsp.ValueSemanticsProviderAndFacetAbstract;
+import org.apache.isis.core.metamodel.services.ServicesInjector;
+import org.joda.time.format.DateTimeFormat;
+import org.joda.time.format.ISODateTimeFormat;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+
+public class Jdk8LocalDateTimeValueSemanticsProvider extends ValueSemanticsProviderAndFacetAbstract<LocalDateTime> implements Jdk8LocalDateTimeValueFacet {
+
+    public static final int MAX_LENGTH = 36;
+    public static final int TYPICAL_LENGTH = 22;
+
+    /**
+     * Introduced to allow BDD tests to provide a different format string "mid-flight".
+     * 
+     * <p>
+     * REVIEW: This seems only to have any effect if 'propertyType' is set to 'date'.
+     * 
+     * @see #setTitlePatternOverride(String)
+     * @deprecated - because 'propertyType' parameter is never used
+     */
+    @Deprecated
+    public static void setFormat(final String propertyType, final String pattern) {
+        setTitlePatternOverride(pattern);
+    }
+    /**
+     * A replacement for {@link #setFormat(String, String)}.
+     */
+    public static void setTitlePatternOverride(final String pattern) {
+        OVERRIDE_TITLE_PATTERN.set(pattern);
+    }
+    
+    /**
+     * Key to indicate how LocalDateTime should be parsed/rendered.
+     * 
+     * <p>
+     * eg:
+     * <pre>
+     * isis.value.format.datetime=iso
+     * </pre>
+     * 
+     * <p>
+     * A pre-determined list of values is available, specifically 'iso_encoding', 'iso' and 'medium' (see 
+     * {@link #NAMED_TITLE_FORMATTERS}).  Alternatively,  can also specify a mask, eg <tt>dd-MMM-yyyy</tt>.
+     * 
+     * @see #NAMED_TITLE_FORMATTERS  
+     */
+    public final static String CFG_FORMAT_KEY = ConfigurationConstants.ROOT + "value.format.datetime";
+    
+    
+    /**
+     * Keys represent the values which can be configured, and which are used for the rendering of dates.
+     * 
+     */
+    private static Map<String, TimeFormatter> NAMED_TITLE_FORMATTERS = Maps.newHashMap();
+    static {
+        NAMED_TITLE_FORMATTERS.put("iso_encoding", formatterOf(ISODateTimeFormat.basicDateTime()));
+        NAMED_TITLE_FORMATTERS.put("iso", formatterOf(ISODateTimeFormat.basicDateTimeNoMillis()));
+        NAMED_TITLE_FORMATTERS.put("long", formatterOf(DateTimeFormat.forStyle("LL")));
+        NAMED_TITLE_FORMATTERS.put("medium", formatterOf(DateTimeFormat.forStyle("MM")));
+        NAMED_TITLE_FORMATTERS.put("short", formatterOf(DateTimeFormat.forStyle("SS")));
+    }
+    
+    private final static ThreadLocal<String> OVERRIDE_TITLE_PATTERN = new ThreadLocal<String>() {
+        @Override
+        protected String initialValue() {
+            return null;
+        }
+    };
+
+    
+    private final static List<TimeParser> PARSE_FORMATTERS = Lists.newArrayList();
+    static {
+        PARSE_FORMATTERS.add(parserOf(DateTimeFormat.forStyle("LL")));
+        PARSE_FORMATTERS.add(parserOf(DateTimeFormat.forStyle("MM")));
+        PARSE_FORMATTERS.add(parserOf(DateTimeFormat.forStyle("SS")));
+        PARSE_FORMATTERS.add(parserOf(ISODateTimeFormat.basicDateTimeNoMillis()));
+        PARSE_FORMATTERS.add(parserOf(ISODateTimeFormat.basicDateTime()));
+    }
+
+    public static Class<? extends Facet> type() {
+        return Jdk8LocalDateTimeValueFacet.class;
+    }
+
+	// no default
+    private static final LocalDateTime DEFAULT_VALUE = null;
+
+    private final TimeParser encodingParser = Jdk8LocalDateTimeUtil.parserOf(ISODateTimeFormat.dateHourMinuteSecondMillis()); 
+    private final TimeFormatter encodingFormatter = Jdk8LocalDateTimeUtil.formatterOf(ISODateTimeFormat.dateHourMinuteSecondMillis());
+    
+    private TimeFormatter titleStringFormatter;
+    private String titleStringFormatNameOrPattern;
+
+    
+    // //////////////////////////////////////
+    // constructor
+    // //////////////////////////////////////
+
+    /**
+     * Required because implementation of {@link TimeParser} and
+     * {@link EncoderDecoder}.
+     */
+    public Jdk8LocalDateTimeValueSemanticsProvider() {
+        this(null, null);
+    }
+
+    /**
+     * Uses {@link #type()} as the facet type.
+     */
+    public Jdk8LocalDateTimeValueSemanticsProvider(final FacetHolder holder, final ServicesInjector context) {
+        super(type(), holder, LocalDateTime.class, TYPICAL_LENGTH, MAX_LENGTH, Immutability.IMMUTABLE, EqualByContent.HONOURED, DEFAULT_VALUE, context);
+
+        String configuredNameOrPattern = getConfiguration().getString(CFG_FORMAT_KEY, "medium").toLowerCase().trim();
+        updateTitleStringFormatter(configuredNameOrPattern);
+    }
+
+
+    private void updateTitleStringFormatter(String titleStringFormatNameOrPattern) {
+        titleStringFormatter = NAMED_TITLE_FORMATTERS.get(titleStringFormatNameOrPattern);
+        if (titleStringFormatter == null) {
+            titleStringFormatter = 
+            		DateTimeFormatter.ofPattern(titleStringFormatNameOrPattern)::format;
+        }
+        this.titleStringFormatNameOrPattern = titleStringFormatNameOrPattern; 
+    }
+    
+
+    // //////////////////////////////////////////////////////////////////
+    // Parsing
+    // //////////////////////////////////////////////////////////////////
+
+    @Override
+    protected LocalDateTime doParse(
+            final String entry,
+            final Object context) {
+
+        updateTitleStringFormatterIfOverridden();
+        
+        LocalDateTime contextDateTime = (LocalDateTime) context;
+
+        final String dateString = entry.trim().toUpperCase();
+        if (dateString.startsWith("+") && contextDateTime != null) {
+            return Jdk8LocalDateTimeUtil.relativeDateTime(contextDateTime, dateString, true);
+        } else if (dateString.startsWith("-")  && contextDateTime != null) {
+            return Jdk8LocalDateTimeUtil.relativeDateTime(contextDateTime, dateString, false);
+        } else {
+            return parseDateTime(dateString, contextDateTime);
+        }
+    }
+
+    private void updateTitleStringFormatterIfOverridden() {
+        final String overridePattern = OVERRIDE_TITLE_PATTERN.get();
+        if (overridePattern == null || 
+            titleStringFormatNameOrPattern.equals(overridePattern)) {
+            return;
+        } 
+        
+        // (re)create format
+        updateTitleStringFormatter(overridePattern);
+    }
+
+    private LocalDateTime parseDateTime(final String dateStr, final Object original) {
+        return Jdk8LocalDateTimeUtil.parseDate(dateStr, PARSE_FORMATTERS);
+    }
+    
+
+    // ///////////////////////////////////////////////////////////////////////////
+    // TitleProvider
+    // ///////////////////////////////////////////////////////////////////////////
+
+    @Override
+    public String titleString(final Object value) {
+        if (value == null) {
+            return null;
+        }
+        final LocalDateTime dateTime = (LocalDateTime) value;
+        return Jdk8LocalDateTimeUtil.titleString(titleStringFormatter, dateTime);
+    }
+
+    @Override
+    public String titleStringWithMask(final Object value, final String usingMask) {
+        final LocalDateTime dateTime = (LocalDateTime) value;
+        return Jdk8LocalDateTimeUtil.titleString(
+        		DateTimeFormatter.ofPattern(usingMask)::format, 
+        		dateTime);
+    }
+
+
+    // //////////////////////////////////////////////////////////////////
+    // EncoderDecoder
+    // //////////////////////////////////////////////////////////////////
+
+    @Override
+    protected String doEncode(final Object object) {
+        final LocalDateTime date = (LocalDateTime) object;
+        return encode(date);
+    }
+
+    private synchronized String encode(final LocalDateTime date) {
+        return encodingFormatter.apply(date);
+    }
+
+    @Override
+    protected LocalDateTime doRestore(final String data) {
+        try {
+            return parse(data);
+        } catch (final IllegalArgumentException e) {
+            throw new EncodingException(e);
+        }
+    }
+
+    private synchronized LocalDateTime parse(final String data) {
+        return encodingParser.apply(data); 
+    }
+
+    // //////////////////////////////////////////////////////////////////
+    // Jdk8LocalDateValueFacet
+    // //////////////////////////////////////////////////////////////////
+
+    @Override
+    public final LocalDateTime dateValue(final ObjectAdapter object) {
+        return (LocalDateTime) (object == null ? null : object.getObject());
+    }
+
+    @Override
+    public final ObjectAdapter createValue(final LocalDateTime date) {
+        return getAdapterManager().adapterFor(date);
+    }
+
+
+    // //////////////////////////////////////
+    
+    @Override
+    public String toString() {
+        return "Jdk8LocalDateTimeValueSemanticsProvider: " + titleStringFormatter;
+    }
+
+}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datetimejdk8local/TimeFormatter.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datetimejdk8local/TimeFormatter.java
new file mode 100644
index 0000000..4911dfc
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datetimejdk8local/TimeFormatter.java
@@ -0,0 +1,27 @@
+/*
+ *  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.core.metamodel.facets.value.datetimejdk8local;
+
+import java.time.LocalDateTime;
+import java.util.function.Function;
+
+interface TimeFormatter extends Function<LocalDateTime, String> {
+
+}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datetimejdk8local/TimeParser.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datetimejdk8local/TimeParser.java
new file mode 100644
index 0000000..2417cfd
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datetimejdk8local/TimeParser.java
@@ -0,0 +1,27 @@
+/*
+ *  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.core.metamodel.facets.value.datetimejdk8local;
+
+import java.time.LocalDateTime;
+import java.util.function.Function;
+
+interface TimeParser extends Function<String, LocalDateTime> {
+
+}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datetimejdk8offset/Jdk8OffsetDateTimeValueFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datetimejdk8offset/Jdk8OffsetDateTimeValueFacet.java
new file mode 100644
index 0000000..27e1cde
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datetimejdk8offset/Jdk8OffsetDateTimeValueFacet.java
@@ -0,0 +1,33 @@
+/*
+ *  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.core.metamodel.facets.value.datetimejdk8offset;
+
+import java.time.OffsetDateTime;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.facetapi.Facet;
+
+public interface Jdk8OffsetDateTimeValueFacet extends Facet {
+
+    OffsetDateTime dateValue(ObjectAdapter object);
+
+    ObjectAdapter createValue(OffsetDateTime date);
+
+}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datetimejdk8offset/Jdk8OffsetDateTimeValueFacetUsingSemanticsProviderFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datetimejdk8offset/Jdk8OffsetDateTimeValueFacetUsingSemanticsProviderFactory.java
new file mode 100644
index 0000000..7916dfd
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datetimejdk8offset/Jdk8OffsetDateTimeValueFacetUsingSemanticsProviderFactory.java
@@ -0,0 +1,45 @@
+/*
+ *  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.core.metamodel.facets.value.datetimejdk8offset;
+
+import java.time.OffsetDateTime;
+
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.object.value.vsp.ValueFacetUsingSemanticsProviderFactory;
+
+public class Jdk8OffsetDateTimeValueFacetUsingSemanticsProviderFactory extends ValueFacetUsingSemanticsProviderFactory<OffsetDateTime> {
+
+    public Jdk8OffsetDateTimeValueFacetUsingSemanticsProviderFactory() {
+     // as per inherited DateTimeValueSemanticsProvider#facetType
+        super(); 
+    }
+
+    @Override
+    public void process(final ProcessClassContext processClassContext) {
+        final Class<?> type = processClassContext.getCls();
+        final FacetHolder holder = processClassContext.getFacetHolder();
+
+        if (type != OffsetDateTime.class) {
+            return;
+        }
+        addFacets(new Jdk8OffsetDateTimeValueSemanticsProvider(holder, getContext()));
+    }
+
+}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datetimejdk8offset/Jdk8OffsetDateTimeValueSemanticsProvider.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datetimejdk8offset/Jdk8OffsetDateTimeValueSemanticsProvider.java
new file mode 100644
index 0000000..2952aed
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datetimejdk8offset/Jdk8OffsetDateTimeValueSemanticsProvider.java
@@ -0,0 +1,104 @@
+/*
+ *  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.core.metamodel.facets.value.datetimejdk8offset;
+
+import java.time.OffsetDateTime;
+import java.time.ZoneOffset;
+import java.time.format.DateTimeFormatter;
+import java.util.Date;
+
+import org.apache.isis.applib.adapters.EncoderDecoder;
+import org.apache.isis.applib.adapters.EncodingException;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.value.datetimejoda.JodaDateTimeValueSemanticsProviderAbstract;
+import org.apache.isis.core.metamodel.services.ServicesInjector;
+
+public class Jdk8OffsetDateTimeValueSemanticsProvider extends JodaDateTimeValueSemanticsProviderAbstract<OffsetDateTime> {
+
+    // no default
+    private static final OffsetDateTime DEFAULT_VALUE = null;
+
+
+    /**
+     * Required because implementation of {@link TimeParser} and
+     * {@link EncoderDecoder}.
+     */
+    public Jdk8OffsetDateTimeValueSemanticsProvider() {
+        this(null, null);
+    }
+
+    public Jdk8OffsetDateTimeValueSemanticsProvider(final FacetHolder holder, final ServicesInjector context) {
+        super(holder, OffsetDateTime.class, DEFAULT_VALUE, context);
+    }
+
+    @Override
+    protected OffsetDateTime add(final OffsetDateTime original, final int years, final int months, final int days, final int hours, final int minutes) {
+        if(hours != 0 || minutes != 0) {
+            throw new IllegalArgumentException("cannot add non-zero hours or minutes to a DateTime");
+        }
+        return original.plusYears(years).plusMonths(months).plusDays(days);
+    }
+
+    @Override
+    protected OffsetDateTime now() {
+        return OffsetDateTime.now();
+    }
+
+    @Override
+    protected Date dateValue(final Object value) {
+    	long epochMilli = ((OffsetDateTime) value).toInstant().toEpochMilli();
+        return new Date(epochMilli);
+    }
+
+    @Override
+    protected OffsetDateTime setDate(final Date date) {
+    	return OffsetDateTime.ofInstant(date.toInstant(), ZoneOffset.UTC);
+    }
+
+    // //////////////////////////////////////////////////////////////////
+    // EncoderDecoder
+    // //////////////////////////////////////////////////////////////////
+
+    private final DateTimeFormatter encodingFormatter = DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmss.SSSZ");
+
+    @Override
+    protected String doEncode(final Object object) {
+        final OffsetDateTime date = (OffsetDateTime) object;
+        return encode(date);
+    }
+
+    private synchronized String encode(final OffsetDateTime date) {
+        return encodingFormatter.format(date);
+    }
+
+    @Override
+    protected OffsetDateTime doRestore(final String data) {
+        try {
+            return parse(data);
+        } catch (final IllegalArgumentException e) {
+            throw new EncodingException(e);
+        }
+    }
+
+    private synchronized OffsetDateTime parse(final String data) {
+    	return OffsetDateTime.parse(data, encodingFormatter); 
+    }
+
+}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datetimejdk8offset/Jdk8OffsetDateTimeValueSemanticsProviderAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datetimejdk8offset/Jdk8OffsetDateTimeValueSemanticsProviderAbstract.java
new file mode 100644
index 0000000..e532bcb
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/value/datetimejdk8offset/Jdk8OffsetDateTimeValueSemanticsProviderAbstract.java
@@ -0,0 +1,120 @@
+/*
+ *  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.core.metamodel.facets.value.datetimejdk8offset;
+
+import java.text.DateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import com.google.common.collect.Maps;
+
+import org.apache.isis.core.commons.config.ConfigurationConstants;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.value.ValueSemanticsProviderAbstractTemporal;
+import org.apache.isis.core.metamodel.services.ServicesInjector;
+
+public abstract class Jdk8OffsetDateTimeValueSemanticsProviderAbstract<T> extends ValueSemanticsProviderAbstractTemporal<T> {
+
+    private static final Map<String, DateFormat> FORMATS = Maps.newHashMap();
+
+    static {
+        FORMATS.put(ISO_ENCODING_FORMAT, createDateEncodingFormat("yyyyMMdd"));
+        FORMATS.put("iso", createDateFormat("yyyy-MM-dd"));
+        FORMATS.put("medium", DateFormat.getDateInstance(DateFormat.MEDIUM));
+    }
+
+    public Jdk8OffsetDateTimeValueSemanticsProviderAbstract(final FacetHolder holder, final Class<T> adaptedClass, final T defaultValue, final ServicesInjector context) {
+        super("date", holder, adaptedClass, 12, Immutability.IMMUTABLE, EqualByContent.HONOURED, defaultValue, context);
+
+        final String formatRequired = getConfiguration().getString(ConfigurationConstants.ROOT + "value.format.date");
+        if (formatRequired == null) {
+            format = formats().get(defaultFormat());
+        } else {
+            setMask(formatRequired);
+        }
+    }
+
+
+    // //////////////////////////////////////////////////////////////////
+    // temporal-specific stuff
+    // //////////////////////////////////////////////////////////////////
+
+    @Override
+    protected void clearFields(final Calendar cal) {
+        cal.set(Calendar.HOUR, 0);
+        cal.set(Calendar.HOUR_OF_DAY, 0);
+        cal.set(Calendar.MINUTE, 0);
+        cal.set(Calendar.SECOND, 0);
+        cal.set(Calendar.AM_PM, 0);
+        cal.set(Calendar.MILLISECOND, 0);
+    }
+
+    @Override
+    protected String defaultFormat() {
+        return "medium";
+    }
+
+    @Override
+    protected boolean ignoreTimeZone() {
+        return true;
+    }
+
+    @Override
+    protected Map<String, DateFormat> formats() {
+        return FORMATS;
+    }
+
+    @Override
+    public String toString() {
+        return "DateValueSemanticsProvider: " + format;
+    }
+
+    @Override
+    protected DateFormat format() {
+        final Locale locale = Locale.getDefault();
+
+        final DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.MEDIUM, locale);
+        dateFormat.setTimeZone(UTC_TIME_ZONE);
+        return dateFormat;
+    }
+
+    protected List<DateFormat> formatsToTry() {
+
+        final Locale locale = Locale.getDefault();
+
+        List<DateFormat> formats = new ArrayList<>();
+
+        formats.add(DateFormat.getDateInstance(DateFormat.LONG, locale));
+        formats.add(DateFormat.getDateInstance(DateFormat.MEDIUM, locale));
+        formats.add(DateFormat.getDateInstance(DateFormat.SHORT, locale));
+        formats.add(createDateFormat("yyyy-MM-dd"));
+        formats.add(createDateFormat("yyyyMMdd"));
+
+        for (DateFormat format : formats) {
+            format.setTimeZone(UTC_TIME_ZONE);
+        }
+
+        return formats;
+    }
+
+}
diff --git a/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/ProgrammingModelFacetsJava5.java b/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/ProgrammingModelFacetsJava5.java
index 4ac5d5e..b786d42 100644
--- a/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/ProgrammingModelFacetsJava5.java
+++ b/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/ProgrammingModelFacetsJava5.java
@@ -130,9 +130,12 @@ import org.apache.isis.core.metamodel.facets.value.chars.CharWrapperValueFacetUs
 import org.apache.isis.core.metamodel.facets.value.clobs.ClobValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.color.ColorValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.date.DateValueFacetUsingSemanticsProviderFactory;
+import org.apache.isis.core.metamodel.facets.value.datejdk8local.Jdk8LocalDateValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.datejodalocal.JodaLocalDateValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.datesql.JavaSqlDateValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.datetime.DateTimeValueFacetUsingSemanticsProviderFactory;
+import org.apache.isis.core.metamodel.facets.value.datetimejdk8local.Jdk8LocalDateTimeValueFacetUsingSemanticsProviderFactory;
+import org.apache.isis.core.metamodel.facets.value.datetimejdk8offset.Jdk8OffsetDateTimeValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.datetimejoda.JodaDateTimeValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.datetimejodalocal.JodaLocalDateTimeValueFacetUsingSemanticsProviderFactory;
 import org.apache.isis.core.metamodel.facets.value.dateutil.JavaUtilDateValueFacetUsingSemanticsProviderFactory;
@@ -275,7 +278,6 @@ public final class ProgrammingModelFacetsJava5 extends ProgrammingModelAbstract
         addFactory(new NotInServiceMenuFacetDerivedFromDomainServiceFacetFactory());
 
         
-
         // must come after CssClassFacetOnMemberFactory
         addFactory(new CssClassFacetOnActionFromConfiguredRegexFactory());
 
@@ -292,7 +294,6 @@ public final class ProgrammingModelFacetsJava5 extends ProgrammingModelAbstract
         addFactory(new MixinFacetForMixinAnnotationFactory());
 
 
-
         // must come after RecreatableObjectFacetFactory
         addFactory(new DomainObjectAnnotationFacetFactory());
 
@@ -387,6 +388,11 @@ public final class ProgrammingModelFacetsJava5 extends ProgrammingModelAbstract
         addFactory(new JodaLocalDateTimeValueFacetUsingSemanticsProviderFactory());
         addFactory(new JodaDateTimeValueFacetUsingSemanticsProviderFactory());
 
+        // java 8 time values
+        addFactory(new Jdk8LocalDateValueFacetUsingSemanticsProviderFactory());
+        addFactory(new Jdk8OffsetDateTimeValueFacetUsingSemanticsProviderFactory());
+        addFactory(new Jdk8LocalDateTimeValueFacetUsingSemanticsProviderFactory());
+        
         // written to not trample over TypeOf if already installed
         addFactory(new CollectionFacetFactory());
         // must come after CollectionFacetFactory
diff --git a/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java
index ec9e27d..a350367 100644
--- a/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java
+++ b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/registries/components/ComponentFactoryRegistrarDefault.java
@@ -46,6 +46,9 @@ import org.apache.isis.viewer.wicket.ui.components.header.HeaderPanelFactory;
 import org.apache.isis.viewer.wicket.ui.components.property.PropertyEditFormPanelFactory;
 import org.apache.isis.viewer.wicket.ui.components.property.PropertyEditPanelFactory;
 import org.apache.isis.viewer.wicket.ui.components.scalars.isisapplib.*;
+import org.apache.isis.viewer.wicket.ui.components.scalars.jdk8time.Jdk8LocalDatePanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.scalars.jdk8time.Jdk8LocalDateTimePanelFactory;
+import org.apache.isis.viewer.wicket.ui.components.scalars.jdk8time.Jdk8OffsetDateTimePanelFactory;
 import org.apache.isis.viewer.wicket.ui.components.scalars.jdkdates.JavaSqlDatePanelFactory;
 import org.apache.isis.viewer.wicket.ui.components.scalars.jdkdates.JavaSqlTimePanelFactory;
 import org.apache.isis.viewer.wicket.ui.components.scalars.jdkdates.JavaSqlTimestampPanelFactory;
@@ -217,6 +220,10 @@ public class ComponentFactoryRegistrarDefault implements ComponentFactoryRegistr
         componentFactories.add(new JodaLocalDatePanelFactory());
         componentFactories.add(new JodaLocalDateTimePanelFactory());
         componentFactories.add(new JodaDateTimePanelFactory());
+        
+        componentFactories.add(new Jdk8OffsetDateTimePanelFactory());	
+        componentFactories.add(new Jdk8LocalDatePanelFactory());
+        componentFactories.add(new Jdk8LocalDateTimePanelFactory());
 
         componentFactories.add(new ValuePanelFactory());
 
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
new file mode 100644
index 0000000..a2c817b
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/DateConverterForJdk8Abstract.java
@@ -0,0 +1,62 @@
+/*
+ *  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.jdk8time;
+
+import org.apache.wicket.util.convert.ConversionException;
+import org.apache.isis.viewer.wicket.ui.components.scalars.DateConverterAbstract;
+
+import java.time.format.DateTimeFormatter;
+import java.util.Locale;
+
+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);
+    }
+
+    @Override
+    protected final T doConvertToObject(String value, Locale locale) {
+        T dateTime = convert(value);
+        return minusDays(dateTime, adjustBy);
+    }
+
+    @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));
+    }
+
+    protected DateTimeFormatter getFormatterForDatePattern8() {
+        return DateTimeFormatter.ofPattern(datePattern);
+    }
+
+    protected DateTimeFormatter getFormatterForDateTimePattern8() {
+        return DateTimeFormatter.ofPattern(dateTimePattern);
+    }
+
+    protected abstract T minusDays(T value, int adjustBy);
+    protected abstract T plusDays(T value, int adjustBy);
+
+    protected abstract T convert(String value) throws ConversionException;
+    protected abstract String toString(T value, DateTimeFormatter dateTimeFormatter);
+
+}
\ No newline at end of file
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
new file mode 100644
index 0000000..799d21a
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/DateConverterForJdk8LocalDate.java
@@ -0,0 +1,64 @@
+/*
+ *  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.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;
+
+/**
+ * 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.
+ */
+public class DateConverterForJdk8LocalDate extends DateConverterForJdk8Abstract<LocalDate> {
+    
+    private static final long serialVersionUID = 1L;
+
+    public DateConverterForJdk8LocalDate(WicketViewerSettings settings, int adjustBy) {
+        super(LocalDate.class, settings.getDatePattern(), settings.getDatePattern(), adjustBy);
+    }
+
+    @Override
+    protected LocalDate minusDays(LocalDate value, int adjustBy) {
+        return value.minusDays(adjustBy);
+    }
+
+    @Override
+    protected LocalDate plusDays(LocalDate value, int adjustBy) {
+        return value.plusDays(adjustBy);
+    }
+
+    @Override
+    protected LocalDate convert(String value) throws ConversionException {
+        try {
+            return getFormatterForDateTimePattern8().parse(value, LocalDate::from);
+        } catch(Exception ex) {
+            throw new ConversionException(String.format("Cannot convert '%s' into a date/time", value), ex);
+        }
+    }
+    
+
+
+    @Override
+    protected String toString(LocalDate value, DateTimeFormatter dateTimeFormatter) {
+        return value.format(dateTimeFormatter);
+    }
+}
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
new file mode 100644
index 0000000..99e6ed2
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/DateConverterForJdk8LocalDateTime.java
@@ -0,0 +1,76 @@
+/*
+ *  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.jdk8time;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.format.DateTimeFormatter;
+
+import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
+import org.apache.wicket.util.convert.ConversionException;
+
+public class DateConverterForJdk8LocalDateTime extends DateConverterForJdk8Abstract<LocalDateTime> {
+
+    private static final long serialVersionUID = 1L;
+
+    public DateConverterForJdk8LocalDateTime(WicketViewerSettings settings, int adjustBy) {
+        super(LocalDateTime.class, settings.getDatePattern(), settings.getDateTimePattern(), adjustBy);
+    }
+
+
+    @Override
+    protected LocalDateTime minusDays(LocalDateTime value, int adjustBy) {
+        return value.minusDays(adjustBy);
+    }
+
+    @Override
+    protected LocalDateTime plusDays(LocalDateTime value, int adjustBy) {
+        return value.plusDays(adjustBy);
+    }
+
+
+    @Override
+    protected LocalDateTime convert(String value) throws ConversionException {
+        try {
+            return getFormatterForDateTimePattern8().parse(value, LocalDateTime::from);
+        } catch(Exception ex) {
+        	
+            try {
+                
+            	return LocalDateTime.of(
+                		getFormatterForDatePattern8().parse(value, LocalDate::from),
+                		LocalTime.of(0, 0)	);
+            
+            } catch(Exception ex2) {
+            	
+                throw new ConversionException(
+                		String.format(
+                				"Cannot convert '%s' into a date/time using pattern '%s' or '%s'", 
+                				value, dateTimePattern, datePattern), 
+                		ex2	);
+            }
+        }
+    }
+
+    @Override
+    protected String toString(LocalDateTime value, DateTimeFormatter dateTimeFormatter) {
+        return value.format(dateTimeFormatter);
+    }
+}
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
new file mode 100644
index 0000000..5d324b4
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/DateConverterForJdk8OffsetDateTime.java
@@ -0,0 +1,92 @@
+/*
+ *  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.jdk8time;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.OffsetDateTime;
+import java.time.ZoneOffset;
+import java.time.format.DateTimeFormatter;
+
+import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
+import org.apache.wicket.util.convert.ConversionException;
+
+public class DateConverterForJdk8OffsetDateTime extends DateConverterForJdk8Abstract<OffsetDateTime> {
+
+	private static final long serialVersionUID = 1L;
+
+	public DateConverterForJdk8OffsetDateTime(WicketViewerSettings settings, int adjustBy) {
+		super(OffsetDateTime.class, settings.getDatePattern(), settings.getDateTimePattern(), adjustBy);
+	}
+
+	@Override
+	protected OffsetDateTime minusDays(OffsetDateTime value, int adjustBy) {
+		return value.minusDays(adjustBy);
+	}
+
+	@Override
+	protected OffsetDateTime plusDays(OffsetDateTime value, int adjustBy) {
+		return value.plusDays(adjustBy);
+	}
+
+	@Override
+	protected OffsetDateTime convert(String value) throws ConversionException {
+
+		return OffsetDateTime.of(
+				convertToLocal(value),
+				defaultOffset()
+				);
+
+	}
+
+	@Override
+	protected String toString(OffsetDateTime value, DateTimeFormatter dateTimeFormatter) {
+		return value.format(dateTimeFormatter);
+	}
+
+	// -- HELPER
+
+	private LocalDateTime convertToLocal(String value) throws ConversionException {
+		try {
+			return getFormatterForDateTimePattern8().parse(value, LocalDateTime::from);
+		} catch(Exception ex) {
+
+			try {
+
+				return LocalDateTime.of(
+						getFormatterForDatePattern8().parse(value, LocalDate::from),
+						LocalTime.of(0, 0)	);
+
+			} catch(Exception ex2) {
+
+				throw new ConversionException(
+						String.format(
+								"Cannot convert '%s' into a date/time using pattern '%s' or '%s'", 
+								value, dateTimePattern, datePattern), 
+						ex2	);
+			}
+		}
+	}
+
+	private ZoneOffset defaultOffset() {
+		return OffsetDateTime.now().getOffset();
+
+	}
+}
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/Jdk8LocalDatePanel.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/Jdk8LocalDatePanel.java
new file mode 100644
index 0000000..8a448d6
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/Jdk8LocalDatePanel.java
@@ -0,0 +1,42 @@
+/*
+ *  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.jdk8time;
+
+import java.time.LocalDate;
+
+import org.apache.isis.viewer.wicket.model.models.ScalarModel;
+import org.apache.isis.viewer.wicket.ui.components.scalars.ScalarPanelTextFieldDatePickerAbstract;
+/**
+ * Panel for rendering scalars of type {@link LocalDate}.
+ */
+public class Jdk8LocalDatePanel extends ScalarPanelTextFieldDatePickerAbstract<LocalDate> {
+
+    private static final long serialVersionUID = 1L;
+
+    public Jdk8LocalDatePanel(final String id, final ScalarModel scalarModel) {
+        super(id, scalarModel, LocalDate.class); 
+        init(new DateConverterForJdk8LocalDate(getSettings(), getAdjustBy()));
+    }
+
+    @Override
+    protected String getScalarPanelType() {
+        return "jdk8DateTimePanel";
+    }
+}
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/Jdk8LocalDatePanelFactory.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/Jdk8LocalDatePanelFactory.java
new file mode 100644
index 0000000..7194e4b
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/Jdk8LocalDatePanelFactory.java
@@ -0,0 +1,47 @@
+/*
+ *  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.jdk8time;
+
+import org.apache.wicket.Component;
+
+import java.time.LocalDate;
+
+import org.apache.isis.viewer.wicket.model.models.ScalarModel;
+import org.apache.isis.viewer.wicket.ui.ComponentFactory;
+import org.apache.isis.viewer.wicket.ui.components.scalars.ComponentFactoryScalarAbstract;
+
+
+/**
+ * {@link ComponentFactory} for {@link Jdk8LocalDatePanel}.
+ */
+public class Jdk8LocalDatePanelFactory extends ComponentFactoryScalarAbstract {
+
+    private static final long serialVersionUID = 1L;
+
+    public Jdk8LocalDatePanelFactory() {
+        super(Jdk8LocalDatePanel.class, LocalDate.class);
+    }
+
+    @Override
+    public Component createComponent(final String id, final ScalarModel scalarModel) {
+        return new Jdk8LocalDatePanel(id, scalarModel);
+    }
+
+}
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/Jdk8LocalDateTimePanel.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/Jdk8LocalDateTimePanel.java
new file mode 100644
index 0000000..a90beb3
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/Jdk8LocalDateTimePanel.java
@@ -0,0 +1,52 @@
+/*
+ *  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.jdk8time;
+
+import java.time.LocalDateTime;
+
+import org.apache.isis.viewer.wicket.model.models.ScalarModel;
+import org.apache.isis.viewer.wicket.ui.components.scalars.ScalarPanelTextFieldDatePickerAbstract;
+import org.apache.isis.viewer.wicket.ui.components.scalars.TextFieldValueModel;
+import org.apache.isis.viewer.wicket.ui.components.scalars.datepicker.TextFieldWithDateTimePicker;
+import org.apache.wicket.markup.html.form.AbstractTextComponent;
+
+/**
+ * Panel for rendering scalars of type {@link LocalDateTime}.
+ */
+public class Jdk8LocalDateTimePanel extends ScalarPanelTextFieldDatePickerAbstract<LocalDateTime> {
+
+    private static final long serialVersionUID = 1L;
+
+    public Jdk8LocalDateTimePanel(final String id, final ScalarModel scalarModel) {
+        super(id, scalarModel, LocalDateTime.class);
+        init(new DateConverterForJdk8LocalDateTime(getSettings(), getAdjustBy()));
+    }
+
+    protected AbstractTextComponent<LocalDateTime> createTextFieldForRegular(final String id) {
+        final TextFieldValueModel<LocalDateTime> textFieldValueModel = new TextFieldValueModel<>(this);
+        return new TextFieldWithDateTimePicker<>(id, textFieldValueModel, cls, converter);
+    }
+
+    @Override
+    protected String getScalarPanelType() {
+        return "jdk8LocalDateTimePanel";
+    }
+    
+}
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/Jdk8LocalDateTimePanelFactory.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/Jdk8LocalDateTimePanelFactory.java
new file mode 100644
index 0000000..475ea31
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/Jdk8LocalDateTimePanelFactory.java
@@ -0,0 +1,45 @@
+/*
+ *  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.jdk8time;
+
+import java.time.LocalDateTime;
+
+import org.apache.isis.viewer.wicket.model.models.ScalarModel;
+import org.apache.isis.viewer.wicket.ui.ComponentFactory;
+import org.apache.isis.viewer.wicket.ui.components.scalars.ComponentFactoryScalarAbstract;
+import org.apache.wicket.Component;
+
+/**
+ * {@link ComponentFactory} for {@link Jdk8LocalDatePanel}.
+ */
+public class Jdk8LocalDateTimePanelFactory extends ComponentFactoryScalarAbstract {
+
+    private static final long serialVersionUID = 1L;
+
+    public Jdk8LocalDateTimePanelFactory() {
+        super(Jdk8LocalDateTimePanel.class, LocalDateTime.class);
+    }
+
+    @Override
+    public Component createComponent(final String id, final ScalarModel scalarModel) {
+        return new Jdk8LocalDateTimePanel(id, scalarModel);
+    }
+
+}
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/Jdk8OffsetDateTimePanel.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/Jdk8OffsetDateTimePanel.java
new file mode 100644
index 0000000..c3b291f
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/Jdk8OffsetDateTimePanel.java
@@ -0,0 +1,51 @@
+/*
+ *  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.jdk8time;
+
+import java.time.OffsetDateTime;
+
+import org.apache.isis.viewer.wicket.model.models.ScalarModel;
+import org.apache.isis.viewer.wicket.ui.components.scalars.ScalarPanelTextFieldDatePickerAbstract;
+import org.apache.isis.viewer.wicket.ui.components.scalars.TextFieldValueModel;
+import org.apache.isis.viewer.wicket.ui.components.scalars.datepicker.TextFieldWithDateTimePicker;
+import org.apache.wicket.markup.html.form.AbstractTextComponent;
+
+/**
+ * Panel for rendering scalars of type {@link OffsetDateTime}.
+ */
+public class Jdk8OffsetDateTimePanel extends ScalarPanelTextFieldDatePickerAbstract<OffsetDateTime> {
+
+    private static final long serialVersionUID = 1L;
+
+    public Jdk8OffsetDateTimePanel(final String id, final ScalarModel scalarModel) {
+        super(id, scalarModel, OffsetDateTime.class);
+        init(new DateConverterForJdk8OffsetDateTime(getSettings(), getAdjustBy()));
+    }
+
+    protected AbstractTextComponent<OffsetDateTime> createTextFieldForRegular(final String id) {
+        final TextFieldValueModel<OffsetDateTime> textFieldValueModel = new TextFieldValueModel<>(this);
+        return new TextFieldWithDateTimePicker<>(id, textFieldValueModel, cls, converter);
+    }
+
+    @Override
+    protected String getScalarPanelType() {
+        return "jdk8DateTimePanel";
+    }
+}
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/Jdk8OffsetDateTimePanelFactory.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/Jdk8OffsetDateTimePanelFactory.java
new file mode 100644
index 0000000..7afab85
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/jdk8time/Jdk8OffsetDateTimePanelFactory.java
@@ -0,0 +1,45 @@
+/*
+ *  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.jdk8time;
+
+import java.time.OffsetDateTime;
+
+import org.apache.isis.viewer.wicket.model.models.ScalarModel;
+import org.apache.isis.viewer.wicket.ui.ComponentFactory;
+import org.apache.isis.viewer.wicket.ui.components.scalars.ComponentFactoryScalarAbstract;
+import org.apache.wicket.Component;
+
+/**
+ * {@link ComponentFactory} for {@link Jdk8LocalDatePanel}.
+ */
+public class Jdk8OffsetDateTimePanelFactory extends ComponentFactoryScalarAbstract {
+
+    private static final long serialVersionUID = 1L;
+
+    public Jdk8OffsetDateTimePanelFactory() {
+        super(Jdk8OffsetDateTimePanel.class, OffsetDateTime.class);
+    }
+
+    @Override
+    public Component createComponent(final String id, final ScalarModel scalarModel) {
+        return new Jdk8OffsetDateTimePanel(id, scalarModel);
+    }
+
+}
diff --git a/core/viewer-wicket-ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/jdk8time/DateConverterForJdk8LocalDateTest.java b/core/viewer-wicket-ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/jdk8time/DateConverterForJdk8LocalDateTest.java
new file mode 100644
index 0000000..aecfe24
--- /dev/null
+++ b/core/viewer-wicket-ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/jdk8time/DateConverterForJdk8LocalDateTest.java
@@ -0,0 +1,75 @@
+/*
+ *  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.jodatime.jdk8time;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import java.time.LocalDate;
+
+import org.jmock.Expectations;
+import org.jmock.auto.Mock;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2;
+import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2.Mode;
+import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
+import org.apache.isis.viewer.wicket.ui.components.scalars.jdk8time.DateConverterForJdk8LocalDate;
+
+public class DateConverterForJdk8LocalDateTest {
+
+    @Rule
+    public JUnitRuleMockery2 context = JUnitRuleMockery2.createFor(Mode.INTERFACES_AND_CLASSES);
+
+    @Mock
+    private WicketViewerSettings settings;
+
+    @Before
+    public void setUp() throws Exception {
+        context.checking(new Expectations() {
+            {
+                allowing(settings).getDatePattern();
+                will(returnValue("yyyy-MM-dd"));
+            }
+        });
+    }
+    
+    @Test
+    public void roundtrip() {
+        final DateConverterForJdk8LocalDate converter = new DateConverterForJdk8LocalDate(settings, 0);
+        final LocalDate dt = converter.convertToObject("2013-05-11", null);
+        assertThat(dt, is(LocalDate.of(2013, 05, 11)));
+        
+        final String str = converter.convertToString(dt, null);
+        assertThat(str, is("2013-05-11"));
+    }
+    
+    @Test
+    public void roundtripWithAdjustBy() {
+        final DateConverterForJdk8LocalDate converter = new DateConverterForJdk8LocalDate(settings, -1);
+        final LocalDate dt = converter.convertToObject("2013-05-11", null);
+        assertThat(dt, is(LocalDate.of(2013, 05, 12)));
+        
+        final String str = converter.convertToString(dt, null);
+        assertThat(str, is("2013-05-11"));
+    }
+
+}
diff --git a/core/viewer-wicket-ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/jdk8time/DateConverterForJdk8LocalDateTimeTest.java b/core/viewer-wicket-ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/jdk8time/DateConverterForJdk8LocalDateTimeTest.java
new file mode 100644
index 0000000..0105d30
--- /dev/null
+++ b/core/viewer-wicket-ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/jdk8time/DateConverterForJdk8LocalDateTimeTest.java
@@ -0,0 +1,97 @@
+/*
+ *  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.jodatime.jdk8time;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import org.jmock.Expectations;
+import org.jmock.auto.Mock;
+import java.time.LocalDateTime;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2;
+import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2.Mode;
+import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
+import org.apache.isis.viewer.wicket.ui.components.scalars.jdk8time.DateConverterForJdk8LocalDateTime;
+
+public class DateConverterForJdk8LocalDateTimeTest {
+
+    @Rule
+    public JUnitRuleMockery2 context = JUnitRuleMockery2.createFor(Mode.INTERFACES_AND_CLASSES);
+
+    @Mock
+    private WicketViewerSettings settings;
+
+    @Before
+    public void setUp() throws Exception {
+        context.checking(new Expectations() {
+            {
+                allowing(settings).getDatePattern();
+                will(returnValue("yyyy-MM-dd"));
+                allowing(settings).getDateTimePattern();
+                will(returnValue("yyyy-MM-dd HH:mm"));
+            }
+        });
+    }
+    
+    @Test
+    public void roundtripWhenParsingDateFormat() {
+        final DateConverterForJdk8LocalDateTime converter = new DateConverterForJdk8LocalDateTime(settings, 0);
+        final LocalDateTime dt = converter.convertToObject("2013-05-11", null);
+        assertThat(dt, is(LocalDateTime.of(2013, 05, 11, 0, 0)));
+        
+        final String str = converter.convertToString(dt, null);
+        assertThat(str, is("2013-05-11 00:00"));
+    }
+    
+    @Test
+    public void roundtripWhenParsingDateTimeFormat() {
+        final DateConverterForJdk8LocalDateTime converter = new DateConverterForJdk8LocalDateTime(settings, 0);
+        final LocalDateTime dt = converter.convertToObject("2013-05-11 00:00", null);
+        assertThat(dt, is(LocalDateTime.of(2013, 05, 11, 0, 0)));
+        
+        final String str = converter.convertToString(dt, null);
+        assertThat(str, is("2013-05-11 00:00"));
+    }
+    
+    @Test
+    public void roundtripWhenParsingDateFormatWithAdjustBy() {
+        final DateConverterForJdk8LocalDateTime converter = new DateConverterForJdk8LocalDateTime(settings, -1);
+        final LocalDateTime dt = converter.convertToObject("2013-05-11", null);
+        assertThat(dt, is(LocalDateTime.of(2013, 05, 12, 0, 0)));
+        
+        final String str = converter.convertToString(dt, null);
+        assertThat(str, is("2013-05-11 00:00"));
+    }
+
+    @Test
+    public void roundtripWhenParsingDateTimeFormatWithAdjustBy() {
+        final DateConverterForJdk8LocalDateTime converter = new DateConverterForJdk8LocalDateTime(settings, -1);
+        final LocalDateTime dt = converter.convertToObject("2013-05-11 00:00", null);
+        assertThat(dt, is(LocalDateTime.of(2013, 05, 12, 0, 0)));
+        
+        final String str = converter.convertToString(dt, null);
+        assertThat(str, is("2013-05-11 00:00"));
+    }
+    
+
+}
diff --git a/core/viewer-wicket-ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/jdk8time/DateConverterForJdk8OffsetDateTimeTest.java b/core/viewer-wicket-ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/jdk8time/DateConverterForJdk8OffsetDateTimeTest.java
new file mode 100644
index 0000000..4d1874c
--- /dev/null
+++ b/core/viewer-wicket-ui/src/test/java/org/apache/isis/viewer/wicket/ui/components/scalars/jodatime/jdk8time/DateConverterForJdk8OffsetDateTimeTest.java
@@ -0,0 +1,107 @@
+/*
+ *  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.jodatime.jdk8time;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import java.time.OffsetDateTime;
+
+import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2;
+import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2.Mode;
+import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
+import org.apache.isis.viewer.wicket.ui.components.scalars.jdk8time.DateConverterForJdk8OffsetDateTime;
+import org.jmock.Expectations;
+import org.jmock.auto.Mock;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+public class DateConverterForJdk8OffsetDateTimeTest {
+
+    @Rule
+    public JUnitRuleMockery2 context = JUnitRuleMockery2.createFor(Mode.INTERFACES_AND_CLASSES);
+
+    @Mock
+    private WicketViewerSettings settings;
+
+    @Before
+    public void setUp() throws Exception {
+        context.checking(new Expectations() {
+            {
+                allowing(settings).getDatePattern();
+                will(returnValue("yyyy-MM-dd"));
+                allowing(settings).getDateTimePattern();
+                will(returnValue("yyyy-MM-dd HH:mm"));
+            }
+        });
+    }
+    
+    
+    @Test
+    public void roundtripWhenParsingDateFormat() {
+        final DateConverterForJdk8OffsetDateTime converter = new DateConverterForJdk8OffsetDateTime(settings, 0);
+        final OffsetDateTime dt = converter.convertToObject("2013-05-11", null);
+        assertThat(dt, is(sample(2013, 05, 11, 0, 0)));
+        
+        final String str = converter.convertToString(dt, null);
+        assertThat(str, is("2013-05-11 00:00"));
+    }
+    
+    @Test
+    public void roundtripWhenParsingDateTimeFormat() {
+        final DateConverterForJdk8OffsetDateTime converter = new DateConverterForJdk8OffsetDateTime(settings, 0);
+        final OffsetDateTime dt = converter.convertToObject("2013-05-11 00:00", null);
+        assertThat(dt, is(sample(2013, 05, 11, 0, 0)));
+        
+        final String str = converter.convertToString(dt, null);
+        assertThat(str, is("2013-05-11 00:00"));
+    }
+    
+    @Test
+    public void roundtripWhenParsingDateFormatWithAdjustBy() {
+        final DateConverterForJdk8OffsetDateTime converter = new DateConverterForJdk8OffsetDateTime(settings, -1);
+        final OffsetDateTime dt = converter.convertToObject("2013-05-11", null);
+        assertThat(dt, is(sample(2013, 05, 12, 0, 0)));
+        
+        final String str = converter.convertToString(dt, null);
+        assertThat(str, is("2013-05-11 00:00"));
+    }
+
+    @Test
+    public void roundtripWhenParsingDateTimeFormatWithAdjustBy() {
+        final DateConverterForJdk8OffsetDateTime converter = new DateConverterForJdk8OffsetDateTime(settings, -1);
+        final OffsetDateTime dt = converter.convertToObject("2013-05-11 00:00", null);
+        assertThat(dt, is(sample(2013, 05, 12, 0, 0)));
+        
+        final String str = converter.convertToString(dt, null);
+        assertThat(str, is("2013-05-11 00:00"));
+    }
+
+
+	private static OffsetDateTime sample( int year, int month, int dayOfMonth,
+            int hour, int minute) {
+		return OffsetDateTime.of(year, month, dayOfMonth, hour, minute, 0, 0, 
+				OffsetDateTime.now().getOffset());
+	}
+    
+    
+    
+
+}

-- 
To stop receiving notification emails like this one, please contact
"commits@isis.apache.org" <co...@isis.apache.org>.