http://git-wip-us.apache.org/repos/asf/wicket/blob/0a4b5f2e/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/0a4b5f2e/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/0a4b5f2e/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/0a4b5f2e/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/0a4b5f2e/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/0a4b5f2e/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/0a4b5f2e/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/0a4b5f2e/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/0a4b5f2e/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/0a4b5f2e/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/0a4b5f2e/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/0a4b5f2e/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/0a4b5f2e/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))));
        }
        

Reply via email to