You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by sv...@apache.org on 2017/10/15 15:52:57 UTC

[1/2] wicket git commit: WICKET-6200 restructured, fixed javadoc, removed wrong code

Repository: wicket
Updated Branches:
  refs/heads/WICKET-6105-java.time 39bbfb91c -> 8567308e5


http://git-wip-us.apache.org/repos/asf/wicket/blob/8567308e/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/StyleDateConverter.java
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/StyleDateConverter.java b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/StyleDateConverter.java
deleted file mode 100644
index 79decad..0000000
--- a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/StyleDateConverter.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * 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.wicket.extensions.markup.html.form.datetime;
-
-import java.time.LocalDate;
-import java.time.chrono.IsoChronology;
-import java.time.format.DateTimeFormatter;
-import java.time.format.DateTimeFormatterBuilder;
-import java.time.format.FormatStyle;
-import java.util.Locale;
-
-/**
- * Date converter that uses javax.time and can be configured to take the time zone difference between
- * clients and server into account, and that is configured for a certain date style. The pattern
- * will always be locale specific.
- * <p>
- * This converter is especially suited on a per-component base.
- * </p>
- * 
- * @see org.apache.wicket.extensions.markup.html.form.DateTextField
- * @see java.time.LocalDate
- * @see DateTimeFormatter
- * 
- * @author eelcohillenius
- */
-public class StyleDateConverter extends LocalDateConverter
-{
-	private static final long serialVersionUID = 1L;
-
-	/**
-	 * Date style to use. See {@link DateTimeFormatter#ofLocalizedDate(FormatStyle)}.
-	 */
-	private final FormatStyle dateStyle;
-
-	/**
-	 * Construct. The dateStyle 'S-' (which is the same as {@link DateTimeFormatter#ofLocalizedDate(FormatStyle)}) will
-	 * be used for constructing the date format for the current locale.
-	 * 
-	 */
-	public StyleDateConverter()
-	{
-		this(FormatStyle.SHORT);
-	}
-
-	/**
-	 * Construct. The provided pattern will be used as the base format (but they will be localized
-	 * for the current locale) and if null, {@link DateTimeFormatter#ofLocalizedDate(FormatStyle)} will be used.
-	 * 
-	 * @param dateStyle
-	 *            Date style to use. See {@link DateTimeFormatter#ofLocalizedDate(FormatStyle)}.
-	 * @throws IllegalArgumentException
-	 *             in case dateStyle is null
-	 */
-	public StyleDateConverter(FormatStyle dateStyle)
-	{
-		super();
-		this.dateStyle = dateStyle;
-	}
-
-	public StyleDateConverter(String dateStyle)
-	{
-		this(parseFormatStyle(dateStyle.charAt(0)));
-	}
-
-	/**
-	 * Gets the optional date pattern.
-	 * 
-	 * @return datePattern
-	 */
-	@Override
-	public final String getPattern(Locale locale)
-	{
-		return DateTimeFormatterBuilder.getLocalizedDateTimePattern(dateStyle, null, IsoChronology.INSTANCE, locale);
-	}
-
-	/**
-	 * @return formatter The formatter for the current conversion
-	 */
-	@Override
-	public DateTimeFormatter getFormat(Locale locale)
-	{
-		return dateStyle == null ? null : DateTimeFormatter.ofLocalizedDate(dateStyle).withLocale(locale);
-	}
-
-	public static FormatStyle parseFormatStyle(char style)
-	{
-		return DateField.parseFormatStyle(style);
-	}
-
-	@Override
-	public LocalDate convertToObject(String value, DateTimeFormatter format, Locale locale) {
-		if (format == null) {
-			return null;
-		}
-		try
-		{
-			return LocalDate.parse(value, format);
-		}
-		catch (RuntimeException e)
-		{
-			throw newConversionException(e, locale);
-		}
-	}
-}

http://git-wip-us.apache.org/repos/asf/wicket/blob/8567308e/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/StyleTimeConverter.java
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/StyleTimeConverter.java b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/StyleTimeConverter.java
deleted file mode 100644
index e95725b..0000000
--- a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/StyleTimeConverter.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * 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.wicket.extensions.markup.html.form.datetime;
-
-import java.time.LocalTime;
-import java.time.chrono.IsoChronology;
-import java.time.format.DateTimeFormatter;
-import java.time.format.DateTimeFormatterBuilder;
-import java.time.format.FormatStyle;
-import java.util.Locale;
-
-/**
- * Date converter that uses javax.time and can be configured to take the time zone difference between
- * clients and server into account, and that is configured for a certain date style. The pattern
- * will always be locale specific.
- * <p>
- * This converter is especially suited on a per-component base.
- * </p>
- * 
- * @see org.apache.wicket.extensions.markup.html.form.DateTextField
- */
-public class StyleTimeConverter extends LocalTimeConverter
-{
-	private static final long serialVersionUID = 1L;
-
-	/**
-	 * Date style to use. See {@link DateTimeFormatter#ofLocalizedTime(FormatStyle)}.
-	 */
-	private final FormatStyle timeStyle;
-
-	/**
-	 * Construct. The dateStyle 'S-' (which is the same as {@link DateTimeFormatter#ofLocalizedTime(FormatStyle)}) will
-	 * be used for constructing the date format for the current locale.
-	 * 
-	 */
-	public StyleTimeConverter()
-	{
-		this(FormatStyle.SHORT);
-	}
-
-	/**
-	 * Construct. The provided pattern will be used as the base format (but they will be localized
-	 * for the current locale) and if null, {@link DateTimeFormatter#ofLocalizedTime(FormatStyle)} will be used.
-	 * 
-	 * @param timeStyle
-	 *            Date style to use. See {@link DateTimeFormatter#ofLocalizedTime(FormatStyle)}.
-	 * @throws IllegalArgumentException
-	 *             in case dateStyle is null
-	 */
-	public StyleTimeConverter(FormatStyle timeStyle)
-	{
-		super();
-		this.timeStyle = timeStyle;
-	}
-
-	public StyleTimeConverter(String timeStyle)
-	{
-		this(parseFormatStyle(timeStyle.charAt(0)));
-	}
-
-	/**
-	 * Gets the optional time pattern.
-	 * 
-	 * @return timePattern
-	 */
-	@Override
-	public final String getPattern(Locale locale)
-	{
-		return DateTimeFormatterBuilder.getLocalizedDateTimePattern(null, timeStyle, IsoChronology.INSTANCE, locale);
-	}
-
-	/**
-	 * @return formatter The formatter for the current conversion
-	 */
-	@Override
-	public DateTimeFormatter getFormat(Locale locale)
-	{
-		return timeStyle == null ? null : DateTimeFormatter.ofLocalizedTime(timeStyle).withLocale(locale);
-	}
-
-	public static FormatStyle parseFormatStyle(char style)
-	{
-		return TimeField.parseFormatStyle(style);
-	}
-
-	@Override
-	public LocalTime convertToObject(String value, DateTimeFormatter format, Locale locale) {
-		if (format == null) {
-			return null;
-		}
-		try
-		{
-			return LocalTime.parse(value, format);
-		}
-		catch (RuntimeException e)
-		{
-			throw newConversionException(e, locale);
-		}
-	}
-}

http://git-wip-us.apache.org/repos/asf/wicket/blob/8567308e/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/StyleZonedDateTimeConverter.java
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/StyleZonedDateTimeConverter.java b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/StyleZonedDateTimeConverter.java
deleted file mode 100644
index c186cfe..0000000
--- a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/StyleZonedDateTimeConverter.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * 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.wicket.extensions.markup.html.form.datetime;
-
-import java.time.LocalDate;
-import java.time.ZonedDateTime;
-import java.time.chrono.IsoChronology;
-import java.time.format.DateTimeFormatter;
-import java.time.format.DateTimeFormatterBuilder;
-import java.time.format.FormatStyle;
-import java.util.Locale;
-
-/**
- * Date converter that uses javax.time and can be configured to take the time zone difference between
- * clients and server into account, and that is configured for a certain date style. The pattern
- * will always be locale specific.
- * <p>
- * This converter is especially suited on a per-component base.
- * </p>
- * 
- * @see org.apache.wicket.extensions.markup.html.form.DateTextField
- * @see java.time.ZonedDateTime
- * @see DateTimeFormatter
- * @see java.time.ZoneId
- * 
- * @author eelcohillenius
- */
-public class StyleZonedDateTimeConverter extends ZonedDateTimeConverter
-{
-	private static final long serialVersionUID = 1L;
-
-	/**
-	 * Date style to use. See {@link DateTimeFormatter#ofLocalizedDate(FormatStyle)}.
-	 */
-	private final FormatStyle dateStyle;
-
-	private final FormatStyle timeStyle;
-
-	/**
-	 * Construct. The dateStyle 'S-' (which is the same as {@link DateTimeFormatter#ofLocalizedDate(FormatStyle)}) will
-	 * be used for constructing the date format for the current locale. </p> When
-	 * applyTimeZoneDifference is true, the current time is applied on the parsed date, and the date
-	 * will be corrected for the time zone difference between the server and the client. For
-	 * instance, if I'm in Seattle and the server I'm working on is in Amsterdam, the server is 9
-	 * hours ahead. So, if I'm inputting say 12/24 at a couple of hours before midnight, at the
-	 * server it is already 12/25. If this boolean is true, it will be transformed to 12/25, while
-	 * the client sees 12/24. </p>
-	 * 
-	 * @param applyTimeZoneDifference
-	 *            whether to apply the difference in time zones between client and server
-	 */
-	public StyleZonedDateTimeConverter(boolean applyTimeZoneDifference)
-	{
-		this(FormatStyle.SHORT, null, applyTimeZoneDifference);
-	}
-
-	/**
-	 * Construct. The provided pattern will be used as the base format (but they will be localized
-	 * for the current locale) and if null, {@link DateTimeFormatter#ofLocalizedDate(FormatStyle)} will be used. </p>
-	 * When applyTimeZoneDifference is true, the current time is applied on the parsed date, and the
-	 * date will be corrected for the time zone difference between the server and the client. For
-	 * instance, if I'm in Seattle and the server I'm working on is in Amsterdam, the server is 9
-	 * hours ahead. So, if I'm inputting say 12/24 at a couple of hours before midnight, at the
-	 * server it is already 12/25. If this boolean is true, it will be transformed to 12/25, while
-	 * the client sees 12/24. </p>
-	 * 
-	 * @param dateStyle
-	 *            Date style to use. See {@link DateTimeFormatter#ofLocalizedDate(FormatStyle)}.
-	 * @param timeStyle
-	 *            Time style to use. See {@link DateTimeFormatter#ofLocalizedTime(FormatStyle)}
-	 * @param applyTimeZoneDifference
-	 *            whether to apply the difference in time zones between client and server
-	 * @throws IllegalArgumentException
-	 *             in case dateStyle is null
-	 */
-	public StyleZonedDateTimeConverter(FormatStyle dateStyle, FormatStyle timeStyle, boolean applyTimeZoneDifference)
-	{
-		super(applyTimeZoneDifference);
-		this.dateStyle = dateStyle;
-		this.timeStyle = timeStyle;
-	}
-
-	public StyleZonedDateTimeConverter(String dateTimeStyle, boolean applyTimeZoneDifference)
-	{
-		this(parseFormatStyle(dateTimeStyle.charAt(0)), parseFormatStyle(dateTimeStyle.charAt(1)), applyTimeZoneDifference);
-	}
-
-	/**
-	 * Gets the optional date pattern.
-	 * 
-	 * @return datePattern
-	 */
-	@Override
-	public final String getPattern(Locale locale)
-	{
-		String localizedDateTimePattern = DateTimeFormatterBuilder.getLocalizedDateTimePattern(dateStyle, timeStyle, IsoChronology.INSTANCE, locale);
-		return localizedDateTimePattern;
-	}
-
-	/**
-	 * @return formatter The formatter for the current conversion
-	 */
-	@Override
-	public DateTimeFormatter getFormat(Locale locale)
-	{
-		DateTimeFormatter df = null;
-		if (dateStyle == null && timeStyle == null) {
-			return df;
-		}
-		if (timeStyle == null)
-		{
-			df = DateTimeFormatter.ofLocalizedDate(dateStyle);
-		}
-		else if (dateStyle == null)
-		{
-			df = DateTimeFormatter.ofLocalizedTime(timeStyle);
-		}
-		else
-		{
-			df = DateTimeFormatter.ofLocalizedDateTime(dateStyle, timeStyle);
-		}
-		return df.withLocale(locale);
-	}
-
-	public static FormatStyle parseFormatStyle(char style)
-	{
-		return DateField.parseFormatStyle(style);
-	}
-
-	@Override
-	public ZonedDateTime convertToObject(String value, DateTimeFormatter format, Locale locale) {
-		if (format == null) {
-			return null;
-		}
-		try
-		{
-			if (timeStyle == null)
-			{
-				LocalDate d = LocalDate.parse(value, format);
-				return ZonedDateTime.of(d.atStartOfDay(), getTimeZone());
-			}
-			else if (dateStyle == null)
-			{
-				// not sure how we can get ZonedDateTime from time
-				return null;
-			}
-			return super.convertToObject(value, format, locale);
-		}
-		catch (RuntimeException e)
-		{
-			throw newConversionException(e, locale);
-		}
-	}
-}

http://git-wip-us.apache.org/repos/asf/wicket/blob/8567308e/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/TimeField.html
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/TimeField.html b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/TimeField.html
index 82cb00d..b80249c 100644
--- a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/TimeField.html
+++ b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/TimeField.html
@@ -16,9 +16,9 @@
    limitations under the License.
 -->
 <wicket:panel xmlns:wicket="http://wicket.apache.org">
-  <span style="white-space: nowrap;">
+  <span>
     <input type="number" wicket:id="hours" size="2" maxlength="2" />
-    <span wicket:id="hoursSeparator">&#160;:</span>
+    <span wicket:id="hoursSeparator"> : </span>
     <input type="number" wicket:id="minutes" size="2" maxlength="2" />
     <select wicket:id="amOrPmChoice"></select>
   </span>

http://git-wip-us.apache.org/repos/asf/wicket/blob/8567308e/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/TimeField.java
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/TimeField.java b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/TimeField.java
index 68af251..976bc49 100644
--- a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/TimeField.java
+++ b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/TimeField.java
@@ -18,7 +18,6 @@ package org.apache.wicket.extensions.markup.html.form.datetime;
 
 import java.text.DecimalFormat;
 import java.text.NumberFormat;
-import java.text.SimpleDateFormat;
 import java.time.LocalTime;
 import java.time.chrono.IsoChronology;
 import java.time.format.DateTimeFormatterBuilder;
@@ -27,63 +26,49 @@ import java.time.temporal.ChronoField;
 import java.util.Arrays;
 import java.util.Locale;
 
-import org.apache.wicket.AttributeModifier;
-import org.apache.wicket.markup.html.WebMarkupContainer;
-import org.apache.wicket.markup.html.form.AbstractTextComponent.ITextFormatProvider;
+import org.apache.wicket.core.util.string.CssUtils;
+import org.apache.wicket.markup.ComponentTag;
+import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.markup.html.form.DropDownChoice;
 import org.apache.wicket.markup.html.form.FormComponentPanel;
 import org.apache.wicket.markup.html.form.TextField;
 import org.apache.wicket.model.IModel;
-import org.apache.wicket.model.Model;
+import org.apache.wicket.model.ResourceModel;
+import org.apache.wicket.util.convert.ConversionException;
 import org.apache.wicket.util.convert.IConverter;
 import org.apache.wicket.util.convert.converter.IntegerConverter;
-import org.apache.wicket.util.lang.Args;
 import org.apache.wicket.validation.validator.RangeValidator;
 
 /**
- * Works on a {@link java.util.Date} object. Displays a field for hours and a field for minutes, and
- * an AM/PM field. The format (12h/24h) of the hours field depends on the time format of this
+ * Works on a {@link LocalTime} object. Displays a field for hours and a field for minutes, and an
+ * AM/PM field. The format (12h/24h) of the hours field depends on the time format of this
  * {@link TimeField}'s {@link Locale}, as does the visibility of the AM/PM field (see
  * {@link TimeField#use12HourFormat}).
  * 
  * @author eelcohillenius
- * @see TimeField for a variant with just the date field and date picker
  */
