The date converter is being phased out because it is messy in many
ways (and the java.util.Date API is partly to blame for that!). I
think you would do best just copying the whole component to your own
project and then tweaking it in getInitiScript and by depending on
your own date converter for getting the proper patterns.

Btw, if you are working with different locales, the client's time zone
is something you might want to consider as well. Here is something
that does that and which depends on JodaTime


import java.util.Date;
import java.util.TimeZone;

import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.MutableDateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import wicket.Session;
import wicket.protocol.http.request.WebClientInfo;
import wicket.request.ClientInfo;
import wicket.util.convert.SimpleConverterAdapter;

/**
 * Date converter that can be smart about differences in time zone between
 * clients and server. NOT thread safe.
 *
 * @author eelcohillenius
 */
public class DateConverter extends SimpleConverterAdapter {

        /**
         * 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>
         * <p>
         * True by default
         * </p>
         */
        private boolean applyTimeZoneDifference = true;

        /** optional pattern to use. */
        private String datePattern;

        /**
         * Construct.
         */
        public DateConverter() {
        }

        /**
         * 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;
        }

        /**
         * Gets the optional date pattern.
         *
         * @return datePattern
         */
        public String getDatePattern() {
                return datePattern;
        }

        /**
         * Sets 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>
         *
         * @param applyTimeZoneDifference
         *            whether to apply the difference in time zones between 
client
         *            and server
         */
        public final void setApplyTimeZoneDifference(boolean 
applyTimeZoneDifference) {
                this.applyTimeZoneDifference = applyTimeZoneDifference;
        }

        /**
         * Sets the optional date pattern.
         *
         * @param datePattern
         *            datePattern
         */
        public void setDatePattern(String datePattern) {
                this.datePattern = datePattern;
        }

        @Override
        public Object toObject(String value) {

                DateTimeFormatter format = getFormat();

                if (applyTimeZoneDifference) {
                        TimeZone zone = getClientTimeZone();
                        // instantiate now/ current time
                        MutableDateTime dt = new MutableDateTime();
                        if (zone != null) {
                                // set time zone for client
                                format = 
format.withZone(DateTimeZone.forTimeZone(zone));
                                dt.setZone(DateTimeZone.forTimeZone(zone));
                        }
                        // parse date retaining the time of the submission
                        format.parseInto(dt, value, 0);
                        // apply the server time zone to the parsed value
                        
dt.setZone(DateTimeZone.forTimeZone(TimeZone.getDefault()));
                        return dt.toDate();
                } else {
                        return format.parseDateTime(value).toDate();
                }
        }

        @Override
        public String toString(Object value) {

                DateTime dt = new DateTime(((Date) value).getTime());
                DateTimeFormatter format = getFormat();

                if (applyTimeZoneDifference) {
                        TimeZone zone = getClientTimeZone();
                        if (zone != null) {
                                // apply time zone to formatter
                                format = 
format.withZone(DateTimeZone.forTimeZone(zone));
                        }
                }
                return format.print(dt);
        }

        /**
         * Gets the client's time zone.
         *
         * @return The client's time zone or null
         */
        private TimeZone getClientTimeZone() {
                ClientInfo info = Session.get().getClientInfo();
                if (info instanceof WebClientInfo) {
                        return ((WebClientInfo) 
info).getProperties().getTimeZone();
                }
                return null;
        }

        /**
         * @return formatter
         */
        private DateTimeFormatter getFormat() {
                if (datePattern != null) {
                        return DateTimeFormat.forPattern(datePattern);
                } else {
                        return 
DateTimeFormat.shortDate().withLocale(Session.get().getLocale());
                }
        }
}

import java.util.Date;

import wicket.markup.ComponentTag;
import wicket.markup.html.form.TextField;
import wicket.model.IModel;
import wicket.util.convert.IConverter;

/**
 * A TextField that is mapped to a <code>java.util.Date</code> object and that
 * uses Joda time to parse and format values.
 * <p>
 * You can provide a date pattern in two of the constructors. When not provided,
 * [EMAIL PROTECTED] DateTimeFormat#shortDate()} will be used.
 * </p>
 * <p>
 * A special option is applyTimeZoneDifference which is an option that says
 * whether to correct for the difference between the client's time zone and
 * server's time zone. This is true by default.
 * </p>
 *
 * @see DateTime
 * @see DateTimeFormat
 * @see DateTimeZone
 *
 * @author eelcohillenius
 */
public class DateTextField extends TextField {

        private static final long serialVersionUID = 1L;

        /**
         * The converter for the TextField
         */
        private DateConverter converter = new DateConverter();