-public class TimeField extends FormComponentPanel<LocalTime> implements ITextFormatProvider
+public class TimeField extends FormComponentPanel<LocalTime>
 {
 	private static final long serialVersionUID = 1L;
 
+	public static final String HOURS_CSS_CLASS_KEY = CssUtils.key(TimeField.class, "hours");
+
+	public static final String MINUTES_CSS_CLASS_KEY = CssUtils.key(TimeField.class, "minutes");
+
 	/**
 	 * Enumerated type for different ways of handling the render part of requests.
 	 */
-	public enum AM_PM {
-		/** */
-		AM("AM"),
-
-		/** */
-		PM("PM");
-
-		private  final String value;
-
-		AM_PM(final String name)
-		{
-			value = name;
-		}
-
-		@Override
-		public String toString()
-		{
-			return value;
-		}
+	public enum AM_PM
+	{
+		AM, PM;
 	}
-	protected static final String HOURS = "hours";
-	protected static final String MINUTES = "minutes";
-	protected static final String AM_OR_PM_CHOICE = "amOrPmChoice";
 
-	private static final IConverter<Integer> MINUTES_CONVERTER = new IntegerConverter() {
+	private static final IConverter<Integer> MINUTES_CONVERTER = new IntegerConverter()
+	{
 		private static final long serialVersionUID = 1L;
 
-		protected NumberFormat newNumberFormat(Locale locale) {
+		protected NumberFormat newNumberFormat(Locale locale)
+		{
 			return new DecimalFormat("00");
 		}
 	};
@@ -96,184 +81,67 @@ public class TimeField extends FormComponentPanel<LocalTime> implements ITextFor
 
 	// The dropdown list for AM/PM and it's associated model object
 	private DropDownChoice<AM_PM> amOrPmChoice;
-	private LocalTime time = LocalTime.now();
 
 	/**
-	 * Creates a new TimeField defaulting to using a short date pattern
-	 * 
-	 * @param id
-	 *            The id of the text field
-	 * @param model
-	 *            The model
-	 * @param timePattern
-	 *            The pattern to use. Must be not null. See {@link SimpleDateFormat} for available
-	 *            patterns.
-	 * @return TimeField
-	 */
-	public static TimeField forTimePattern(String id, IModel<LocalTime> model, String timePattern)
-	{
-		return new TimeField(id, model, new PatternTimeConverter(timePattern));
-	}
-
-	/**
-	 * Creates a new TimeField defaulting to using a short date pattern
+	 * Construct.
 	 * 
 	 * @param id
-	 *            The id of the text field
-	 * @param timePattern
-	 *            The pattern to use. Must be not null. See {@link SimpleDateFormat} for available
-	 *            patterns.
-	 * @return TimeField
+	 *            the component id
 	 */
-	public static TimeField forTimePattern(String id, String timePattern)
+	public TimeField(String id)
 	{
-		return forTimePattern(id, null, timePattern);
+		this(id, null);
 	}
 
 	/**
-	 * Creates a new TimeField using the provided date style.
+	 * Construct.
 	 * 
 	 * @param id
-	 *            The id of the text field
+	 *            the component id
 	 * @param model
-	 *            The model
-	 * @param timeStyle
-	 *            Date style to use. The first character is the date style, and the second character
-	 *            is the time style. Specify a character of 'S' for short style, 'M' for medium, 'L'
-	 *            for long, and 'F' for full. A date or time may be ommitted by specifying a style
-	 *            character '-'. See {@link org.joda.time.DateTimeFormat#forStyle(String)}.
-	 * @return TimeField
-	 */
-	public static TimeField forTimeStyle(String id, IModel<LocalTime> model, String timeStyle)
-	{
-		return new TimeField(id, model, new StyleTimeConverter(timeStyle));
-	}
-
-	/**
-	 * Creates a new TimeField using the provided date style.
-	 * 
-	 * @param id
-	 *            The id of the text field
-	 * @param timeStyle
-	 *            Date style to use. The first character is the date style, and the second character
-	 *            is the time style. Specify a character of 'S' for short style, 'M' for medium, 'L'
-	 *            for long, and 'F' for full. A date or time may be ommitted by specifying a style
-	 *            character '-'. See {@link org.joda.time.DateTimeFormat#forStyle(String)}.
-	 * @return TimeField
+	 *            the component's model
 	 */
-	public static TimeField forTimeStyle(String id, String timeStyle)
+	public TimeField(String id, IModel<LocalTime> model)
 	{
-		return forTimeStyle(id, null, timeStyle);
-	}
-
-	/**
-	 * Creates a new TimeField defaulting to using a short date pattern
-	 * 
-	 * @param id
-	 *            The id of the text field
-	 * @return TimeField
-	 */
-	public static TimeField forShortStyle(String id)
-	{
-		return forShortStyle(id, null);
-	}
+		super(id, model);
 
-	/**
-	 * Creates a new TimeField defaulting to using a short date pattern
-	 * 
-	 * @param id
-	 *            The id of the text field
-	 * @param model
-	 *            The model
-	 * @return TimeField
-	 */
-	public static TimeField forShortStyle(String id, IModel<LocalTime> model)
-	{
-		return new TimeField(id, model, new StyleTimeConverter());
-	}
+		// Sets the type that will be used when updating the model for this component.
+		setType(LocalTime.class);
 
-	/**
-	 * Creates a new TimeField using the provided converter.
-	 * 
-	 * @param id
-	 *            The id of the text field
-	 * @param converter
-	 *            the date converter
-	 * @return TimeField
-	 */
-	public static TimeField withConverter(String id, LocalTimeConverter converter)
-	{
-		return withConverter(id, null, converter);
-	}
+		add(new Label("hoursSeparator", new ResourceModel("TimeField.hoursSeparator"))
+		{
+			private static final long serialVersionUID = 1L;
 
-	/**
-	 * Creates a new TimeField using the provided converter.
-	 * 
-	 * @param id
-	 *            The id of the text field
-	 * @param model
-	 *            The model
-	 * @param converter
-	 *            the date converter
-	 * @return TimeField
-	 */
-	public static TimeField withConverter(String id, IModel<LocalTime> model, LocalTimeConverter converter)
-	{
-		return new TimeField(id, model, converter);
-	}
+			@Override
+			protected void onConfigure()
+			{
+				super.onConfigure();
 
-	/**
-	 * The converter for the TextField
-	 */
-	private final LocalTimeConverter converter;
+				minutesField.configure();
 
-	/**
-	 * Construct.
-	 * 
-	 * @param id
-	 *      the component id
-	 */
-	public TimeField(String id, LocalTimeConverter converter)
-	{
-		this(id, null, converter);
+				setVisible(minutesField.isVisible());
+			}
+		});
 	}
 
-	/**
-	 * Construct.
-	 * 
-	 * @param id
-	 *      the component id
-	 * @param model
-	 *      the component's model
-	 */
-	public TimeField(String id, IModel<LocalTime> model, LocalTimeConverter converter)
+	@Override
+	protected void onInitialize()
 	{
-		super(id, model);
-
-		Args.notNull(converter, "converter");
-		this.converter = converter;
-
-		// Sets the type that will be used when updating the model for this component.
-		setType(LocalTime.class);
-
+		super.onInitialize();
 
 		// Create and add the "hours" TextField
-		add(hoursField = newHoursTextField(HOURS, new HoursModel(), Integer.class));
+		add(hoursField = newHoursTextField("hours", new HoursModel(), Integer.class));
 
 		// Create and add the "minutes" TextField
-		add(minutesField = newMinutesTextField(MINUTES, new MinutesModel(), Integer.class));
-
-		// Create and add the "AM/PM" Listbox
-		add(amOrPmChoice = new DropDownChoice<>(AM_OR_PM_CHOICE, new AmPmModel(), Arrays.asList(AM_PM.values())));
-
-		add(new WebMarkupContainer("hoursSeparator")
-		{
-			private static final long serialVersionUID = 1L;
+		add(minutesField = newMinutesTextField("minutes", new MinutesModel(), Integer.class));
 
+		// Create and add the "AM/PM" choice
+		add(amOrPmChoice = new DropDownChoice<AM_PM>("amOrPmChoice", new AmPmModel(),
+			Arrays.asList(AM_PM.values())) {
 			@Override
-			public boolean isVisible()
+			protected boolean localizeDisplayValues()
 			{
-				return minutesField.determineVisibility();
+				return true;
 			}
 		});
 	}
@@ -289,7 +157,9 @@ public class TimeField extends FormComponentPanel<LocalTime> implements ITextFor
 	 *            the type of the text field
 	 * @return a new text field instance
 	 */
-	protected TextField<Integer> newHoursTextField(final String id, IModel<Integer> model, Class<Integer> type) {
+	protected TextField<Integer> newHoursTextField(final String id, IModel<Integer> model,
+		Class<Integer> type)
+	{
 		TextField<Integer> hoursTextField = new TextField<Integer>(id, model, type)
 		{
 			private static final long serialVersionUID = 1L;
@@ -297,13 +167,22 @@ public class TimeField extends FormComponentPanel<LocalTime> implements ITextFor
 			@Override
 			protected String[] getInputTypes()
 			{
-				return new String[] {"number"};
+				return new String[] { "number" };
+			}
+
+			@Override
+			protected void onComponentTag(ComponentTag tag)
+			{
+				super.onComponentTag(tag);
+
+				tag.append("class", getString(HOURS_CSS_CLASS_KEY), " ");
+
+				tag.put("min", use12HourFormat() ? 1 : 0);
+				tag.put("max", use12HourFormat() ? 12 : 23);
 			}
 		};
-		hoursTextField.add(AttributeModifier.append("min", getMaximumHours() == 24 ? 0 : 1));
-		hoursTextField.add(AttributeModifier.append("max", getMaximumHours() == 24 ? 23 : 12));
-		hoursTextField.add(getMaximumHours() == 24 ? RangeValidator.range(0, 23) : RangeValidator.range(1, 12));
-		hoursTextField.setLabel(new Model<>(HOURS));
+		hoursTextField
+			.add(use12HourFormat() ? RangeValidator.range(1, 12) : RangeValidator.range(0, 23));
 		return hoursTextField;
 	}
 
@@ -338,13 +217,21 @@ public class TimeField extends FormComponentPanel<LocalTime> implements ITextFor
 			@Override
 			protected String[] getInputTypes()
 			{
-				return new String[] {"number"};
+				return new String[] { "number" };
+			}
+
+			@Override
+			protected void onComponentTag(ComponentTag tag)
+			{
+				super.onComponentTag(tag);
+
+				tag.append("class", getString(MINUTES_CSS_CLASS_KEY), " ");
+
+				tag.put("min", 0);
+				tag.put("max", 59);
 			}
 		};
-		minutesField.add(AttributeModifier.append("min", 0));
-		minutesField.add(AttributeModifier.append("max", 59));
 		minutesField.add(new RangeValidator<>(0, 59));
-		minutesField.setLabel(new Model<>(MINUTES));
 		return minutesField;
 	}
 
@@ -363,8 +250,12 @@ public class TimeField extends FormComponentPanel<LocalTime> implements ITextFor
 		Integer minutes = minutesField.getConvertedInput();
 		AM_PM amOrPmInput = amOrPmChoice.getConvertedInput();
 
-		LocalTime localTime = null;
-		if (hours != null && minutes != null)
+		LocalTime localTime;
+		if (hours == null && minutes == null)
+		{
+			localTime = null;
+		}
+		else if (hours != null && minutes != null)
 		{
 			// Use the input to create a LocalTime object
 			localTime = LocalTime.of(hours, minutes);
@@ -376,51 +267,39 @@ public class TimeField extends FormComponentPanel<LocalTime> implements ITextFor
 				localTime = localTime.with(ChronoField.AMPM_OF_DAY, halfday);
 			}
 		}
+		else
+		{
+			error(newValidationError(new ConversionException("Cannot parse time").setTargetType(getType())));
+			return;
+		}
+
 		setConvertedInput(localTime);
 	}
 
 	@Override
-	protected void onBeforeRender() {
+	protected void onConfigure()
+	{
+		super.onConfigure();
+
 		hoursField.setRequired(isRequired());
 		minutesField.setRequired(isRequired());
 
-		boolean use12HourFormat = use12HourFormat();
-		amOrPmChoice.setVisible(use12HourFormat);
-		super.onBeforeRender();
+		amOrPmChoice.setVisible(use12HourFormat());
 	}
 
 	/**
 	 * Checks whether the current {@link Locale} uses the 12h or 24h time format. This method can be
 	 * overridden to e.g. always use 24h format.
 	 * 
-	 * @return true, if the current {@link Locale} uses the 12h format.<br/>
-	 *         false, otherwise
+	 * @return {@value true}, if the current {@link Locale} uses the 12h format.<br/>
+	 *         {@value false}, otherwise
 	 */
 	protected boolean use12HourFormat()
 	{
-		String pattern = DateTimeFormatterBuilder.getLocalizedDateTimePattern(null, FormatStyle.SHORT, IsoChronology.INSTANCE, getLocale());
-		return pattern.indexOf('a') != -1 || pattern.indexOf('h') != -1 || pattern.indexOf('K') != -1;
-	}
-
-	/**
-	 * @return either 12 or 24, depending on the hour format of the current {@link Locale}
-	 */
-	private int getMaximumHours()
-	{
-		return getMaximumHours(use12HourFormat());
-	}
-
-	/**
-	 * Convenience method (mainly for optimization purposes), in case {@link #use12HourFormat()} has
-	 * already been stored in a local variable and thus doesn't need to be computed again.
-	 * 
-	 * @param use12HourFormat
-	 *            the hour format to use
-	 * @return either 12 or 24, depending on the parameter <code>use12HourFormat</code>
-	 */
-	private int getMaximumHours(boolean use12HourFormat)
-	{
-		return use12HourFormat ? 12 : 24;
+		String pattern = DateTimeFormatterBuilder.getLocalizedDateTimePattern(null,
+			FormatStyle.SHORT, IsoChronology.INSTANCE, getLocale());
+		return pattern.indexOf('a') != -1 || pattern.indexOf('h') != -1
+			|| pattern.indexOf('K') != -1;
 	}
 
 	protected class HoursModel implements IModel<Integer>
@@ -435,13 +314,13 @@ public class TimeField extends FormComponentPanel<LocalTime> implements ITextFor
 			{
 				return null;
 			}
-			return getMaximumHours() == 24 ? t.getHour() : t.get(ChronoField.CLOCK_HOUR_OF_AMPM);
+			return use12HourFormat() ? t.get(ChronoField.CLOCK_HOUR_OF_AMPM) : t.getHour();
 		}
 
 		@Override
 		public void setObject(Integer hour)
 		{
-			time = time.with(getMaximumHours() == 24 ? ChronoField.HOUR_OF_DAY : ChronoField.CLOCK_HOUR_OF_AMPM, hour);
+			// ignored
 		}
 	}
 
@@ -459,7 +338,7 @@ public class TimeField extends FormComponentPanel<LocalTime> implements ITextFor
 		@Override
 		public void setObject(Integer minute)
 		{
-			time = time.with(ChronoField.MINUTE_OF_HOUR, minute);
+			// ignored
 		}
 	}
 
@@ -478,43 +357,7 @@ public class TimeField extends FormComponentPanel<LocalTime> implements ITextFor
 		@Override
 		public void setObject(AM_PM amPm)
 		{
-			int i = AM_PM.AM == amPm ? 0 : 1;
-			time = time.with(ChronoField.AMPM_OF_DAY, i);
-		}
-	}
-
-	/**
-	 * @return The specialized converter.
-	 * @see org.apache.wicket.Component#createConverter(java.lang.Class)
-	 */
-	@Override
-	protected IConverter<?> createConverter(Class<?> clazz)
-	{
-		if (LocalTime.class.isAssignableFrom(clazz))
-		{
-			return converter;
-		}
-		return null;
-	}
-
-	/**
-	 * @see org.apache.wicket.markup.html.form.AbstractTextComponent.ITextFormatProvider#getTextFormat()
-	 */
-	@Override
-	public final String getTextFormat()
-	{
-		return converter.getPattern(getLocale());
-	}
-
-	public static FormatStyle parseFormatStyle(char style)
-	{
-		switch (style)
-		{
-			case 'M':
-				return FormatStyle.MEDIUM;
-			case 'S':
-			default:
-				return FormatStyle.SHORT;
+			// ignored
 		}
 	}