        /**
         * Creates a new DateTextField, without a specified pattern. This is the
         * same as calling <code>new TextField(id, Date.class)</code>
         *
         * @param id
         *            The id of the text field
         *
         * @see wicket.markup.html.form.TextField
         */
        public DateTextField(String id) {
                super(id, Date.class);
        }

        /**
         * Creates a new DateTextField, without a specified pattern. This is the
         * same as calling <code>new TextField(id, object, Date.class)</code>
         *
         * @param id
         *            The id of the text field
         * @param object
         *            The model
         *
         * @see wicket.markup.html.form.TextField
         */
        public DateTextField(String id, IModel object) {
                super(id, object, Date.class);
        }

        /**
         * Creates a new DateTextField bound with a specific
         * [EMAIL PROTECTED] org.joda.time.format.DateTimeFormatter} pattern.
         *
         * @param id
         *            The id of the text field
         * @param object
         *            The model
         * @param datePattern
         *            A [EMAIL PROTECTED] 
org.joda.time.format.DateTimeFormatter} pattern
         *
         * @see wicket.markup.html.form.TextField
         */
        public DateTextField(String id, IModel object, String datePattern) {
                super(id, object, Date.class);
                converter.setDatePattern(datePattern);
        }

        /**
         * Creates a new DateTextField bound with a specific
         * [EMAIL PROTECTED] org.joda.time.format.DateTimeFormatter} pattern.
         *
         * @param id
         *            The id of the text field
         * @param datePattern
         *            A [EMAIL PROTECTED] 
org.joda.time.format.DateTimeFormatter} pattern
         *
         * @see wicket.markup.html.form.TextField
         */
        public DateTextField(String id, String datePattern) {
                super(id, Date.class);
                converter.setDatePattern(datePattern);
        }

        /**
         * 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 boolean getApplyTimeZoneDifference() {
                return converter.getApplyTimeZoneDifference();
        }

        /**
         * Returns the specialized converter.
         */
        @Override
        public IConverter getConverter() {
                return converter;
        }

        /**
         * Sets 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>
         *
         * @param applyTimeZoneDifference
         *            whether to apply the difference in time zones between 
client
         *            and server
         */
        public void setApplyTimeZoneDifference(boolean applyTimeZoneDifference) 
{
                converter.setApplyTimeZoneDifference(applyTimeZoneDifference);
        }

        @Override
        protected void onComponentTag(ComponentTag tag) {
                super.onComponentTag(tag);
                tag.put("onfocus", "this.select();");
        }
}


If you plan to use this, you surely should patch DatePicker.

The time difference isn't as obvious when you work with dates, but you
can have weird differences. If you work with times, it is more
obvious. As a bonus, here is code to let you work with times:

import java.util.Arrays;
import java.util.Date;
import java.util.TimeZone;

import org.joda.time.DateTimeFieldType;
import org.joda.time.DateTimeZone;
import org.joda.time.MutableDateTime;

import ts4.web.wicket.component.datepicker.settings.DatePickerSettings;
import wicket.Session;
import wicket.extensions.markup.html.datepicker.DatePicker;
import wicket.markup.html.form.DropDownChoice;
import wicket.markup.html.form.FormComponentPanel;
import wicket.markup.html.form.TextField;
import wicket.markup.html.form.validation.NumberValidator;
import wicket.model.IModel;
import wicket.model.PropertyModel;
import wicket.protocol.http.request.WebClientInfo;
import wicket.request.ClientInfo;

/**
 * Works on a [EMAIL PROTECTED] java.util.Date} object. Displays a date field 
and a date
 * picker, a field for hours and a field for minutes, and a AM/ PM field.
 *
 * @author eelcohillenius
 * @see DateField for a variant with just the date field and date picker
 */
public class DateTimeField extends FormComponentPanel {

        private static enum AM_PM {
                AM, PM
        }

        private AM_PM amOrPm = AM_PM.AM;

        private DropDownChoice amOrPmChoice;

        /**
         * 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>
         * <p>
         * True by default
         * </p>
         */
        private boolean applyTimeZoneDifference = true;

        private MutableDateTime date;

        private DateTextField dateField;

        private Integer hours;

        private TextField hoursField;

        private Integer minutes;

        private TextField minutesField;

        /**
         * Construct.
         *
         * @param id
         */
        public DateTimeField(String id) {
                super(id);
                init();
        }

        /**
         * Construct.
         *
         * @param id
         * @param model
         */
        public DateTimeField(String id, IModel model) {
                super(id, model);
                init();
        }