-}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/wicket/blob/8567308e/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/ZonedDateTimeConverter.java
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/ZonedDateTimeConverter.java b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/ZonedDateTimeConverter.java
deleted file mode 100644
index 9286f2e..0000000
--- a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/ZonedDateTimeConverter.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * 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.wicket.extensions.markup.html.form.datetime;
-
-import java.time.ZoneId;
-import java.time.ZonedDateTime;
-import java.time.format.DateTimeFormatter;
-import java.util.Locale;
-import java.util.TimeZone;
-
-import org.apache.wicket.Session;
-import org.apache.wicket.core.request.ClientInfo;
-import org.apache.wicket.protocol.http.request.WebClientInfo;
-import org.apache.wicket.util.convert.ConversionException;
-import org.apache.wicket.util.convert.IConverter;
-import org.apache.wicket.util.lang.Args;
-import org.apache.wicket.util.string.Strings;
-
-
-/**
- * Base class for javax.time based date converters. It contains the logic to parse and format,
- * optionally taking the time zone difference between clients and the server into account.
- * <p>
- * Converters of this class are best suited for per-component use.
- * </p>
- * 
- * @author eelcohillenius
- */
-public abstract class ZonedDateTimeConverter implements IConverter<ZonedDateTime>
-{
-	private static final long serialVersionUID = 1L;
-
-	/**
-	 * Whether to apply the time zone difference when interpreting dates.
-	 */
-	private final boolean applyTimeZoneDifference;
-
-	/**
-	 * Construct. <p> When applyTimeZoneDifference is true, the current time is applied on the
-	 * parsed date, and the date will be corrected for the time zone difference between the server
-	 * and the client. For instance, if I'm in Seattle and the server I'm working on is in
-	 * Amsterdam, the server is 9 hours ahead. So, if I'm inputting say 12/24 at a couple of hours
-	 * before midnight, at the server it is already 12/25. If this boolean is true, it will be
-	 * transformed to 12/25, while the client sees 12/24. </p>
-	 * 
-	 * @param applyTimeZoneDifference
-	 *            whether to apply the difference in time zones between client and server
-	 */
-	public ZonedDateTimeConverter(boolean applyTimeZoneDifference)
-	{
-		this.applyTimeZoneDifference = applyTimeZoneDifference;
-	}
-
-	public ZonedDateTime convertToObject(String value, DateTimeFormatter format, Locale locale) {
-		try
-		{
-			// parse date retaining the time of the submission
-			return ZonedDateTime.parse(value, format);
-		}
-		catch (RuntimeException e)
-		{
-			throw newConversionException(e, locale);
-		}
-	}
-
-	@Override
-	public ZonedDateTime convertToObject(String value, Locale locale)
-	{
-		if (Strings.isEmpty(value))
-		{
-			return null;
-		}
-
-		DateTimeFormatter format = getFormat(locale);
-		Args.notNull(format, "format");
-
-		if (applyTimeZoneDifference)
-		{
-			ZoneId zoneId = getClientTimeZone();
-
-			// set time zone for client
-			format = format.withZone(getTimeZone());
-
-			ZonedDateTime dateTime = convertToObject(value, format, locale);
-			// apply the server time zone to the parsed value
-			if (zoneId != null)
-			{
-				dateTime = dateTime.withZoneSameInstant(zoneId);
-			}
-
-			return dateTime;
-		}
-		else
-		{
-			return convertToObject(value, format, locale);
-		}
-	}
-
-	/**
-	 * Creates a ConversionException and sets additional context information to it.
-	 *
-	 * @param cause
-	 *            - {@link RuntimeException} cause
-	 * @param locale
-	 *            - {@link Locale} used to set 'format' variable with localized pattern
-	 * @return {@link ConversionException}
-	 */
-	ConversionException newConversionException(RuntimeException cause, Locale locale)
-	{
-		return new ConversionException(cause)
-				.setVariable("format", getPattern(locale));
-	}
-
-	@Override
-	public String convertToString(ZonedDateTime dateTime, Locale locale)
-	{
-		DateTimeFormatter format = getFormat(locale);
-
-		if (applyTimeZoneDifference)
-		{
-			ZoneId zoneId = getClientTimeZone();
-			if (zoneId != null)
-			{
-				// apply time zone to formatter
-				format = format.withZone(zoneId);
-			}
-		}
-		return format.format(dateTime);
-	}
-
-	/**
-	 * Gets whether to apply the time zone difference when interpreting dates.
-	 * 
-	 * </p> When true, the current time is applied on the parsed date, and the date will be
-	 * corrected for the time zone difference between the server and the client. For instance, if
-	 * I'm in Seattle and the server I'm working on is in Amsterdam, the server is 9 hours ahead.
-	 * So, if I'm inputting say 12/24 at a couple of hours before midnight, at the server it is
-	 * already 12/25. If this boolean is true, it will be transformed to 12/25, while the client
-	 * sees 12/24. </p>
-	 * 
-	 * @return whether to apply the difference in time zones between client and server
-	 */
-	public final boolean getApplyTimeZoneDifference()
-	{
-		return applyTimeZoneDifference;
-	}
-
-	/**
-	 * @param locale
-	 *            The locale used to convert the value
-	 * @return Gets the pattern that is used for printing and parsing
-	 */
-	public abstract String getPattern(Locale locale);
-
-	/**
-	 * Gets the client's time zone.
-	 * 
-	 * @return The client's time zone or null
-	 */
-	protected ZoneId getClientTimeZone()
-	{
-		ClientInfo info = Session.get().getClientInfo();
-		if (info instanceof WebClientInfo)
-		{
-			TimeZone timeZone = ((WebClientInfo) info).getProperties().getTimeZone();
-			return timeZone.toZoneId();
-		}
-		return null;
-	}
-
-	/**
-	 * @param locale
-	 *            The locale used to convert the value
-	 * 
-	 * @return formatter The formatter for the current conversion
-	 */
-	public abstract DateTimeFormatter getFormat(Locale locale);
-
-	/**
-	 * Gets the server time zone. Override this method if you want to fix to a certain time zone,
-	 * regardless of what actual time zone the server is in.
-	 * 
-	 * @return The server time zone
-	 */
-	protected ZoneId getTimeZone()
-	{
-		return ZoneId.systemDefault();
-	}
-}

http://git-wip-us.apache.org/repos/asf/wicket/blob/8567308e/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/ZonedDateTimeField.java
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/ZonedDateTimeField.java b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/ZonedDateTimeField.java
index eb70e12..4b3143d 100644
--- a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/ZonedDateTimeField.java
+++ b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/ZonedDateTimeField.java
@@ -20,53 +20,19 @@ import java.time.LocalDate;
 import java.time.LocalTime;
 import java.time.ZoneId;
 import java.time.ZonedDateTime;
-import java.time.temporal.ChronoField;
-import java.util.Locale;
-import java.util.TimeZone;
 
-import org.apache.wicket.Session;
-import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
-import org.apache.wicket.core.request.ClientInfo;
 import org.apache.wicket.model.IModel;
-import org.apache.wicket.protocol.http.request.WebClientInfo;
 
 /**
- * Works on a {@link java.time.ZonedDateTimeTime} object. Displays a date field and a DatePicker, a field
- * for hours and a field for minutes, and an AM/PM field. The format (12h/24h) of the hours field
- * depends on the time format of this {@link ZonedDateTimeField}'s {@link Locale}, as does the visibility
- * of the AM/PM field (see {@link ZonedDateTimeField#use12HourFormat}).
- * <p>
- * <strong>Ajaxifying the DateTimeField</strong>: If you want to update a DateTimeField with an
- * {@link AjaxFormComponentUpdatingBehavior}, you have to attach it to the contained
- * {@link DateField} by overriding {@link #newDateTextField(String, IModel)} and calling
- * {@link #processInput()}:
- * 
- * <pre>{@code
- *  DateTimeField dateTimeField = new DateTimeField(...) {
- *    protected DateTextField newDateTextField(String id, PropertyModel<Date> dateFieldModel)
- *    {
- *      DateTextField dateField = super.newDateTextField(id, dateFieldModel);     
- *      dateField.add(new AjaxFormComponentUpdatingBehavior("change") {
- *        protected void onUpdate(AjaxRequestTarget target) {
- *          processInput(); // let DateTimeField process input too
- *
- *          ...
- *        }
- *      });
- *      return recorder;
- *    }
- *  }
- * }</pre>
+ * Works on a {@link java.time.ZonedDateTimeTime} object. See {@link AbstractDateTimeField} for
+ * further details.
  * 
  * @author eelcohillenius
- * @see DateField for a variant with just the date field and date picker
  */
 public class ZonedDateTimeField extends AbstractDateTimeField<ZonedDateTime>
 {
 	private static final long serialVersionUID = 1L;
 
-	private ZonedDateTime dateTime = ZonedDateTime.now();
-
 	/**
 	 * Construct.
 	 * 
@@ -92,59 +58,23 @@ public class ZonedDateTimeField extends AbstractDateTimeField<ZonedDateTime>
 	}
 
 	/**
-	 * Gets the client's time zone.
+	 * Creates a zoned date time in the systems default zone.
 	 * 
-	 * @return The client's time zone or null
+	 * @see ZoneId#systemDefault()
 	 */
-	protected ZoneId getClientTimeZone()
-	{
-		ClientInfo info = Session.get().getClientInfo();
-		if (info instanceof WebClientInfo)
-		{
-			TimeZone timeZone = ((WebClientInfo) info).getProperties().getTimeZone();
-			return timeZone != null ? timeZone.toZoneId() : null;
-		}
-		return null;
-	}
-
-	ZonedDateTime performConvert(LocalDate date, LocalTime time) {
-		return ZonedDateTime.of(date, time, getClientTimeZone());
+	protected ZonedDateTime createTemporal(LocalDate date, LocalTime time) {
+		return ZonedDateTime.of(date, time, ZoneId.systemDefault());
 	}
 
 	@Override
-	void prepareObject() {
-		ZonedDateTime modelObject = getModelObject();
-		if (modelObject != null)
-		{
-			// convert date to the client's time zone if we have that info
-			ZoneId zone = getClientTimeZone();
-			if (zone != null)
-			{
-				modelObject = modelObject.withZoneSameInstant(zone);
-			}
-		}
-	}
-
-	LocalDate getLocalDate()
+	protected LocalDate getLocalDate(ZonedDateTime temporal)
 	{
-		return getModelObject() == null ? null : dateTime.toLocalDate();
+		return temporal.toLocalDate();
 	}
 
-	void setLocalDate(LocalDate date)
-	{
-		dateTime = dateTime.with(ChronoField.YEAR, date.getYear())
-				.with(ChronoField.MONTH_OF_YEAR, date.getMonthValue())
-				.with(ChronoField.DAY_OF_YEAR, date.getDayOfMonth());
-	}
-
-	LocalTime getLocalTime()
-	{
-		return getModelObject() == null ? null : dateTime.toLocalTime();
-	}
-
-	void setLocalTime(LocalTime time)
+	@Override
+	protected LocalTime getLocalTime(ZonedDateTime temporal)
 	{
-		dateTime = dateTime.with(ChronoField.HOUR_OF_DAY, time.getHour())
-				.with(ChronoField.MINUTE_OF_HOUR, time.getMinute());
+		return temporal.toLocalTime();
 	}
-}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/wicket/blob/8567308e/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/ZonedToLocalDateTimeModel.java
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/ZonedToLocalDateTimeModel.java b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/ZonedToLocalDateTimeModel.java
new file mode 100644
index 0000000..0fcb79c
--- /dev/null
+++ b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/ZonedToLocalDateTimeModel.java
@@ -0,0 +1,118 @@
+/*
+ * 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.wicket.extensions.markup.html.form.datetime;
+
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.util.TimeZone;
+
+import org.apache.wicket.Session;
+import org.apache.wicket.core.request.ClientInfo;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.protocol.http.request.WebClientInfo;
+import org.apache.wicket.settings.RequestCycleSettings;
+import org.apache.wicket.util.lang.Args;
+
+/**
+ * Model mapping {@link ZonedDateTime} to a {@link LocalDateTime} in {@link #getClientTimeZone()}.
+ * 
+ * @author svenmeier
+ */
+public class ZonedToLocalDateTimeModel implements IModel<LocalDateTime>
+{
+	private IModel<ZonedDateTime> model;
+
+	/**
+	 * Map the given {@link ZonedDateTime} to a {@link LocalDateTime} in the client's time zone.
+	 *  
+	 * @param model zoned date time
+	 */
+	public ZonedToLocalDateTimeModel(IModel<ZonedDateTime> model)
+	{
+		Args.notNull(model, "model");
+		
+		this.model = model;
+	}
+
+	@Override
+	public void detach()
+	{
+		model.detach();
+	}
+
+	/**
+	 * What is the {@link ZoneId} of the client.
+	 * 
+	 * @see RequestCycleSettings#getGatherExtendedBrowserInfo()
+	 * @see ZoneId#systemDefault()
+	 */
+	protected ZoneId getClientTimeZone()
+	{
+		ClientInfo info = Session.get().getClientInfo();
+		if (info instanceof WebClientInfo)
+		{
+			TimeZone timeZone = ((WebClientInfo)info).getProperties().getTimeZone();
+			return timeZone != null ? timeZone.toZoneId() : null;
+		}
+		return ZoneId.systemDefault();
+	}
+
+	/**
+	 * What is the {@link ZoneId} of created {@link ZonedDateTime} objects. 
+	 */
+	protected ZoneId getTargetTimeZone()
+	{
+		return ZoneId.systemDefault();
+	}
+
+	@Override
+	public LocalDateTime getObject()
+	{
+		ZonedDateTime zonedDateTime = model.getObject();
+		if (zonedDateTime == null)
+		{
+			return null;
+		}
+		else
+		{
+			return zonedDateTime.withZoneSameInstant(getClientTimeZone()).toLocalDateTime();
+		}
+	}
+
+	@Override
+	public void setObject(LocalDateTime dateTime)
+	{
+		if (dateTime == null)
+		{
+			model.setObject(null);
+		}
+		else
+		{
+			model.setObject(dateTime.atZone(getClientTimeZone()).withZoneSameInstant(getTargetTimeZone()));
+		}
+	}
+
+	/**
+	 * Convenience factory for a date time.
+	 */
+	public static IModel<LocalDateTime> of(ZonedDateTime dateTime)
+	{
+		return new ZonedToLocalDateTimeModel(new Model<ZonedDateTime>(dateTime));
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/wicket/blob/8567308e/wicket-extensions/src/test/java/org/apache/wicket/extensions/markup/html/form/datetime/DateConverterTest.java
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/test/java/org/apache/wicket/extensions/markup/html/form/datetime/DateConverterTest.java b/wicket-extensions/src/test/java/org/apache/wicket/extensions/markup/html/form/datetime/DateConverterTest.java
deleted file mode 100644
index d590615..0000000
--- a/wicket-extensions/src/test/java/org/apache/wicket/extensions/markup/html/form/datetime/DateConverterTest.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * 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.wicket.extensions.markup.html.form.datetime;
-
-import java.time.ZoneId;
-import java.time.ZonedDateTime;
-import java.time.format.DateTimeFormatter;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.Locale;
-
-import org.apache.wicket.extensions.markup.html.form.datetime.PatternZonedDateTimeConverter;
-import org.apache.wicket.extensions.markup.html.form.datetime.StyleZonedDateTimeConverter;
-import org.apache.wicket.util.convert.ConversionException;
-import org.apache.wicket.util.convert.IConverter;
-import org.apache.wicket.util.convert.converter.CalendarConverter;
-import org.junit.Assert;
-import org.junit.Test;
-
-/**
- * Tests for {@link ZonedDateTimeConverter} and subclasses.
- * 
- * @author akiraly
- */
-public class DateConverterTest
-{
-	/**
-	 * WICKET-3598
-	 */
-	@Test
-	public void testLocaleUsed()
-	{
-		Locale locale = Locale.GERMAN;
-
-		StyleZonedDateTimeConverter styleDateConverter = new StyleZonedDateTimeConverter("F-", false);
-		DateTimeFormatter styleFormatter = styleDateConverter.getFormat(locale);
-
-		Assert.assertEquals(locale, styleFormatter.getLocale());
-
-		PatternZonedDateTimeConverter patternDateConverter = new PatternZonedDateTimeConverter(
-			styleDateConverter.getPattern(locale), false);
-		DateTimeFormatter patternFormatter = patternDateConverter.getFormat(locale);
-
-		Assert.assertEquals(locale, patternFormatter.getLocale());
-
-		Calendar now = Calendar.getInstance();
-
-		ZonedDateTime zNow = ZonedDateTime.ofInstant(now.toInstant(), ZoneId.systemDefault());
-		String actual = styleDateConverter.convertToString(zNow, locale);
-		String expected = patternDateConverter.convertToString(zNow, locale);
-
-		Assert.assertEquals(expected, actual);
-	}
-
-	/**
-	 * WICKET-3658
-	 */
-	@Test
-	public void testCalendarConverterWithDelegate()
-	{
-		Locale locale = Locale.GERMAN;
-
-		Calendar input = Calendar.getInstance(locale);
-		input.clear();
-		input.set(2011, Calendar.MAY, 7);
-
-		final StyleZonedDateTimeConverter styleDateConverter = new StyleZonedDateTimeConverter("F-", false);
-
-		CalendarConverter calendarConverter = new CalendarConverter(new IConverter<Date>()
-		{
-			private static final long serialVersionUID = 1L;
-
-			@Override
-			public Date convertToObject(String value, Locale locale) throws ConversionException {
-				ZonedDateTime zd = styleDateConverter.convertToObject(value, locale);
-				return zd == null ? null : Date.from(zd.toInstant());
-			}
-
-			@Override
-			public String convertToString(Date value, Locale locale) {
-				return styleDateConverter.convertToString(ZonedDateTime.ofInstant(value.toInstant(), ZoneId.systemDefault()), locale);
-			}
-			
-		});
-
-		String expected = styleDateConverter.convertToString(ZonedDateTime.ofInstant(input.toInstant(), ZoneId.systemDefault()), locale);
-		String actual = calendarConverter.convertToString(input, locale);
-
-		Assert.assertEquals(expected, actual);
-
-		Calendar revert = calendarConverter.convertToObject(actual, locale);
-
-		Assert.assertEquals(input, revert);
-	}
-}

http://git-wip-us.apache.org/repos/asf/wicket/blob/8567308e/wicket-extensions/src/test/java/org/apache/wicket/extensions/markup/html/form/datetime/DateTimeFieldTest.java
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/test/java/org/apache/wicket/extensions/markup/html/form/datetime/DateTimeFieldTest.java b/wicket-extensions/src/test/java/org/apache/wicket/extensions/markup/html/form/datetime/DateTimeFieldTest.java
index 753e98e..64efda6 100644
--- a/wicket-extensions/src/test/java/org/apache/wicket/extensions/markup/html/form/datetime/DateTimeFieldTest.java
+++ b/wicket-extensions/src/test/java/org/apache/wicket/extensions/markup/html/form/datetime/DateTimeFieldTest.java
@@ -20,6 +20,7 @@ import java.io.Serializable;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
+import java.time.format.FormatStyle;
 import java.util.Locale;
 
 import org.apache.wicket.MarkupContainer;
@@ -29,6 +30,7 @@ import org.apache.wicket.markup.html.form.Form;
 import org.apache.wicket.markup.html.form.FormComponent;
 import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.Model;
+import org.apache.wicket.util.convert.converter.LocalDateConverter;
 import org.apache.wicket.util.resource.IResourceStream;
 import org.apache.wicket.util.resource.StringResourceStream;
 import org.apache.wicket.util.tester.FormTester;
@@ -98,7 +100,7 @@ public class DateTimeFieldTest extends WicketTestCase {
 		TestDatePage page = new TestDatePage(null);
 		tester.startPage(page);
 		FormTester formTester = tester.newFormTester("form", false);
-		formTester.setValue("field", new StyleDateConverter("F").convertToString(date, Locale.forLanguageTag("en-US")));
+		formTester.setValue("field", new LocalDateConverter().convertToString(date, Locale.forLanguageTag("en-US")));
 		formTester.submit();
 		LocalDate d = page.field.getModelObject();
 		assertNotNull(d);
@@ -120,7 +122,7 @@ public class DateTimeFieldTest extends WicketTestCase {
 		TestDateTimePage page = new TestDateTimePage(null);
 		tester.startPage(page);
 		FormTester formTester = tester.newFormTester("form", false);
-		formTester.setValue("field:date", new StyleDateConverter("F").convertToString(date, Locale.forLanguageTag("en-US")));
+		formTester.setValue("field:date", new LocalDateConverter().convertToString(date, Locale.forLanguageTag("en-US")));
 		formTester.submit();
 		assertNull(page.field.getModelObject());
 	}
@@ -143,7 +145,7 @@ public class DateTimeFieldTest extends WicketTestCase {
 		TestDateTimePage page = new TestDateTimePage(null);
 		tester.startPage(page);
 		FormTester formTester = tester.newFormTester("form", false);
-		formTester.setValue("field:date", new StyleDateConverter("S").convertToString(date, Locale.forLanguageTag("en-US")));
+		formTester.setValue("field:date", new LocalDateConverter().convertToString(date, Locale.forLanguageTag("en-US")));
 		formTester.setValue("field:time:hours", "6");
 		formTester.setValue("field:time:minutes", "15");
 		formTester.select("field:time:amOrPmChoice", 0);
@@ -164,7 +166,7 @@ public class DateTimeFieldTest extends WicketTestCase {
 		@Override
 		FormComponent<LocalDateTime> newComponent()
 		{
-			return new DateTimeField("field", model);
+			return new LocalDateTimeField("field", model);
 		}
 	}
 
@@ -181,7 +183,7 @@ public class DateTimeFieldTest extends WicketTestCase {
 		@Override
 		FormComponent<LocalDate> newComponent()
 		{
-			return DateField.forDateStyle("field", model, "F");
+			return new LocalDateTextField("field", model, FormatStyle.SHORT);
 		}
 	}
 
@@ -197,7 +199,7 @@ public class DateTimeFieldTest extends WicketTestCase {
 		@Override
 		FormComponent<LocalTime> newComponent()
 		{
-			return TimeField.forTimeStyle("field", model, "F");
+			return new TimeField("field", model);
 		}
 	}
 

http://git-wip-us.apache.org/repos/asf/wicket/blob/8567308e/wicket-extensions/src/test/java/org/apache/wicket/extensions/markup/html/form/datetime/ZonedToLocalDateTimeModelTest.java
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/test/java/org/apache/wicket/extensions/markup/html/form/datetime/ZonedToLocalDateTimeModelTest.java b/wicket-extensions/src/test/java/org/apache/wicket/extensions/markup/html/form/datetime/ZonedToLocalDateTimeModelTest.java
new file mode 100644
index 0000000..76caf09
--- /dev/null
+++ b/wicket-extensions/src/test/java/org/apache/wicket/extensions/markup/html/form/datetime/ZonedToLocalDateTimeModelTest.java
@@ -0,0 +1,65 @@
+/*
+ * 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.wicket.extensions.markup.html.form.datetime;
+
+import static org.junit.Assert.assertEquals;
+
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+import org.junit.Test;
+
+/**
+ * Test for {@link ZonedToLocalDateTimeModel}.
+ * 
+ * @author svenmeier
+ */
+public class ZonedToLocalDateTimeModelTest
+{
+
+	@Test
+	public void test() {
+		
+		ZoneId targetZone = ZoneId.of("UTC");
+		ZoneId clientZone = ZoneId.of("UTC+2");
+		
+		IModel<ZonedDateTime> target = Model.of(ZonedDateTime.of(2000, 6, 1, 5, 0, 0, 0, targetZone));
+		
+		ZonedToLocalDateTimeModel client = new ZonedToLocalDateTimeModel(target) {
+			@Override
+			protected ZoneId getTargetTimeZone()
+			{
+				return targetZone;
+			}
+			
+			@Override
+			protected ZoneId getClientTimeZone()
+			{
+				return clientZone;
+			}
+		};
+		
+		assertEquals(LocalDateTime.of(2000, 6, 1, 7, 0, 0, 0), client.getObject());
+		
+		client.setObject(LocalDateTime.of(2000, 6, 1, 7, 30, 0, 0));
+		
+		assertEquals(ZonedDateTime.of(2000, 6, 1, 5, 30, 0, 0, targetZone), target.getObject());
+	}
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/8567308e/wicket-util/src/main/java/org/apache/wicket/util/convert/converter/ZonedDateTimeConverter.java
----------------------------------------------------------------------
diff --git a/wicket-util/src/main/java/org/apache/wicket/util/convert/converter/ZonedDateTimeConverter.java b/wicket-util/src/main/java/org/apache/wicket/util/convert/converter/ZonedDateTimeConverter.java
index 2972b20..dd85a77 100644
--- a/wicket-util/src/main/java/org/apache/wicket/util/convert/converter/ZonedDateTimeConverter.java
+++ b/wicket-util/src/main/java/org/apache/wicket/util/convert/converter/ZonedDateTimeConverter.java
@@ -16,7 +16,6 @@
  */
 package org.apache.wicket.util.convert.converter;
 
-import java.time.ZoneId;
 import java.time.ZonedDateTime;
 import java.time.format.DateTimeFormatter;
 import java.time.format.FormatStyle;
@@ -29,7 +28,7 @@ public class ZonedDateTimeConverter extends AbstractJavaTimeConverter<ZonedDateT
 {
 	private static final long serialVersionUID = 1L;
 
-	private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM);
+	private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM, FormatStyle.FULL);
 
 	@Override
 	protected Class<ZonedDateTime> getTargetType()
@@ -45,6 +44,6 @@ public class ZonedDateTimeConverter extends AbstractJavaTimeConverter<ZonedDateT
 
 	@Override
 	protected DateTimeFormatter getDateTimeFormatter() {
-		return DATE_TIME_FORMATTER.withZone(ZoneId.systemDefault());
+		return DATE_TIME_FORMATTER;
 	}
 }

http://git-wip-us.apache.org/repos/asf/wicket/blob/8567308e/wicket-util/src/test/java/org/apache/wicket/util/convert/converter/ZonedDateTimeConverterTest.java
----------------------------------------------------------------------
diff --git a/wicket-util/src/test/java/org/apache/wicket/util/convert/converter/ZonedDateTimeConverterTest.java b/wicket-util/src/test/java/org/apache/wicket/util/convert/converter/ZonedDateTimeConverterTest.java
index 8d946c5..58a0af9 100644
--- a/wicket-util/src/test/java/org/apache/wicket/util/convert/converter/ZonedDateTimeConverterTest.java
+++ b/wicket-util/src/test/java/org/apache/wicket/util/convert/converter/ZonedDateTimeConverterTest.java
@@ -32,20 +32,19 @@ import org.junit.Test;
  */
 public class ZonedDateTimeConverterTest extends Assert
 {
-	private ZoneId zone = ZoneId.systemDefault();
+	private ZoneId zone = ZoneId.of("UTC");
 
 	@Test
 	public void convertToString() {
 		ZonedDateTimeConverter converter = new ZonedDateTimeConverter();
 		String date = converter.convertToString(ZonedDateTime.of(2016, 7, 11, 1, 2, 3, 0, zone), Locale.ENGLISH);
-		assertThat(date, is(equalTo("Jul 11, 2016 1:02:03 AM")));
+		assertThat(date, is(equalTo("Jul 11, 2016 1:02:03 AM UTC")));
 	}
 
 	@Test
 	public void convertToObject() {
 		ZonedDateTimeConverter converter = new ZonedDateTimeConverter();
-		ZoneId zone = ZoneId.systemDefault();
-		ZonedDateTime date = converter.convertToObject("Jul 11, 2016 1:02:03 AM", Locale.ENGLISH);
+		ZonedDateTime date = converter.convertToObject("Jul 11, 2016 1:02:03 AM UTC", Locale.ENGLISH);
 		assertThat(date, is(equalTo(ZonedDateTime.of(2016, 7, 11, 1, 2, 3, 0, zone))));
 	}
 	


[2/2] wicket git commit: WICKET-6200 restructured, fixed javadoc, removed wrong code

Posted by sv...@apache.org.
WICKET-6200 restructured, fixed javadoc, removed wrong code


Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/8567308e
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/8567308e
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/8567308e

Branch: refs/heads/WICKET-6105-java.time
Commit: 8567308e56d6c4d2c9840daa71775c13fcb0ab81
Parents: 39bbfb9
Author: Sven Meier <sv...@apache.org>
Authored: Fri Oct 13 14:46:22 2017 +0200
Committer: Sven Meier <sv...@apache.org>
Committed: Sun Oct 15 17:51:43 2017 +0200

----------------------------------------------------------------------
 .../org/apache/wicket/ConverterLocator.java     |   3 +
 .../ajax/builtin/modal/ModalContent1Page.java   |   4 +-
 .../ajax/builtin/modal/ModalPanel1.java         |   4 +-
 .../bean/validation/BeanValidationPage.html     |   2 +-
 .../bean/validation/BeanValidationPage.java     |  11 +-
 .../examples/datetime/DateTimeApplication.java  |  12 +-
 .../wicket/examples/datetime/DateTimePage.html  |  53 ++-
 .../wicket/examples/datetime/DateTimePage.java  | 268 +++++++++++--
 .../examples/datetime/DateTimePage.properties   |  17 +
 .../wicket/extensions/Initializer.properties    |   7 +
 .../form/datetime/AbstractDateTimeField.html    |   3 +-
 .../form/datetime/AbstractDateTimeField.java    | 194 +++++++---
 .../markup/html/form/datetime/DateField.java    | 252 -------------
 .../html/form/datetime/DateTimeField.java       | 115 ------
 .../html/form/datetime/LocalDateConverter.java  | 104 ------
 .../html/form/datetime/LocalDateTextField.java  | 163 ++++++++
 .../html/form/datetime/LocalDateTimeField.java  |  74 ++++
 .../form/datetime/LocalDateTimeTextField.java   | 163 ++++++++
 .../html/form/datetime/LocalTimeConverter.java  | 104 ------
 .../html/form/datetime/LocalTimeTextField.java  | 163 ++++++++
 .../form/datetime/PatternDateConverter.java     |  85 -----
 .../form/datetime/PatternTimeConverter.java     |  85 -----
 .../datetime/PatternZonedDateTimeConverter.java |  97 -----
 .../html/form/datetime/StyleDateConverter.java  | 118 ------
 .../html/form/datetime/StyleTimeConverter.java  | 114 ------
 .../datetime/StyleZonedDateTimeConverter.java   | 168 ---------
 .../markup/html/form/datetime/TimeField.html    |   4 +-
 .../markup/html/form/datetime/TimeField.java    | 373 ++++++-------------
 .../form/datetime/ZonedDateTimeConverter.java   | 203 ----------
 .../html/form/datetime/ZonedDateTimeField.java  |  94 +----
 .../datetime/ZonedToLocalDateTimeModel.java     | 118 ++++++
 .../html/form/datetime/DateConverterTest.java   | 109 ------
 .../html/form/datetime/DateTimeFieldTest.java   |  14 +-
 .../datetime/ZonedToLocalDateTimeModelTest.java |  65 ++++
 .../converter/ZonedDateTimeConverter.java       |   5 +-
 .../converter/ZonedDateTimeConverterTest.java   |   7 +-
 36 files changed, 1344 insertions(+), 2031 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/8567308e/wicket-core/src/main/java/org/apache/wicket/ConverterLocator.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/ConverterLocator.java b/wicket-core/src/main/java/org/apache/wicket/ConverterLocator.java
index 373f3cd..dbef956 100644
--- a/wicket-core/src/main/java/org/apache/wicket/ConverterLocator.java
+++ b/wicket-core/src/main/java/org/apache/wicket/ConverterLocator.java
@@ -22,6 +22,7 @@ import java.math.BigInteger;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
+import java.time.ZonedDateTime;
 import java.util.Calendar;
 import java.util.Date;
 import java.util.HashMap;
@@ -48,6 +49,7 @@ import org.apache.wicket.util.convert.converter.ShortConverter;
 import org.apache.wicket.util.convert.converter.SqlDateConverter;
 import org.apache.wicket.util.convert.converter.SqlTimeConverter;
 import org.apache.wicket.util.convert.converter.SqlTimestampConverter;
+import org.apache.wicket.util.convert.converter.ZonedDateTimeConverter;
 import org.apache.wicket.util.lang.Args;
 import org.apache.wicket.util.lang.Objects;
 
@@ -184,6 +186,7 @@ public class ConverterLocator implements IConverterLocator
 		set(LocalDate.class, new LocalDateConverter());
 		set(LocalDateTime.class, new LocalDateTimeConverter());
 		set(LocalTime.class, new LocalTimeConverter());
+		set(ZonedDateTime.class, new ZonedDateTimeConverter());
 	}
 
 	/**

http://git-wip-us.apache.org/repos/asf/wicket/blob/8567308e/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/modal/ModalContent1Page.java
----------------------------------------------------------------------
diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/modal/ModalContent1Page.java b/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/modal/ModalContent1Page.java
index 5c252e4..94ba192 100644
--- a/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/modal/ModalContent1Page.java
+++ b/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/modal/ModalContent1Page.java
@@ -20,7 +20,7 @@ import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.markup.html.AjaxLink;
 import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
-import org.apache.wicket.extensions.markup.html.form.datetime.DateTimeField;
+import org.apache.wicket.extensions.markup.html.form.datetime.LocalDateTimeField;
 import org.apache.wicket.markup.html.WebPage;
 
 
@@ -65,7 +65,7 @@ public class ModalContent1Page extends WebPage
 			}
 		});
 
-		add(new DateTimeField("dateTimeField"));
+		add(new LocalDateTimeField("dateTimeField"));
 
 		final ModalWindow modal;
 		add(modal = new ModalWindow("modal"));

http://git-wip-us.apache.org/repos/asf/wicket/blob/8567308e/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/modal/ModalPanel1.java
----------------------------------------------------------------------
diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/modal/ModalPanel1.java b/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/modal/ModalPanel1.java
index 3a9389a..884077c 100644
--- a/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/modal/ModalPanel1.java
+++ b/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/modal/ModalPanel1.java
@@ -16,7 +16,7 @@
  */
 package org.apache.wicket.examples.ajax.builtin.modal;
 
-import org.apache.wicket.extensions.markup.html.form.datetime.DateTimeField;
+import org.apache.wicket.extensions.markup.html.form.datetime.LocalDateTimeField;
 import org.apache.wicket.markup.html.panel.Panel;
 
 /**
@@ -32,6 +32,6 @@ public class ModalPanel1 extends Panel
 	public ModalPanel1(String id)
 	{
 		super(id);
-		add(new DateTimeField("dateTimeField"));
+		add(new LocalDateTimeField("dateTimeField"));
 	}
 }

http://git-wip-us.apache.org/repos/asf/wicket/blob/8567308e/wicket-examples/src/main/java/org/apache/wicket/examples/bean/validation/BeanValidationPage.html
----------------------------------------------------------------------
diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/bean/validation/BeanValidationPage.html b/wicket-examples/src/main/java/org/apache/wicket/examples/bean/validation/BeanValidationPage.html
index db04a1c..7b5f6fa 100644
--- a/wicket-examples/src/main/java/org/apache/wicket/examples/bean/validation/BeanValidationPage.html
+++ b/wicket-examples/src/main/java/org/apache/wicket/examples/bean/validation/BeanValidationPage.html
@@ -34,7 +34,7 @@
 			<tr>
 				<td><label wicket:for="birthdate"><wicket:label>Birthdate</wicket:label></label></td>
 				<td><input wicket:id="birthdate" type="text" size="10"/></td>
-				<td><pre class="note">m/d/yyyy field with @Past</pre></td>
+				<td><pre class="note"><span wicket:id="pattern" /> field with @Past</pre></td>
 			</tr>
 			<tr>
 				<td><label wicket:for="password"><wicket:label>Password</wicket:label></label></td>

http://git-wip-us.apache.org/repos/asf/wicket/blob/8567308e/wicket-examples/src/main/java/org/apache/wicket/examples/bean/validation/BeanValidationPage.java
----------------------------------------------------------------------
diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/bean/validation/BeanValidationPage.java b/wicket-examples/src/main/java/org/apache/wicket/examples/bean/validation/BeanValidationPage.java
index e1eb59d..3173867 100644
--- a/wicket-examples/src/main/java/org/apache/wicket/examples/bean/validation/BeanValidationPage.java
+++ b/wicket-examples/src/main/java/org/apache/wicket/examples/bean/validation/BeanValidationPage.java
@@ -16,12 +16,14 @@
  */
 package org.apache.wicket.examples.bean.validation;
 
+import java.time.format.FormatStyle;
+
 import org.apache.wicket.bean.validation.PropertyValidator;
-import org.apache.wicket.extensions.markup.html.form.datetime.DateField;
-import org.apache.wicket.extensions.markup.html.form.datetime.StyleDateConverter;
 import org.apache.wicket.examples.WicketExamplePage;
+import org.apache.wicket.extensions.markup.html.form.datetime.LocalDateTextField;
 import org.apache.wicket.feedback.ExactLevelFeedbackMessageFilter;
 import org.apache.wicket.feedback.FeedbackMessage;
+import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.markup.html.form.Form;
 import org.apache.wicket.markup.html.form.TextField;
 import org.apache.wicket.markup.html.panel.FeedbackPanel;
@@ -52,8 +54,9 @@ public class BeanValidationPage extends WicketExamplePage
 		form.add(new TextField<>("name", new PropertyModel<String>(this, "person.name")).add(new PropertyValidator<>()));
 		form.add(new TextField<>("phone", new PropertyModel<String>(this, "person.phone")).add(new PropertyValidator<>()));
 		form.add(new TextField<>("email", new PropertyModel<String>(this, "person.email")).add(new PropertyValidator<>()));
-		form.add(new DateField("birthdate", new PropertyModel<>(this, "person.birthdate"),
-			new StyleDateConverter("S-")).add(new PropertyValidator<>()));
+		LocalDateTextField dateField = new LocalDateTextField("birthdate", new PropertyModel<>(this, "person.birthdate"), FormatStyle.SHORT);
+		form.add(dateField.add(new PropertyValidator<>()));
+		form.add(new Label("pattern", new PropertyModel<>(dateField, "textFormat")));
 		form.add(new TextField<>("password", new PropertyModel<String>(this, "person.password")).add(new PropertyValidator<>()));
 		
 		add(new FeedbackPanel("feedbackSuccess", new ExactLevelFeedbackMessageFilter(FeedbackMessage.INFO)));

http://git-wip-us.apache.org/repos/asf/wicket/blob/8567308e/wicket-examples/src/main/java/org/apache/wicket/examples/datetime/DateTimeApplication.java
----------------------------------------------------------------------
diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/datetime/DateTimeApplication.java b/wicket-examples/src/main/java/org/apache/wicket/examples/datetime/DateTimeApplication.java
index 7dc4282..713f5b7 100644
--- a/wicket-examples/src/main/java/org/apache/wicket/examples/datetime/DateTimeApplication.java
+++ b/wicket-examples/src/main/java/org/apache/wicket/examples/datetime/DateTimeApplication.java
@@ -26,8 +26,16 @@ import org.apache.wicket.examples.WicketExampleApplication;
 public class DateTimeApplication extends WicketExampleApplication
 {
 	@Override
+	protected void init()
+	{
+		super.init();
+		
+		getRequestCycleSettings().setGatherExtendedBrowserInfo(true);
+	}
+
+	@Override
 	public Class< ? extends Page> getHomePage()
 	{
 		return DateTimePage.class;
-	}
-}
+	}	
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/wicket/blob/8567308e/wicket-examples/src/main/java/org/apache/wicket/examples/datetime/DateTimePage.html
----------------------------------------------------------------------
diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/datetime/DateTimePage.html b/wicket-examples/src/main/java/org/apache/wicket/examples/datetime/DateTimePage.html
index eed5878..2589935 100644
--- a/wicket-examples/src/main/java/org/apache/wicket/examples/datetime/DateTimePage.html
+++ b/wicket-examples/src/main/java/org/apache/wicket/examples/datetime/DateTimePage.html
@@ -9,26 +9,51 @@
 	<body>
 		<span wicket:id="mainNavigation" />
 
-		<h3>Demo for short style time</h3>
-		<span wicket:id="time1"></span><br/>
-
-		<hr/>
+		<form wicket:id="form">
+		 	 <div>
+		 	 	<wicket:message key="locale"></wicket:message>
+				<select wicket:id="localeSelect"></select>
+				<a href="#" wicket:id="defaultLocaleLink">[<wicket:message key="default" />]</a>
+     		</div>
+		
+			<hr/>
+		
+			<h3>TimeField 12-hours</h3>
+			<span wicket:id="time1"></span><br/>
+	
+			<hr/>
+	
+			<h3>TimeField 24-hours</h3>
+			<span wicket:id="time2"></span><br/>
+	
+			<hr/>
 
-		<h3>Demo for Full style time</h3>
-		<span wicket:id="time2"></span><br/>
+			<h3>LocalDateTimeField (default time 00:00)</h3>
+			<span wicket:id="datetime0"></span><br/>
 
-		<hr/>
+			<hr/>
 
-		<h3>Demo for Short style time with 24-hours</h3>
-		<span wicket:id="time3"></span><br/>
+	 	 	<wicket:message key="clientZone"></wicket:message>
+			<select wicket:id="zoneSelect"></select>
+			<br/>
+			
+			<h3>LocalDateTimeField with a ZonedDateTime (<span wicket:id="datetime1-label" />) adjusted to client's time zone</h3>
+			<span wicket:id="datetime1"></span>
+			<br/>
 
-		<hr/>
+			<h3>LocalDateTimeTextField with a ZonedDateTime (<span wicket:id="datetime2-label" />) adjusted to client's time zone</h3>
+			<input wicket:id="datetime2" type="text" />
+			<br/>
+			
+			<h3>ZonedDateTimeField</h3>
+			<span wicket:id="datetime3"></span>
+			<br/>
+			
+			<hr/>
 
-		<form wicket:id="form">
-			<h3>Demo for default Local Date Time in Form</h3>
-			<span wicket:id="datetime1"></span><br/>
-			<input wicket:id="submit" type="submit" value="Submit"/>
 			<div wicket:id="feedback"></div>
+			
+			<input wicket:id="submit" type="submit" value="Submit"/>
 		</form>
 	</body>
 </html>

http://git-wip-us.apache.org/repos/asf/wicket/blob/8567308e/wicket-examples/src/main/java/org/apache/wicket/examples/datetime/DateTimePage.java
----------------------------------------------------------------------
diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/datetime/DateTimePage.java b/wicket-examples/src/main/java/org/apache/wicket/examples/datetime/DateTimePage.java
index 6294863..b102c2e 100644
--- a/wicket-examples/src/main/java/org/apache/wicket/examples/datetime/DateTimePage.java
+++ b/wicket-examples/src/main/java/org/apache/wicket/examples/datetime/DateTimePage.java
@@ -18,16 +18,36 @@ package org.apache.wicket.examples.datetime;
 
 import java.time.LocalDateTime;
 import java.time.LocalTime;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.time.format.FormatStyle;
+import java.time.format.TextStyle;
+import java.util.List;
+import java.util.Locale;
+import java.util.stream.Collectors;
 
-import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.ajax.markup.html.form.AjaxButton;
+import org.apache.wicket.Session;
 import org.apache.wicket.examples.WicketExamplePage;
-import org.apache.wicket.extensions.markup.html.form.datetime.DateTimeField;
-import org.apache.wicket.extensions.markup.html.form.datetime.StyleTimeConverter;
+import org.apache.wicket.examples.forminput.FormInputApplication;
+import org.apache.wicket.extensions.markup.html.form.datetime.LocalDateTimeField;
+import org.apache.wicket.extensions.markup.html.form.datetime.LocalDateTimeTextField;
 import org.apache.wicket.extensions.markup.html.form.datetime.TimeField;
+import org.apache.wicket.extensions.markup.html.form.datetime.ZonedDateTimeField;
+import org.apache.wicket.extensions.markup.html.form.datetime.ZonedToLocalDateTimeModel;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.form.Button;
+import org.apache.wicket.markup.html.form.ChoiceRenderer;
+import org.apache.wicket.markup.html.form.DropDownChoice;
 import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.form.FormComponentUpdatingBehavior;
+import org.apache.wicket.markup.html.form.IChoiceRenderer;
+import org.apache.wicket.markup.html.link.Link;
 import org.apache.wicket.markup.html.panel.FeedbackPanel;
-import org.apache.wicket.model.Model;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.PropertyModel;
+import org.apache.wicket.protocol.http.request.WebClientInfo;
+import org.apache.wicket.request.http.WebRequest;
 
 /**
  * DateTime example page.
@@ -37,43 +57,231 @@ public class DateTimePage extends WicketExamplePage
 {
 	private static final long serialVersionUID = 1L;
 
+	private ZoneId clientZone;
+
+	private ZoneId targetZone = ZoneId.of("UTC+8");
+
+	@SuppressWarnings("unused")
+	private LocalTime time1 = LocalTime.of(22, 15);
+
+	@SuppressWarnings("unused")
+	private LocalTime time2 = LocalTime.of(22, 15);
+
+	@SuppressWarnings("unused")
+	private LocalDateTime dateTime0 = LocalDateTime.now();
+
+	@SuppressWarnings("unused")
+	private ZonedDateTime dateTime1 = LocalDateTime.now().atZone(targetZone);
+
+	@SuppressWarnings("unused")
+	private ZonedDateTime dateTime2 = LocalDateTime.now().atZone(targetZone);
+
+	@SuppressWarnings("unused")
+	private ZonedDateTime dateTime3 = ZonedDateTime.now();
+
 	/**
 	 * Constructor.
 	 */
 	public DateTimePage()
 	{
-		add(TimeField.forShortStyle("time1", Model.of(LocalTime.of(22, 15))));
-		add(TimeField.forTimeStyle("time2", Model.of(LocalTime.of(22, 15)), "F"));
-		add(new TimeField("time3", Model.of(LocalTime.of(22, 15)), new StyleTimeConverter("S")) {
+		Form<String> form = new Form<>("form");
+		this.add(form);
+
+		form.add(new ZoneDropDownChoice("zoneSelect"));
+
+		// Dropdown for selecting locale
+		form.add(new LocaleDropDownChoice("localeSelect"));
+
+		// Link to return to default locale
+		form.add(new Link<Void>("defaultLocaleLink")
+		{
+			public void onClick()
+			{
+				WebRequest request = (WebRequest)getRequest();
+				getSession().setLocale(request.getLocale());
+			}
+		});
+
+		form.add(new TimeField("time1", new PropertyModel<>(this, "time1"))
+		{
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			protected boolean use12HourFormat()
+			{
+				return true;
+			}
+		});
+
+		form.add(new TimeField("time2", new PropertyModel<>(this, "time2"))
+		{
 			private static final long serialVersionUID = 1L;
 
 			@Override
-			protected boolean use12HourFormat() {
+			protected boolean use12HourFormat()
+			{
 				return false;
 			}
 		});
-		final DateTimeField datetime1 = new DateTimeField("datetime1", Model.of(LocalDateTime.now()));
+
+		final LocalDateTimeField datetimeField0 = new LocalDateTimeField("datetime0",
+			new PropertyModel<>(this, "dateTime0"))
+		{
+			@Override
+			protected LocalTime getDefaultTime()
+			{
+				return LocalTime.of(0, 0);
+			}
+		};
+		form.add(datetimeField0);
+
+		IModel<ZonedDateTime> zonedDateTime1 = new PropertyModel<>(this, "dateTime1");
+		final LocalDateTimeField datetimeField1 = new LocalDateTimeField("datetime1",
+			new ZonedToLocalDateTimeModel(zonedDateTime1)
+			{
+				@Override
+				protected ZoneId getClientTimeZone()
+				{
+					return clientZone;
+				}
+
+				@Override
+				protected ZoneId getTargetTimeZone()
+				{
+					return targetZone;
+				}
+			});
+		form.add(datetimeField1);
+		form.add(new Label("datetime1-label", zonedDateTime1));
+
+		IModel<ZonedDateTime> zonedDateTime2 = new PropertyModel<>(this, "dateTime2");
+		LocalDateTimeTextField datetime2 = new LocalDateTimeTextField("datetime2",
+			new ZonedToLocalDateTimeModel(zonedDateTime2)
+			{
+				@Override
+				protected ZoneId getClientTimeZone()
+				{
+					return clientZone;
+				}
+
+				@Override
+				protected ZoneId getTargetTimeZone()
+				{
+					return targetZone;
+				}
+			}, FormatStyle.SHORT, FormatStyle.SHORT);
+		form.add(datetime2);
+		form.add(new Label("datetime2-label", zonedDateTime2));
+
+		final ZonedDateTimeField datetimeField3 = new ZonedDateTimeField("datetime3",
+			new PropertyModel<>(this, "dateTime3"));
+		form.add(datetimeField3);
+
 		final FeedbackPanel feedback = new FeedbackPanel("feedback");
-		Form<String> form = new Form<>("form");
-		add(form.add(datetime1)
-				.add(feedback.setOutputMarkupId(true))
-				.add(new AjaxButton("submit")
+		form.add(feedback);
+
+		form.add(new Button("submit"));
+	}
+
+	@Override
+	protected void onInitialize()
+	{
+		super.onInitialize();
+
+		clientZone = ((WebClientInfo)Session.get().getClientInfo()).getProperties().getTimeZone()
+			.toZoneId();
+	}
+
+	/**
+	 * Choice for a locale.
+	 */
+	private final class LocaleChoiceRenderer extends ChoiceRenderer<Locale>
+	{
+		@Override
+		public Object getDisplayValue(Locale locale)
+		{
+			return locale.getDisplayName(getLocale());
+		}
+	}
+
+	/**
+	 * Dropdown with Locales.
+	 */
+	private final class LocaleDropDownChoice extends DropDownChoice<Locale>
+	{
+		/**
+		 * Construct.
+		 * 
+		 * @param id
+		 *            component id
+		 */
+		public LocaleDropDownChoice(String id)
+		{
+			super(id, FormInputApplication.LOCALES, new LocaleChoiceRenderer());
+
+			setModel(new PropertyModel<>(this, "session.locale"));
+
+			add(new FormComponentUpdatingBehavior()
+			{
+				@Override
+				protected void onUpdate()
+				{
+					setResponsePage(getPage().getClass());
+				}
+			});
+		}
+	}
+
+	private class ZoneDropDownChoice extends DropDownChoice<ZoneId>
+	{
+
+		public ZoneDropDownChoice(String id)
+		{
+			super(id, new IModel<List<ZoneId>>()
+			{
+				@Override
+				public List<ZoneId> getObject()
+				{
+					return ZoneId.getAvailableZoneIds().stream().map(id -> ZoneId.of(id))
+						.collect(Collectors.toList());
+				}
+			});
+
+			setModel(new PropertyModel<ZoneId>(DateTimePage.this, "clientZone"));
+
+			setChoiceRenderer(new IChoiceRenderer<ZoneId>()
+			{
+				@Override
+				public Object getDisplayValue(ZoneId object)
+				{
+					String name = object.getDisplayName(TextStyle.FULL, getLocale());
+
+					ZoneOffset offset = LocalDateTime.now().atZone(object).getOffset();
+
+					return name + offset;
+				}
+
+				@Override
+				public String getIdValue(ZoneId object, int index)
+				{
+					return object.getId();
+				}
+
+				@Override
+				public ZoneId getObject(String id, IModel<? extends List<? extends ZoneId>> choices)
+				{
+					return ZoneId.of(id);
+				}
+			});
+
+			add(new FormComponentUpdatingBehavior()
+			{
+				protected void onUpdate()
 				{
-					private static final long serialVersionUID = 1L;
-
-					@Override
-					protected void onSubmit(AjaxRequestTarget target)
-					{
-						form.info(String.format("DateTime was just submitted: %s", datetime1.getModelObject()));
-						target.add(feedback);
-					}
-
-					@Override
-					protected void onError(AjaxRequestTarget target)
-					{
-						target.add(feedback);
-					}
-				})
-			);
+					// clear raw input of all inputs so that values are reformatted
+					getForm().clearInput();
+				};
+			});
+		}
 	}
 }

http://git-wip-us.apache.org/repos/asf/wicket/blob/8567308e/wicket-examples/src/main/java/org/apache/wicket/examples/datetime/DateTimePage.properties
----------------------------------------------------------------------
diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/datetime/DateTimePage.properties b/wicket-examples/src/main/java/org/apache/wicket/examples/datetime/DateTimePage.properties
new file mode 100644
index 0000000..6a4447b
--- /dev/null
+++ b/wicket-examples/src/main/java/org/apache/wicket/examples/datetime/DateTimePage.properties
@@ -0,0 +1,17 @@
+#  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.
+locale=Locale
+default=default
+clientZone=Client timezone

http://git-wip-us.apache.org/repos/asf/wicket/blob/8567308e/wicket-extensions/src/main/java/org/apache/wicket/extensions/Initializer.properties
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/Initializer.properties b/wicket-extensions/src/main/java/org/apache/wicket/extensions/Initializer.properties
index 326f2a7..b9a7819 100644
--- a/wicket-extensions/src/main/java/org/apache/wicket/extensions/Initializer.properties
+++ b/wicket-extensions/src/main/java/org/apache/wicket/extensions/Initializer.properties
@@ -38,3 +38,10 @@ Folder.CSS.other=tree-folder-other
 Folder.CSS.closed=tree-folder-closed
 Folder.CSS.open=tree-folder-open
 Folder.CSS.selected=selected
+
+AbstractDateTimeField.timeSeparator=\u00a0-\u00a0 
+AbstractDateTimeField.CSS.date=datetime-date
+AbstractDateTimeField.CSS.time=datetime-time
+TimeField.hoursSeparator=\u00a0:\u00a0
+TimeField.CSS.hours=time-hours
+TimeField.CSS.minutes=time-minutes
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/wicket/blob/8567308e/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/AbstractDateTimeField.html
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/AbstractDateTimeField.html b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/AbstractDateTimeField.html
index d92f2ce..3230a08 100644
--- a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/AbstractDateTimeField.html
+++ b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/AbstractDateTimeField.html
@@ -16,8 +16,9 @@
    limitations under the License.
 -->
 <wicket:panel xmlns:wicket="http://wicket.apache.org">
-  <span style="white-space: nowrap;">
+  <span>
     <input type="text" wicket:id="date" size="12" />
+    <span wicket:id="timeSeparator"> - </span>
     <span wicket:id="time" />
   </span>
 </wicket:panel>

http://git-wip-us.apache.org/repos/asf/wicket/blob/8567308e/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/AbstractDateTimeField.java
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/AbstractDateTimeField.java b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/AbstractDateTimeField.java
index 8b6f85d..2f86c19 100644
--- a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/AbstractDateTimeField.java
+++ b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/AbstractDateTimeField.java
@@ -18,24 +18,25 @@ package org.apache.wicket.extensions.markup.html.form.datetime;
 
 import java.time.LocalDate;
 import java.time.LocalTime;
+import java.time.format.FormatStyle;
 import java.time.temporal.Temporal;
 import java.util.Date;
-import java.util.Locale;
 
 import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
+import org.apache.wicket.core.util.string.CssUtils;
+import org.apache.wicket.markup.ComponentTag;
+import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.markup.html.form.FormComponentPanel;
 import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.ResourceModel;
+import org.apache.wicket.util.convert.ConversionException;
 
 /**
- * Works on a {@link java.time.ZonedDateTime} object. Displays a date field and a DatePicker, a field
- * for hours and a field for minutes, and an AM/PM field. The format (12h/24h) of the hours field
- * depends on the time format of this {@link AbstractDateTimeField}'s {@link Locale}, as does the visibility
- * of the AM/PM field (see {@link AbstractDateTimeField#use12HourFormat}).
+ * Works on a {@link java.time.Temporal} object, aggregating a {@link LocalDateTextField} and a {@link TimeField}.
  * <p>
- * <strong>Ajaxifying the DateTimeField</strong>: If you want to update a DateTimeField with an
- * {@link AjaxFormComponentUpdatingBehavior}, you have to attach it to the contained
- * {@link DateField} by overriding {@link #newDateTextField(String, IModel)} and calling
- * {@link #processInput()}:
+ * <strong>Ajaxifying an AbstractDateTimeField</strong>:
+ * If you want to update this component with an {@link AjaxFormComponentUpdatingBehavior}, you have to attach it
+ * to the contained components by overriding {@link #newDateTextField(String, IModel)}:
  * 
  * <pre>{@code
  *  DateTimeField dateTimeField = new DateTimeField(...) {
@@ -55,19 +56,17 @@ import org.apache.wicket.model.IModel;
  * }</pre>
  * 
  * @author eelcohillenius
- * @see DateField for a variant with just the date field and date picker
  */
 abstract class AbstractDateTimeField<T extends Temporal> extends FormComponentPanel<T>
 {
 	private static final long serialVersionUID = 1L;
 
-	// Component-IDs
-	protected static final String DATE = "date";
-	protected static final String TIME = "time";
+	public static final String DATE_CSS_CLASS_KEY = CssUtils.key(AbstractDateTimeField.class, "date");
 
-	// The date TextField and it's associated model object
-	// Note that any time information in date will be ignored
-	private DateField dateField;
+	public static final String TIME_CSS_CLASS_KEY = CssUtils.key(AbstractDateTimeField.class, "time");
+
+	private LocalDateTextField localDateField;
+	
 	private TimeField timeField;
 
 	/**
@@ -90,18 +89,38 @@ abstract class AbstractDateTimeField<T extends Temporal> extends FormComponentPa
 	{
 		super(id, model);
 
-		// Create and add the date TextField
-		add(dateField = newDateField(DATE, new DateModel()));
-		add(timeField = newTimeField(TIME, new TimeModel()));
+		add(new Label("timeSeparator", new ResourceModel("AbstractDateTimeField.timeSeparator"))
+		{
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			protected void onConfigure()
+			{
+				super.onConfigure();
+
+				timeField.configure();
+				
+				setVisible(timeField.isVisible());
+			}
+		});
+	}
+	
+	@Override
+	protected void onInitialize()
+	{
+		super.onInitialize();
+		
+		add(localDateField = newDateField("date", new DateModel()));
+		add(timeField = newTimeField("time", new TimeModel()));
 	}
 
 	/**
 	 * 
 	 * @return The date TextField
 	 */
-	protected final DateField getDateField()
+	protected final LocalDateTextField getDateField()
 	{
-		return dateField;
+		return localDateField;
 	}
 
 	/**
@@ -118,7 +137,7 @@ abstract class AbstractDateTimeField<T extends Temporal> extends FormComponentPa
 	{
 		// since we override convertInput, we can let this method return a value
 		// that is just suitable for error reporting
-		return String.format("%s, %s", dateField.getInput(), timeField.getInput());
+		return String.format("%s, %s", localDateField.getInput(), timeField.getInput());
 	}
 
 	/**
@@ -134,47 +153,68 @@ abstract class AbstractDateTimeField<T extends Temporal> extends FormComponentPa
 	@Override
 	public void convertInput()
 	{
-		try
-		{
-			// Get the converted input values
-			LocalDate date = dateField.getConvertedInput();
-			LocalTime time = timeField.getConvertedInput();
+		// Get the converted input values
+		LocalDate date = localDateField.getConvertedInput();
+		LocalTime time = timeField.getConvertedInput();
 
-			if (date == null || time == null)
+		T temporal;
+		if (date == null && time == null)
+		{
+			temporal = null;
+		}
+		else
+		{
+			if (date == null)
 			{
-				setConvertedInput(null);
+				error(newValidationError(new ConversionException("Cannot create temporal without date").setTargetType(getType())));
+				return;
 			}
-			else
+			if (time == null)
 			{
-				// Use the input to create proper date-time
-				setConvertedInput(performConvert(date, time));
+				time = getDefaultTime();
+				if (time == null) {
+					error(newValidationError(new ConversionException("Cannot create temporal without time").setTargetType(getType())));
+					return;
+				}
 			}
+			
+			// Use the input to create proper date-time
+			temporal = createTemporal(date, time);
 		}
-		catch (RuntimeException e)
-		{
-			AbstractDateTimeField.this.error(e.getMessage());
-			invalid();
-		}
+		
+		setConvertedInput(temporal);
 	}
 
-	abstract T performConvert(LocalDate date, LocalTime time);
-
-	void prepareObject() {
-		// no-op by default
+	/**
+	 * Get a default time if none was entered.
+	 * 
+	 * @return {@value null} by default
+	 */
+	protected LocalTime getDefaultTime()
+	{
+		return null;
 	}
 
 	/**
-	 * create a new {@link DateField} instance to be added to this panel.
+	 * create a new {@link LocalDateTextField} instance to be added to this panel.
 	 * 
 	 * @param id
 	 *            the component id
 	 * @param dateFieldModel
-	 *            model that should be used by the {@link DateField}
+	 *            model that should be used by the {@link LocalDateTextField}
 	 * @return a new date text field instance
 	 */
-	protected DateField newDateField(String id, IModel<LocalDate> dateFieldModel)
+	protected LocalDateTextField newDateField(String id, IModel<LocalDate> dateFieldModel)
 	{
-		return DateField.forShortStyle(id, dateFieldModel);
+		return new LocalDateTextField(id, dateFieldModel, FormatStyle.SHORT) {
+			@Override
+			protected void onComponentTag(ComponentTag tag)
+			{
+				super.onComponentTag(tag);
+				
+				tag.append("class", getString(DATE_CSS_CLASS_KEY), " ");
+			}
+		};
 	}
 
 	/**
@@ -188,7 +228,15 @@ abstract class AbstractDateTimeField<T extends Temporal> extends FormComponentPa
 	 */
 	protected TimeField newTimeField(String id, IModel<LocalTime> timeFieldModel)
 	{
-		return TimeField.forShortStyle(id, timeFieldModel);
+		return new TimeField(id, timeFieldModel) {
+			@Override
+			protected void onComponentTag(ComponentTag tag)
+			{
+				super.onComponentTag(tag);
+				
+				tag.append("class", getString(TIME_CSS_CLASS_KEY), " ");
+			}
+		};
 	}
 
 	/**
@@ -197,50 +245,78 @@ abstract class AbstractDateTimeField<T extends Temporal> extends FormComponentPa
 	@Override
 	protected void onBeforeRender()
 	{
-		dateField.setRequired(isRequired());
+		localDateField.setRequired(isRequired());
 		timeField.setRequired(isRequired());
 
-		prepareObject();
-
 		super.onBeforeRender();
 	}
 
-	abstract LocalDate getLocalDate();
-	abstract void setLocalDate(LocalDate date);
-	abstract LocalTime getLocalTime();
-	abstract void setLocalTime(LocalTime time);
+	/**
+	 * Get the local date from the given temporal.
+	 * 
+	 * @param temporal
+	 * @return local date
+	 */
+	protected abstract LocalDate getLocalDate(T temporal);
 
-	protected class DateModel implements IModel<LocalDate>
+	/**
+	 * Get the time from the given temporal.
+	 * 
+	 * @param temporal
+	 * @return time
+	 */
+	protected abstract LocalTime getLocalTime(T temporal);
+
+	/**
+	 * Create the temporal object from date and time. 
+	 * 
+	 * @param date
+	 * @param time
+	 * @return
+	 */
+	protected abstract T createTemporal(LocalDate date, LocalTime time);
+
+	private class DateModel implements IModel<LocalDate>
 	{
 		private static final long serialVersionUID = 1L;
 
 		@Override
 		public LocalDate getObject()
 		{
-			return getLocalDate();
+			T temporal = getModelObject();
+			if (temporal == null) {
+				return null;
+			}
+			
+			return getLocalDate(temporal);
 		}
 
 		@Override
 		public void setObject(LocalDate date)
 		{
-			setLocalDate(date);
+			// ignored
 		}
 	}
 
-	protected class TimeModel implements IModel<LocalTime>
+	private class TimeModel implements IModel<LocalTime>
 	{
 		private static final long serialVersionUID = 1L;
 
 		@Override
 		public LocalTime getObject()
 		{
-			return getLocalTime();
+			T temporal = getModelObject();
+			if (temporal == null) {
+				return null;
+			}
+			
+			return getLocalTime(temporal);
 		}
 
 		@Override
 		public void setObject(LocalTime time)
 		{
-			setLocalTime(time);
+			// ignored
 		}
 	}
 }

http://git-wip-us.apache.org/repos/asf/wicket/blob/8567308e/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/DateField.java
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/DateField.java b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/DateField.java
deleted file mode 100644
index 895c0c6..0000000
--- a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/DateField.java
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * 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.wicket.extensions.markup.html.form.datetime;
-
-import java.text.SimpleDateFormat;
-import java.time.LocalDate;
-import java.time.format.FormatStyle;
-
-import org.apache.wicket.markup.html.form.AbstractTextComponent.ITextFormatProvider;
-import org.apache.wicket.markup.html.form.TextField;
-import org.apache.wicket.model.IModel;
-import org.apache.wicket.util.convert.IConverter;
-import org.apache.wicket.util.lang.Args;
-
-/**
- * A TextField that is mapped to a <code>java.time.LocalDate</code> object and that uses java.time time to
- * parse and format values.
- * <p>
- * You should use on of the factory methods to construct the kind you want or use the public
- * constructor and pass in the converter to use.
- * </p>
- * <p>
- * This component tries to apply the time zone difference between the client and server. See the
- * {@link ZonedDateTimeConverter#getApplyTimeZoneDifference() date converter} of this package for more
- * information on that.
- * </p>
- * 
- * @see StyleZonedDateTimeConverter
- * @see java.time.ZonedDateTime
- * @see java.time.format.DateTimeFormatter
- * @see java.time.ZoneId
- * 
- * @author eelcohillenius
- */
-public class DateField extends TextField<LocalDate> implements ITextFormatProvider
-{
-	private static final long serialVersionUID = 1L;
-
-	/**
-	 * Creates a new DateField defaulting to using a short date pattern
-	 * 
-	 * @param id
-	 *            The id of the text field
-	 * @param model
-	 *            The model
-	 * @param datePattern
-	 *            The pattern to use. Must be not null. See {@link SimpleDateFormat} for available
-	 *            patterns.
-	 * @return DateField
-	 */
-	public static DateField forDatePattern(String id, IModel<LocalDate> model, String datePattern)
-	{
-		return new DateField(id, model, new PatternDateConverter(datePattern));
-	}
-
-	/**
-	 * Creates a new DateField defaulting to using a short date pattern
-	 * 
-	 * @param id
-	 *            The id of the text field
-	 * @param datePattern
-	 *            The pattern to use. Must be not null. See {@link SimpleDateFormat} for available
-	 *            patterns.
-	 * @return DateField
-	 */
-	public static DateField forDatePattern(String id, String datePattern)
-	{
-		return forDatePattern(id, null, datePattern);
-	}
-
-	/**
-	 * Creates a new DateField using the provided date style.
-	 * 
-	 * @param id
-	 *            The id of the text field
-	 * @param model
-	 *            The model
-	 * @param dateStyle
-	 *            Date style to use. The first character is the date style, and the second character
-	 *            is the time style. Specify a character of 'S' for short style, 'M' for medium, 'L'
-	 *            for long, and 'F' for full. A date or time may be ommitted by specifying a style
-	 *            character '-'. See {@link org.joda.time.DateTimeFormat#forStyle(String)}.
-	 * @return DateField
-	 */
-	public static DateField forDateStyle(String id, IModel<LocalDate> model, String dateStyle)
-	{
-		return new DateField(id, model, new StyleDateConverter(dateStyle));
-	}
-
-	/**
-	 * Creates a new DateField using the provided date style.
-	 * 
-	 * @param id
-	 *            The id of the text field
-	 * @param dateStyle
-	 *            Date style to use. The first character is the date style, and the second character
-	 *            is the time style. Specify a character of 'S' for short style, 'M' for medium, 'L'
-	 *            for long, and 'F' for full. A date or time may be ommitted by specifying a style
-	 *            character '-'. See {@link org.joda.time.DateTimeFormat#forStyle(String)}.
-	 * @return DateField
-	 */
-	public static DateField forDateStyle(String id, String dateStyle)
-	{
-		return forDateStyle(id, null, dateStyle);
-	}
-
-	/**
-	 * Creates a new DateField defaulting to using a short date pattern
-	 * 
-	 * @param id
-	 *            The id of the text field
-	 * @return DateField
-	 */
-	public static DateField forShortStyle(String id)
-	{
-		return forShortStyle(id, null);
-	}
-
-	/**
-	 * Creates a new DateField defaulting to using a short date pattern
-	 * 
-	 * @param id
-	 *            The id of the text field
-	 * @param model
-	 *            The model
-	 * @return DateField
-	 */
-	public static DateField forShortStyle(String id, IModel<LocalDate> model)
-	{
-		return new DateField(id, model, new StyleDateConverter());
-	}
-
-	/**
-	 * Creates a new DateField using the provided converter.
-	 * 
-	 * @param id
-	 *            The id of the text field
-	 * @param converter
-	 *            the date converter
-	 * @return DateField
-	 */
-	public static DateField withConverter(String id, LocalDateConverter converter)
-	{
-		return withConverter(id, null, converter);
-	}
-
-	/**
-	 * Creates a new DateField using the provided converter.
-	 * 
-	 * @param id
-	 *            The id of the text field
-	 * @param model
-	 *            The model
-	 * @param converter
-	 *            the date converter
-	 * @return DateField
-	 */
-	public static DateField withConverter(String id, IModel<LocalDate> model, LocalDateConverter converter)
-	{
-		return new DateField(id, model, converter);
-	}
-
-	/**
-	 * The converter for the TextField
-	 */
-	private final LocalDateConverter converter;
-
-	/**
-	 * Construct with a converter.
-	 * 
-	 * @param id
-	 *            The component id
-	 * @param model
-	 *            The model
-	 * @param converter
-	 *            The converter to use
-	 */
-	public DateField(String id, IModel<LocalDate> model, LocalDateConverter converter)
-	{
-		super(id, model, LocalDate.class);
-
-		Args.notNull(converter, "converter");
-		this.converter = converter;
-	}
-
-	/**
-	 * Construct with a converter, and a null model.
-	 * 
-	 * @param id
-	 *            The component id
-	 * @param converter
-	 *            The converter to use
-	 */
-	public DateField(String id, LocalDateConverter converter)
-	{
-		this(id, null, converter);
-	}
-
-	/**
-	 * @return The specialized converter.
-	 * @see org.apache.wicket.Component#createConverter(java.lang.Class)
-	 */
-	@Override
-	protected IConverter<?> createConverter(Class<?> clazz)
-	{
-		if (LocalDate.class.isAssignableFrom(clazz))
-		{
-			return converter;
-		}
-		return null;
-	}
-
-	/**
-	 * @see org.apache.wicket.markup.html.form.AbstractTextComponent.ITextFormatProvider#getTextFormat()
-	 */
-	@Override
-	public final String getTextFormat()
-	{
-		return converter.getPattern(getLocale());
-	}
-
-	public static FormatStyle parseFormatStyle(char style)
-	{
-		switch (style)
-		{
-			case 'S':
-				return FormatStyle.SHORT;
-			case 'M':
-				return FormatStyle.MEDIUM;
-			case 'L':
-				return FormatStyle.LONG;
-			case 'F':
-				return FormatStyle.FULL;
-			default:
-				return null;
-		}
-	}
-}

http://git-wip-us.apache.org/repos/asf/wicket/blob/8567308e/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/DateTimeField.java
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/DateTimeField.java b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/DateTimeField.java
deleted file mode 100644
index bc4801c..0000000
--- a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/DateTimeField.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * 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.wicket.extensions.markup.html.form.datetime;
-
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.LocalTime;
-import java.time.temporal.ChronoField;
-import java.util.Locale;
-
-import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
-import org.apache.wicket.model.IModel;
-
-/**
- * Works on a {@link java.time.LocalDateTimeTime} object. Displays a date field and a DatePicker, a field
- * for hours and a field for minutes, and an AM/PM field. The format (12h/24h) of the hours field
- * depends on the time format of this {@link DateTimeField}'s {@link Locale}, as does the visibility
- * of the AM/PM field (see {@link DateTimeField#use12HourFormat}).
- * <p>
- * <strong>Ajaxifying the DateTimeField</strong>: If you want to update a DateTimeField with an
- * {@link AjaxFormComponentUpdatingBehavior}, you have to attach it to the contained
- * {@link DateField} by overriding {@link #newDateTextField(String, IModel)} and calling
- * {@link #processInput()}:
- * 
- * <pre>{@code
- *  DateTimeField dateTimeField = new DateTimeField(...) {
- *    protected DateTextField newDateTextField(String id, PropertyModel<Date> dateFieldModel)
- *    {
- *      DateTextField dateField = super.newDateTextField(id, dateFieldModel);     
- *      dateField.add(new AjaxFormComponentUpdatingBehavior("change") {
- *        protected void onUpdate(AjaxRequestTarget target) {
- *          processInput(); // let DateTimeField process input too
- *
- *          ...
- *        }
- *      });
- *      return recorder;
- *    }
- *  }
- * }</pre>
- * 
- * @author eelcohillenius
- * @see DateField for a variant with just the date field and date picker
- */
-public class DateTimeField extends AbstractDateTimeField<LocalDateTime>
-{
-	private static final long serialVersionUID = 1L;
-
-	private LocalDateTime dateTime = LocalDateTime.now();
-
-	/**
-	 * Construct.
-	 * 
-	 * @param id
-	 */
-	public DateTimeField(final String id)
-	{
-		this(id, null);
-	}
-
-	/**
-	 * Construct.
-	 * 
-	 * @param id
-	 * @param model
-	 */
-	public DateTimeField(final String id, final IModel<LocalDateTime> model)
-	{
-		super(id, model);
-
-		// Sets the type that will be used when updating the model for this component.
-		setType(LocalDateTime.class);
-	}
-
-	LocalDateTime performConvert(LocalDate date, LocalTime time) {
-		return LocalDateTime.of(date, time);
-	}
-
-	LocalDate getLocalDate()
-	{
-		return getModelObject() == null ? null : dateTime.toLocalDate();
-	}
-
-	void setLocalDate(LocalDate date)
-	{
-		dateTime = dateTime.with(ChronoField.YEAR, date.getYear())
-				.with(ChronoField.MONTH_OF_YEAR, date.getMonthValue())
-				.with(ChronoField.DAY_OF_YEAR, date.getDayOfMonth());
-	}
-
-	LocalTime getLocalTime()
-	{
-		return getModelObject() == null ? null : dateTime.toLocalTime();
-	}
-
-	void setLocalTime(LocalTime time)
-	{
-		dateTime = dateTime.with(ChronoField.HOUR_OF_DAY, time.getHour())
-				.with(ChronoField.MINUTE_OF_HOUR, time.getMinute());
-	}
-}

http://git-wip-us.apache.org/repos/asf/wicket/blob/8567308e/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/LocalDateConverter.java
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/LocalDateConverter.java b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/LocalDateConverter.java
deleted file mode 100644
index 95e1a47..0000000
--- a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/LocalDateConverter.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * 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.wicket.extensions.markup.html.form.datetime;
-
-import java.time.LocalDate;
-import java.time.format.DateTimeFormatter;
-import java.util.Locale;
-
-import org.apache.wicket.util.convert.ConversionException;
-import org.apache.wicket.util.convert.IConverter;
-import org.apache.wicket.util.lang.Args;
-import org.apache.wicket.util.string.Strings;
-
-
-/**
- * Base class for java.time based date converters. It contains the logic to parse and format,
- * optionally taking the time zone difference between clients and the server into account.
- * <p>
- * Converters of this class are best suited for per-component use.
- * </p>
- * 
- * @author eelcohillenius
- */
-public abstract class LocalDateConverter implements IConverter<LocalDate>
-{
-	private static final long serialVersionUID = 1L;
-
-	public LocalDate convertToObject(String value, DateTimeFormatter format, Locale locale) {
-		try
-		{
-			// parse date retaining the time of the submission
-			return LocalDate.parse(value, format);
-		}
-		catch (RuntimeException e)
-		{
-			throw newConversionException(e, locale);
-		}
-	}
-
-	@Override
-	public LocalDate convertToObject(String value, Locale locale)
-	{
-		if (Strings.isEmpty(value))
-		{
-			return null;
-		}
-
-		DateTimeFormatter format = getFormat(locale);
-		Args.notNull(format, "format");
-
-		return convertToObject(value, format, locale);
-	}
-
-	/**
-	 * Creates a ConversionException and sets additional context information to it.
-	 *
-	 * @param cause
-	 *            - {@link RuntimeException} cause
-	 * @param locale
-	 *            - {@link Locale} used to set 'format' variable with localized pattern
-	 * @return {@link ConversionException}
-	 */
-	ConversionException newConversionException(RuntimeException cause, Locale locale)
-	{
-		return new ConversionException(cause)
-				.setVariable("format", getPattern(locale));
-	}
-
-	@Override
-	public String convertToString(LocalDate dateTime, Locale locale)
-	{
-		DateTimeFormatter format = getFormat(locale);
-		return format.format(dateTime);
-	}
-
-	/**
-	 * @param locale
-	 *            The locale used to convert the value
-	 * @return Gets the pattern that is used for printing and parsing
-	 */
-	public abstract String getPattern(Locale locale);
-
-	/**
-	 * @param locale
-	 *            The locale used to convert the value
-	 * 
-	 * @return formatter The formatter for the current conversion
-	 */
-	public abstract DateTimeFormatter getFormat(Locale locale);
-}

http://git-wip-us.apache.org/repos/asf/wicket/blob/8567308e/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/LocalDateTextField.java
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/LocalDateTextField.java b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/LocalDateTextField.java
new file mode 100644
index 0000000..a1d1dc0
--- /dev/null
+++ b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/LocalDateTextField.java
@@ -0,0 +1,163 @@
+/*
+ * 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.wicket.extensions.markup.html.form.datetime;
+
+import java.time.LocalDate;
+import java.time.chrono.IsoChronology;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeFormatterBuilder;
+import java.time.format.FormatStyle;
+import java.util.Locale;
+
+import org.apache.wicket.markup.html.form.AbstractTextComponent.ITextFormatProvider;
+import org.apache.wicket.markup.html.form.TextField;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.util.convert.IConverter;
+import org.apache.wicket.util.convert.converter.LocalDateConverter;
+
+/**
+ * A TextField that is mapped to a <code>java.time.LocalDate</code> object and that uses java.time time to
+ * parse and format values.
+ * 
+ * @see java.time.format.DateTimeFormatter
+ * 
+ * @author eelcohillenius
+ */
+public class LocalDateTextField extends TextField<LocalDate> implements ITextFormatProvider
+{
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * The converter for the TextField
+	 */
+	private final TextFormatConverter converter;
+	
+	/**
+	 * Construct with a pattern.
+	 * 
+	 * @param id
+	 *            the component id
+	 * @param model
+	 *            the model
+	 * @param pattern
+	 *            the pattern to use
+	 */
+	public LocalDateTextField(String id, IModel<LocalDate> model, String datePattern)
+	{
+		super(id, model, LocalDate.class);
+
+		this.converter = new TextFormatConverter() {
+			
+			@Override
+			public DateTimeFormatter getDateTimeFormatter(Locale locale)
+			{
+				return DateTimeFormatter.ofPattern(datePattern).withLocale(locale);
+			}
+
+			@Override
+			public String getTextFormat(Locale locale)
+			{
+				return datePattern;
+			}
+		};
+	}
+
+	/**
+	 * Construct with a pattern.
+	 * 
+	 * @param id
+	 *            the component id
+	 * @param pattern
+	 *            the pattern to use
+	 */
+	public LocalDateTextField(String id, String datePattern)
+	{
+		this(id, null, datePattern);
+	}
+
+	/**
+	 * Construct with a style.
+	 * 
+	 * @param id
+	 *            the component id
+	 * @param model
+	 *            the model
+	 * @param dateStyle
+	 *            the style to use
+	 */
+	public LocalDateTextField(String id, IModel<LocalDate> model, FormatStyle dateStyle)
+	{
+		super(id, model, LocalDate.class);
+
+		this.converter = new TextFormatConverter() {
+			
+			@Override
+			public DateTimeFormatter getDateTimeFormatter(Locale locale)
+			{
+				return DateTimeFormatter.ofLocalizedDate(dateStyle).withLocale(locale);
+			}
+
+			@Override
+			public String getTextFormat(Locale locale)
+			{
+				return DateTimeFormatterBuilder.getLocalizedDateTimePattern(dateStyle, null, IsoChronology.INSTANCE, locale);
+			}
+		};
+	}
+
+
+	/**
+	 * Construct with a style.
+	 * 
+	 * @param id
+	 *            the component id
+	 * @param dateStyle
+	 *            the style to use
+	 */
+	public LocalDateTextField(String id, FormatStyle dateStyle)
+	{
+		this(id, null, dateStyle);
+	}
+
+	/**
+	 * @return The specialized converter.
+	 * @see org.apache.wicket.Component#createConverter(java.lang.Class)
+	 */
+	@Override
+	protected IConverter<?> createConverter(Class<?> clazz)
+	{
+		if (LocalDate.class.isAssignableFrom(clazz))
+		{
+			return converter;
+		}
+		return null;
+	}
+
+	/**
+	 * @see org.apache.wicket.markup.html.form.AbstractTextComponent.ITextFormatProvider#getTextFormat()
+	 */
+	@Override
+	public final String getTextFormat()
+	{
+		return converter.getTextFormat(getLocale());
+	}
+
+	private abstract class TextFormatConverter extends LocalDateConverter {
+		
+		public abstract String getTextFormat(Locale locale);
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/wicket/blob/8567308e/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/LocalDateTimeField.java
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/LocalDateTimeField.java b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/LocalDateTimeField.java
new file mode 100644
index 0000000..2283904
--- /dev/null
+++ b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/LocalDateTimeField.java
@@ -0,0 +1,74 @@
+/*
+ * 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.wicket.extensions.markup.html.form.datetime;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+
+import org.apache.wicket.model.IModel;
+
+/**
+ * Works on a {@link java.time.LocalDateTime} object. See {@link AbstractDateTimeField} for
+ * further details.
+ *  
+ * @author eelcohillenius
+ */
+public class LocalDateTimeField extends AbstractDateTimeField<LocalDateTime>
+{
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * Construct.
+	 * 
+	 * @param id
+	 */
+	public LocalDateTimeField(final String id)
+	{
+		this(id, null);
+	}
+
+	/**
+	 * Construct.
+	 * 
+	 * @param id
+	 * @param model
+	 */
+	public LocalDateTimeField(final String id, final IModel<LocalDateTime> model)
+	{
+		super(id, model);
+
+		// Sets the type that will be used when updating the model for this component.
+		setType(LocalDateTime.class);
+	}
+
+	@Override
+	protected LocalDateTime createTemporal(LocalDate date, LocalTime time) {
+		return LocalDateTime.of(date, time);
+	}
+
+	@Override
+	protected LocalDate getLocalDate(LocalDateTime temporal)
+	{
+		return temporal.toLocalDate();
+	}
+
+	protected LocalTime getLocalTime(LocalDateTime temporal)
+	{
+		return temporal.toLocalTime();
+	}
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/8567308e/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/LocalDateTimeTextField.java
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/LocalDateTimeTextField.java b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/LocalDateTimeTextField.java
new file mode 100644
index 0000000..772b5f3
--- /dev/null
+++ b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/LocalDateTimeTextField.java
@@ -0,0 +1,163 @@
+/*
+ * 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.wicket.extensions.markup.html.form.datetime;
+
+import java.time.LocalDateTime;
+import java.time.chrono.IsoChronology;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeFormatterBuilder;
+import java.time.format.FormatStyle;
+import java.util.Locale;
+
+import org.apache.wicket.markup.html.form.AbstractTextComponent.ITextFormatProvider;
+import org.apache.wicket.markup.html.form.TextField;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.util.convert.IConverter;
+import org.apache.wicket.util.convert.converter.LocalDateTimeConverter;
+
+/**
+ * A TextField that is mapped to a <code>java.time.LocalDateTime</code> object and that uses java.time time to
+ * parse and format values.
+ * 
+ * @see java.time.format.DateTimeFormatter
+ * 
+ * @author eelcohillenius
+ */
+public class LocalDateTimeTextField extends TextField<LocalDateTime> implements ITextFormatProvider
+{
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * The converter for the TextField
+	 */
+	private final TextFormatConverter converter;
+	
+	/**
+	 * Construct with a pattern.
+	 * 
+	 * @param id
+	 *            the component id
+	 * @param model
+	 *            the model
+	 * @param pattern
+	 *            the pattern to use
+	 */
+	public LocalDateTimeTextField(String id, IModel<LocalDateTime> model, String dateTimePattern)
+	{
+		super(id, model, LocalDateTime.class);
+
+		this.converter = new TextFormatConverter() {
+			
+			@Override
+			public DateTimeFormatter getDateTimeFormatter(Locale locale)
+			{
+				return DateTimeFormatter.ofPattern(dateTimePattern).withLocale(locale);
+			}
+
+			@Override
+			public String getTextFormat(Locale locale)
+			{
+				return dateTimePattern;
+			}
+		};
+	}
+
+	/**
+	 * Construct with a pattern.
+	 * 
+	 * @param id
+	 *            the component id
+	 * @param pattern
+	 *            the pattern to use
+	 */
+	public LocalDateTimeTextField(String id, String dateTimePattern)
+	{
+		this(id, null, dateTimePattern);
+	}
+
+	/**
+	 * Construct with a style.
+	 * 
+	 * @param id
+	 *            the component id
+	 * @param model
+	 *            the model
+	 * @param timeStyle
+	 *            the style to use
+	 */
+	public LocalDateTimeTextField(String id, IModel<LocalDateTime> model, FormatStyle dateStyle, FormatStyle timeStyle)
+	{
+		super(id, model, LocalDateTime.class);
+
+		this.converter = new TextFormatConverter() {
+			
+			@Override
+			public DateTimeFormatter getDateTimeFormatter(Locale locale)
+			{
+				return DateTimeFormatter.ofLocalizedDateTime(dateStyle, timeStyle).withLocale(locale);
+			}
+
+			@Override
+			public String getTextFormat(Locale locale)
+			{
+				return DateTimeFormatterBuilder.getLocalizedDateTimePattern(dateStyle, timeStyle, IsoChronology.INSTANCE, locale);
+			}
+		};
+	}
+
+
+	/**
+	 * Construct with a style.
+	 * 
+	 * @param id
+	 *            the component id
+	 * @param timeStyle
+	 *            the style to use
+	 */
+	public LocalDateTimeTextField(String id, FormatStyle dateStyle, FormatStyle timeStyle)
+	{
+		this(id, null, dateStyle, timeStyle);
+	}
+
+	/**
+	 * @return The specialized converter.
+	 * @see org.apache.wicket.Component#createConverter(java.lang.Class)
+	 */
+	@Override
+	protected IConverter<?> createConverter(Class<?> clazz)
+	{
+		if (LocalDateTime.class.isAssignableFrom(clazz))
+		{
+			return converter;
+		}
+		return null;
+	}
+
+	/**
+	 * @see org.apache.wicket.markup.html.form.AbstractTextComponent.ITextFormatProvider#getTextFormat()
+	 */
+	@Override
+	public final String getTextFormat()
+	{
+		return converter.getTextFormat(getLocale());
+	}
+
+	private abstract class TextFormatConverter extends LocalDateTimeConverter {
+		
+		public abstract String getTextFormat(Locale locale);
+	}
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/8567308e/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/LocalTimeConverter.java
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/LocalTimeConverter.java b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/LocalTimeConverter.java
deleted file mode 100644
index 1597ab6..0000000
--- a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/LocalTimeConverter.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * 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.wicket.extensions.markup.html.form.datetime;
-
-import java.time.LocalTime;
-import java.time.format.DateTimeFormatter;
-import java.util.Locale;
-
-import org.apache.wicket.util.convert.ConversionException;
-import org.apache.wicket.util.convert.IConverter;
-import org.apache.wicket.util.lang.Args;
-import org.apache.wicket.util.string.Strings;
-
-
-/**
- * Base class for java.time based date converters. It contains the logic to parse and format,
- * optionally taking the time zone difference between clients and the server into account.
- * <p>
- * Converters of this class are best suited for per-component use.
- * </p>
- * 
- * @author eelcohillenius
- */
-public abstract class LocalTimeConverter implements IConverter<LocalTime>
-{
-	private static final long serialVersionUID = 1L;
-
-	public LocalTime convertToObject(String value, DateTimeFormatter format, Locale locale) {
-		try
-		{
-			// parse date retaining the time of the submission
-			return LocalTime.parse(value, format);
-		}
-		catch (RuntimeException e)
-		{
-			throw newConversionException(e, locale);
-		}
-	}
-
-	@Override
-	public LocalTime convertToObject(String value, Locale locale)
-	{
-		if (Strings.isEmpty(value))
-		{
-			return null;
-		}
-
-		DateTimeFormatter format = getFormat(locale);
-		Args.notNull(format, "format");
-
-		return convertToObject(value, format, locale);
-	}
-
-	/**
-	 * Creates a ConversionException and sets additional context information to it.
-	 *
-	 * @param cause
-	 *            - {@link RuntimeException} cause
-	 * @param locale
-	 *            - {@link Locale} used to set 'format' variable with localized pattern
-	 * @return {@link ConversionException}
-	 */
-	ConversionException newConversionException(RuntimeException cause, Locale locale)
-	{
-		return new ConversionException(cause)
-				.setVariable("format", getPattern(locale));
-	}
-
-	@Override
-	public String convertToString(LocalTime time, Locale locale)
-	{
-		DateTimeFormatter format = getFormat(locale);
-		return format.format(time);
-	}
-
-	/**
-	 * @param locale
-	 *            The locale used to convert the value
-	 * @return Gets the pattern that is used for printing and parsing
-	 */
-	public abstract String getPattern(Locale locale);
-
-	/**
-	 * @param locale
-	 *            The locale used to convert the value
-	 * 
-	 * @return formatter The formatter for the current conversion
-	 */
-	public abstract DateTimeFormatter getFormat(Locale locale);
-}

http://git-wip-us.apache.org/repos/asf/wicket/blob/8567308e/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/LocalTimeTextField.java
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/LocalTimeTextField.java b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/LocalTimeTextField.java
new file mode 100644
index 0000000..5ea7e3a
--- /dev/null
+++ b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/LocalTimeTextField.java
@@ -0,0 +1,163 @@
+/*
+ * 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.wicket.extensions.markup.html.form.datetime;
+
+import java.time.LocalTime;
+import java.time.chrono.IsoChronology;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeFormatterBuilder;
+import java.time.format.FormatStyle;
+import java.util.Locale;
+
+import org.apache.wicket.markup.html.form.AbstractTextComponent.ITextFormatProvider;
+import org.apache.wicket.markup.html.form.TextField;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.util.convert.IConverter;
+import org.apache.wicket.util.convert.converter.LocalTimeConverter;
+
+/**
+ * A TextField that is mapped to a <code>java.time.LocalTime</code> object and that uses java.time time to
+ * parse and format values.
+ * 
+ * @see java.time.format.DateTimeFormatter
+ * 
+ * @author eelcohillenius
+ */
+public class LocalTimeTextField extends TextField<LocalTime> implements ITextFormatProvider
+{
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * The converter for the TextField
+	 */
+	private final TextFormatConverter converter;
+	
+	/**
+	 * Construct with a pattern.
+	 * 
+	 * @param id
+	 *            the component id
+	 * @param model
+	 *            the model
+	 * @param pattern
+	 *            the pattern to use
+	 */
+	public LocalTimeTextField(String id, IModel<LocalTime> model, String timePattern)
+	{
+		super(id, model, LocalTime.class);
+
+		this.converter = new TextFormatConverter() {
+			
+			@Override
+			public DateTimeFormatter getDateTimeFormatter(Locale locale)
+			{
+				return DateTimeFormatter.ofPattern(timePattern).withLocale(locale);
+			}
+
+			@Override
+			public String getTextFormat(Locale locale)
+			{
+				return timePattern;
+			}
+		};
+	}
+
+	/**
+	 * Construct with a pattern.
+	 * 
+	 * @param id
+	 *            the component id
+	 * @param pattern
+	 *            the pattern to use
+	 */
+	public LocalTimeTextField(String id, String datePattern)
+	{
+		this(id, null, datePattern);
+	}
+
+	/**
+	 * Construct with a style.
+	 * 
+	 * @param id
+	 *            the component id
+	 * @param model
+	 *            the model
+	 * @param timeStyle
+	 *            the style to use
+	 */
+	public LocalTimeTextField(String id, IModel<LocalTime> model, FormatStyle timeStyle)
+	{
+		super(id, model, LocalTime.class);
+
+		this.converter = new TextFormatConverter() {
+			
+			@Override
+			public DateTimeFormatter getDateTimeFormatter(Locale locale)
+			{
+				return DateTimeFormatter.ofLocalizedTime(timeStyle).withLocale(locale);
+			}
+
+			@Override
+			public String getTextFormat(Locale locale)
+			{
+				return DateTimeFormatterBuilder.getLocalizedDateTimePattern(null, timeStyle, IsoChronology.INSTANCE, locale);
+			}
+		};
+	}
+
+
+	/**
+	 * Construct with a style.
+	 * 
+	 * @param id
+	 *            the component id
+	 * @param timeStyle
+	 *            the style to use
+	 */
+	public LocalTimeTextField(String id, FormatStyle timeStyle)
+	{
+		this(id, null, timeStyle);
+	}
+
+	/**
+	 * @return The specialized converter.
+	 * @see org.apache.wicket.Component#createConverter(java.lang.Class)
+	 */
+	@Override
+	protected IConverter<?> createConverter(Class<?> clazz)
+	{
+		if (LocalTime.class.isAssignableFrom(clazz))
+		{
+			return converter;
+		}
+		return null;
+	}
+
+	/**
+	 * @see org.apache.wicket.markup.html.form.AbstractTextComponent.ITextFormatProvider#getTextFormat()
+	 */
+	@Override
+	public final String getTextFormat()
+	{
+		return converter.getTextFormat(getLocale());
+	}
+
+	private abstract class TextFormatConverter extends LocalTimeConverter {
+		
+		public abstract String getTextFormat(Locale locale);
+	}
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/8567308e/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/PatternDateConverter.java
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/PatternDateConverter.java b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/PatternDateConverter.java
deleted file mode 100644
index 54ea179..0000000
--- a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/PatternDateConverter.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * 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.wicket.extensions.markup.html.form.datetime;
-
-import java.text.SimpleDateFormat;
-import java.time.format.DateTimeFormatter;
-import java.util.Locale;
-
-import org.apache.wicket.util.lang.Args;
-
-
-/**
- * Date converter that uses javax.time and can be configured to take the time zone difference between
- * clients and server into account. This converter is hard coded to use the provided custom date
- * pattern, no matter what current locale is used. See {@link SimpleDateFormat} for available
- * patterns.
- * <p>
- * This converter is especially suited on a per-component base.
- * </p>
- * 
- * @see SimpleDateFormat
- * @see StyleDateConverter
- * @see org.apache.wicket.extensions.markup.html.form.DateTextField
- * @see java.time.LocalDate
- * @see DateTimeFormatter
- * 
- * @author eelcohillenius
- */
-public class PatternDateConverter extends LocalDateConverter
-{
-
-	private static final long serialVersionUID = 1L;
-
-	/** pattern to use. */
-	private final String datePattern;
-
-	/**
-	 * Construct.
-	 * 
-	 * @param datePattern
-	 *            The pattern to use. Must be not null. See {@link SimpleDateFormat} for available
-	 *            patterns.
-	 * @throws IllegalArgumentException
-	 *             in case the date pattern is null
-	 */
-	public PatternDateConverter(String datePattern)
-	{
-		super();
-		this.datePattern = Args.notNull(datePattern, "datePattern");
-	}
-
-	/**
-	 * Gets the optional date pattern.
-	 * 
-	 * @return datePattern
-	 */
-	@Override
-	public final String getPattern(Locale locale)
-	{
-		return datePattern;
-	}
-
-	/**
-	 * @return formatter The formatter for the current conversion
-	 */
-	@Override
-	public DateTimeFormatter getFormat(Locale locale)
-	{
-		return DateTimeFormatter.ofPattern(datePattern).withLocale(locale);
-	}
-}

http://git-wip-us.apache.org/repos/asf/wicket/blob/8567308e/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/PatternTimeConverter.java
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/PatternTimeConverter.java b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/PatternTimeConverter.java
deleted file mode 100644
index 021f500..0000000
--- a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/PatternTimeConverter.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * 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.wicket.extensions.markup.html.form.datetime;
-
-import java.text.SimpleDateFormat;
-import java.time.format.DateTimeFormatter;
-import java.util.Locale;
-
-import org.apache.wicket.util.lang.Args;
-
-
-/**
- * Date converter that uses javax.time and can be configured to take the time zone difference between
- * clients and server into account. This converter is hard coded to use the provided custom date
- * pattern, no matter what current locale is used. See {@link SimpleDateFormat} for available
- * patterns.
- * <p>
- * This converter is especially suited on a per-component base.
- * </p>
- * 
- * @see SimpleDateFormat
- * @see StyleDateConverter
- * @see org.apache.wicket.extensions.markup.html.form.DateTextField
- * @see java.time.LocalTime
- * @see DateTimeFormatter
- * 
- * @author eelcohillenius
- */
-public class PatternTimeConverter extends LocalTimeConverter
-{
-
-	private static final long serialVersionUID = 1L;
-
-	/** pattern to use. */
-	private final String timePattern;
-
-	/**
-	 * Construct.
-	 * 
-	 * @param timePattern
-	 *            The pattern to use. Must be not null. See {@link SimpleDateFormat} for available
-	 *            patterns.
-	 * @throws IllegalArgumentException
-	 *             in case the date pattern is null
-	 */
-	public PatternTimeConverter(String timePattern)
-	{
-		super();
-		this.timePattern = Args.notNull(timePattern, "timePattern");
-	}
-
-	/**
-	 * Gets the optional date pattern.
-	 * 
-	 * @return datePattern
-	 */
-	@Override
-	public final String getPattern(Locale locale)
-	{
-		return timePattern;
-	}
-
-	/**
-	 * @return formatter The formatter for the current conversion
-	 */
-	@Override
-	public DateTimeFormatter getFormat(Locale locale)
-	{
-		return DateTimeFormatter.ofPattern(timePattern).withLocale(locale);
-	}
-}

http://git-wip-us.apache.org/repos/asf/wicket/blob/8567308e/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/PatternZonedDateTimeConverter.java
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/PatternZonedDateTimeConverter.java b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/PatternZonedDateTimeConverter.java
deleted file mode 100644
index c432d90..0000000
--- a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/PatternZonedDateTimeConverter.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * 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.wicket.extensions.markup.html.form.datetime;
-
-import java.text.SimpleDateFormat;
-import java.time.format.DateTimeFormatter;
-import java.util.Locale;
-
-import org.apache.wicket.util.lang.Args;
-
-
-/**
- * Date converter that uses javax.time and can be configured to take the time zone difference between
- * clients and server into account. This converter is hard coded to use the provided custom date
- * pattern, no matter what current locale is used. See {@link SimpleDateFormat} for available
- * patterns.
- * <p>
- * This converter is especially suited on a per-component base.
- * </p>
- * 
- * @see SimpleDateFormat
- * @see StyleZonedDateTimeConverter
- * @see org.apache.wicket.extensions.markup.html.form.DateTextField
- * @see java.time.ZonedDateTime
- * @see DateTimeFormatter
- * @see java.time.ZoneId
- * 
- * @author eelcohillenius
- */
-public class PatternZonedDateTimeConverter extends ZonedDateTimeConverter
-{
-
-	private static final long serialVersionUID = 1L;
-
-	/** pattern to use. */
-	private final String datePattern;
-
-	/**
-	 * Construct.
-	 * </p>
-	 * When applyTimeZoneDifference is true, the current time is applied on the parsed date, and the
-	 * date will be corrected for the time zone difference between the server and the client. For
-	 * instance, if I'm in Seattle and the server I'm working on is in Amsterdam, the server is 9
-	 * hours ahead. So, if I'm inputting say 12/24 at a couple of hours before midnight, at the
-	 * server it is already 12/25. If this boolean is true, it will be transformed to 12/25, while
-	 * the client sees 12/24.
-	 * </p>
-	 * 
-	 * @param datePattern
-	 *            The pattern to use. Must be not null. See {@link SimpleDateFormat} for available
-	 *            patterns.
-	 * @param applyTimeZoneDifference
-	 *            whether to apply the difference in time zones between client and server
-	 * @throws IllegalArgumentException
-	 *             in case the date pattern is null
-	 */
-	public PatternZonedDateTimeConverter(String datePattern, boolean applyTimeZoneDifference)
-	{
-
-		super(applyTimeZoneDifference);
-		this.datePattern = Args.notNull(datePattern, "datePattern");
-	}
-
-	/**
-	 * Gets the optional date pattern.
-	 * 
-	 * @return datePattern
-	 */
-	@Override
-	public final String getPattern(Locale locale)
-	{
-		return datePattern;
-	}
-
-	/**
-	 * @return formatter The formatter for the current conversion
-	 */
-	@Override
-	public DateTimeFormatter getFormat(Locale locale)
-	{
-		return DateTimeFormatter.ofPattern(datePattern).withLocale(locale);
-	}
-}