        /**
         * Gets amOrPm.
         *
         * @return amOrPm
         */
        public AM_PM getAmOrPm() {
                return amOrPm;
        }

        /**
         * 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;
        }

        /**
         * Gets date.
         *
         * @return date
         */
        public Date getDate() {
                return (date != null) ? date.toDate() : null;
        }

        /**
         * Gets hours.
         *
         * @return hours
         */
        public Integer getHours() {
                return hours;
        }

        /**
         * Gets minutes.
         *
         * @return minutes
         */
        public Integer getMinutes() {
                return minutes;
        }

        /**
         * Sets amOrPm.
         *
         * @param amOrPm
         *            amOrPm
         */
        public void setAmOrPm(AM_PM amOrPm) {
                this.amOrPm = amOrPm;
        }

        /**
         * Sets 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>
         *
         * @param applyTimeZoneDifference
         *            whether to apply the difference in time zones between 
client
         *            and server
         */
        public final void setApplyTimeZoneDifference(boolean 
applyTimeZoneDifference) {
                this.applyTimeZoneDifference = applyTimeZoneDifference;
                dateField.setApplyTimeZoneDifference(applyTimeZoneDifference);
        }

        /**
         * Sets date.
         *
         * @param date
         *            date
         */
        public void setDate(Date date) {
                this.date = (date != null) ? new MutableDateTime(date) : null;
        }

        /**
         * Sets hours.
         *
         * @param hours
         *            hours
         */
        public void setHours(Integer hours) {
                this.hours = hours;
        }

        /**
         * Sets minutes.
         *
         * @param minutes
         *            minutes
         */
        public void setMinutes(Integer minutes) {
                this.minutes = minutes;
        }

        @Override
        public void updateModel() {

                dateField.updateModel();
                hoursField.updateModel();
                minutesField.updateModel();
                amOrPmChoice.updateModel();

                if (date != null) {

                        try {
                                if (applyTimeZoneDifference) {
                                        TimeZone zone = getClientTimeZone();
                                        if (zone != null) {
                                                
date.setZone(DateTimeZone.forTimeZone(zone));
                                        }
                                }

                                if (hours != null) {
                                        
date.set(DateTimeFieldType.hourOfHalfday(), hours);
                                        date.setMinuteOfHour((minutes != null) 
? minutes : 0);
                                }
                                if (amOrPm == AM_PM.PM) {
                                        
date.set(DateTimeFieldType.halfdayOfDay(), 1);
                                } else {
                                        
date.set(DateTimeFieldType.halfdayOfDay(), 0);
                                }
                        } catch (RuntimeException e) {
                                DateTimeField.this.error(e.getMessage());
                                invalid();
                        }

                        // the date will be in the server's timezone
                        Date d = date.toDate();
                        setModelObject(d);
                } else {
                        setModelObject(null);
                }
        }

        protected DatePickerSettings newDatePickerSettings() {
                return new DatePickerSettings();
        }

        @Override
        protected void onAttach() {

                Date d = (Date) getModelObject();
                if (d != null) {
                        date = new MutableDateTime(d);
                } else {
                        date = null;
                }

                if (date != null) {

                        if (applyTimeZoneDifference) {
                                // convert date to the client's time zone if we 
have that info
                                TimeZone zone = getClientTimeZone();
                                // instantiate with the previously set date
                                if (zone != null) {
                                        
date.setZone(DateTimeZone.forTimeZone(zone));
                                }
                        }

                        hours = date.get(DateTimeFieldType.hourOfHalfday());
                        minutes = date.getMinuteOfHour();
                        amOrPm = (date.get(DateTimeFieldType.halfdayOfDay()) == 
0) ?
AM_PM.AM : AM_PM.PM;

                        // we don't really have to reset the date field to the 
server's
                        // timezone, as it's the same milis from EPOCH anyway, 
and toDate
                        // will always get the Date object initialized for the 
time zone
                        // of the server
                }

                super.onAttach();
        }

        /**
         * Gets the client's time zone.
         *
         * @return The client's time zone or null
         */
        private TimeZone getClientTimeZone() {
                ClientInfo info = Session.get().getClientInfo();
                if (info instanceof WebClientInfo) {
                        return ((WebClientInfo) 
info).getProperties().getTimeZone();
                }
                return null;
        }

        private void init() {

                setType(Date.class);
                add(dateField = new DateTextField("date", new 
PropertyModel(this, "date")));
                add(new DatePicker("picker", dateField, 
newDatePickerSettings()));
                add(hoursField = new TextField("hours", new PropertyModel(this,
"hours"), Integer.class));
                hoursField.add(NumberValidator.range(0, 12));
                add(minutesField = new TextField("minutes", new 
PropertyModel(this,
"minutes"), Integer.class));
                minutesField.add(NumberValidator.range(0, 60));
                add(amOrPmChoice = new DropDownChoice("amOrPmChoice", new
PropertyModel(this, "amOrPm"), Arrays.asList(AM_PM
                                .values())));
        }
}

<wicket:panel>
  <span style="white-space: nowrap;">
    <input type="text" wicket:id="date" size="8" />
    <span wicket:id="picker" />
    <input type="text" wicket:id="hours" size="2" />&nbsp;:
    <input type="text" wicket:id="minutes" size="2" />
    <select wicket:id="amOrPmChoice"></select>
  </span>
</wicket:panel>


On 2/2/07, Scott Swank <[EMAIL PROTECTED]> wrote:
> The text field has yy, while the date picker puts yyyy into the date --
> whether it's MM/dd/yyyy or dd/MM/yyyy (due to i18n).  Then we get an
> annoying npe rendering the feedback panel -- which I still haven't tracked
> down.
>
> popup contains panel
> panel contains form
> form contains fields with validation
> form contains date pickers that are tied to two of the fields
> form also has form-level validation
> form also contains feedback panel with form component feedback borders
> around date fields
> form applies
> AjaxFormValidatingBehavior.addToAllFormComponents("onblur")
>
> When the date picker pushes an invalid date (check-in date before today or
> check-out date on/before check-in date) null pointers just roll in rendering
> the feedback panel.  I'm working to isolate this to a simpler case...
>
> Scott
>
>
>
> On 2/2/07, Eelco Hillenius <[EMAIL PROTECTED]> wrote:
> > The date picker component already tries to sync with the text field
> > you provide as the target. Did you try this?
> >
> > Eelco
> >
> >
> > On 2/1/07, Scott Swank <[EMAIL PROTECTED] > wrote:
> > > I just (a bit too optimistically) tried to get the converter from my
> > > TextField and use it to set the DateConverter for the corresponding
> > > DatePicker.  I definitely want to retain the i18n (mm/dd/yyyy for
> ENGLISH
> > > and dd/mm/yyyy for FRENCH).  Is there a straightforward way to synch up
> the
> > > DateConverters for a TextField and DatePicker while retaining
> > > internationalization?
> > >
> > >         RequiredTextField checkIn = new RequiredTextField("checkIn", new
> > > PropertyModel(roomRequest,
> > >                 "checkIn"), Date.class);
> > >         checkIn.setOutputMarkupId(true);
> > >         checkIn.add(DateValidator.minimum(getToday()));
> > >         add(checkIn);
> > >
> > >         DatePicker dp = new
> > > CylleniusCalendar("checkInPicker", checkIn);
> > >         dp.setOutputMarkupId(true);
> > >         dp.setDateConverter ((DateConverter) checkIn.getConverter ());
> > >         add(dp);
> > >
> > >  java.lang.ClassCastException: wicket.util.convert.Converter
> > >     at
> > >
> com.vegas.cart.wicket.components.RoomRequestForm.<init>(RoomRequestForm.java
> > > :69)
> > >
> > > Thank you,
> > > Scott
> > >
> -------------------------------------------------------------------------
> > > Using Tomcat but need to do more? Need to support web services,
> security?
> > > Get stuff done quickly with pre-integrated technology to make your job
> > > easier.
> > > Download IBM WebSphere Application Server v.1.0.1 based on Apache
> Geronimo
> > >
> http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
> > > _______________________________________________
> > > Wicket-user mailing list
> > > Wicket-user@lists.sourceforge.net
> > >
> https://lists.sourceforge.net/lists/listinfo/wicket-user
> > >
> > >
> >
> >
> -------------------------------------------------------------------------
> > Using Tomcat but need to do more? Need to support web services, security?
> > Get stuff done quickly with pre-integrated technology to make your job
> easier.
> > Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
> >
> http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
> > _______________________________________________
> > Wicket-user mailing list
> > Wicket-user@lists.sourceforge.net
> > https://lists.sourceforge.net/lists/listinfo/wicket-user
> >
>
>
>
> --
>  Scott Swank
> reformed mathematician
> -------------------------------------------------------------------------
> Using Tomcat but need to do more? Need to support web services, security?
> Get stuff done quickly with pre-integrated technology to make your job
> easier.
> Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
> http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
>
> _______________________________________________
> Wicket-user mailing list
> Wicket-user@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/wicket-user
>
>
>

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier.
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Wicket-user mailing list
Wicket-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/wicket-user

Reply via email to