/**
*PUBLIC SOFTWARE
*
*This source code has been placed in the public domain. You can use, modify, and distribute
*the source code and executable programs based on the source code.
*
*However, note the following:
*
*DISCLAIMER OF WARRANTY
*
* This source code is provided "as is" and without warranties as to performance
* or merchantability. The author and/or distributors of this source code may
* have made statements about this source code. Any such statements do not constitute
* warranties and shall not be relied on by the user in deciding whether to use
* this source code.This source code is provided without any express or implied
* warranties whatsoever. Because of the diversity of conditions and hardware
* under which this source code may be used, no warranty of fitness for a
* particular purpose is offered. The user is advised to test the source code
* thoroughly before relying on it. The user must assume the entire risk of
* using the source code.
*
*/
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.ui.*;
import java.util.Date;
/**
* DateBox implemenation for keyboard power users.
* @author
* @version 1.0
*/
public final class MyGwtDateBox extends TextBox
{
private static final long MS_PER_SEC = 1000;
private static final long MS_PER_MIN = MS_PER_SEC * 60;
private static final long MS_PER_HOUR = MS_PER_MIN * 60;
private static final long MS_PER_DAY = MS_PER_HOUR * 24;
/**
* date formats recognized .
*/
private static String[] formats = new String[]
{
"dd-MM-yyyy",
"dd-MMM-yyyy",
"dd.MM.yyyy",
"dd.MMM.yyyy",
"dd/MM/yyyy",
"dd/MMM/yyyy",
"dd MM yyyy",
"dd MMM yyyy",
"dd-MMMM-yyyy",
"dd.MMMM.yyyy",
"dd/MMMM/yyyy",
"dd MMMM yyyy",
"MMM dd yyyy",
"MMMM dd yyyy",
"MMM dd,yyyy",
"MMMM dd,yyyy"
};
/**
* output dateFormat
*/
private static DateTimeFormat dtf = DateTimeFormat.getFormat("dd-MMM-yyyy");
public static DateTimeFormat getDateTimeFormat()
{
return dtf;
}
private DateTimeFormat fullWeekDay = DateTimeFormat.getFormat("EEEE");
private DateTimeFormat shortWeekDay = DateTimeFormat.getFormat("EEE");
private Date today = today();
private Date yesterday = yesterday();
private Date tommorrow = tommorrow();
private Date value;
boolean nullAllowed = false;
/**
*
*/
private ChangeHandler changeHandler = new ChangeHandler()
{
/**
* try inferring the date from the enterd String , if not possible rollback to previous value.
*/
public void onChange(ChangeEvent event)
{
MyGwtDateBox x = (MyGwtDateBox) event.getSource();
String text = x.getText();
if (nullAllowed)
{
if (null == text || text.trim().equals(""))
{
return;
}
}
if (text == null)
{
text = dtf.format(new Date());
}
text = text.trim();
text.replaceAll("\\s+", "\\s");
text = handleNoSpacesString(text);
try
{
text = handleShortHands(text);
text = adjustYear(text);
text = dtf.format(DateTimeFormat.getFormat(inferFormat(text)).
parse(text));
value = dtf.parse(text);
x.setText(text);
}
catch (Exception e)
{
x.setText(dtf.format(value));
}
}
};
private HandlerRegistration regChange;
public MyGwtDateBox(int maxLength, int visibleLength)
{
throw new UnsupportedOperationException("not supported");
}
public MyGwtDateBox(String text, int maxLength, int visibleLength)
{
throw new UnsupportedOperationException("not supported");
}
public MyGwtDateBox(int maxLength)
{
throw new UnsupportedOperationException("not supported");
}
public MyGwtDateBox(String text, int maxLength)
{
throw new UnsupportedOperationException("not supported");
}
public MyGwtDateBox(String text)
{
throw new UnsupportedOperationException("not supported");
}
public MyGwtDateBox()
{
this(new Date());
}
public MyGwtDateBox(Date d)
{
super();
super.setText(dtf.format(d));
value = d;
regChange = super.addChangeHandler(changeHandler);
}
public void setNullAllowed(boolean nullAllowed)
{
this.nullAllowed = nullAllowed;
}
String handleNoSpacesString(String x)
{
if (x.matches("^\\d+$"))
{
if (x.length() == 6 || x.length() == 8)
{
return x.substring(0, 2) + " " + x.substring(2, 4) + " " + x.
substring(4);
}
}
return x;
}
/**
* the short-hand evaluation done in accordance with the values entered in AppMessages.properties
* @param x
* @return
*/
String handleShortHands(String x)
{
boolean previousFlag = false;
if (x.equalsIgnoreCase(MESSAGES.today()))
{
return dtf.format(today);
}
if (x.equalsIgnoreCase(MESSAGES.tommorrow()))
{
return dtf.format(tommorrow);
}
if (x.equalsIgnoreCase(MESSAGES.yesterday()))
{
return dtf.format(yesterday);
}
if (x.startsWith(MESSAGES.previous()))
{
previousFlag = true;
x = x.split("\\s")[1];
}
if (x.startsWith(MESSAGES.next()))
{
x = x.split("\\s")[1];
}
if (!x.trim().equals("") && MESSAGES.weekdaysString().
contains(x + ";"))
{
Date dt = previousFlag ? new Date(yesterday.getTime()) : new Date(tommorrow.
getTime());
long increment = previousFlag ? MS_PER_DAY * -1 : MS_PER_DAY;
while (!fullWeekDay.format(dt).equalsIgnoreCase(x))
{
dt.setTime(dt.getTime() + increment);
}
return dtf.format(dt);
}
if (!x.trim().equals("") && MESSAGES.weekdaysStringShort().
contains(x + ";"))
{
Date dt = previousFlag ? new Date(yesterday.getTime()) : new Date(tommorrow.
getTime());
long increment = previousFlag ? MS_PER_DAY * -1 : MS_PER_DAY;
while (!shortWeekDay.format(dt).equalsIgnoreCase(x))
{
dt.setTime(dt.getTime() + increment);
}
return dtf.format(dt);
}
return x;
}
/**
* example transformations
* 19 -> 2019
* 20 -> 2020
* 21 -> 1921
* @param x
* @return
*/
String adjustYear(String x)
{
if (x.matches("^.*\\D\\d\\d$"))
{
int year = Integer.parseInt(x.substring(x.length() - 2, x.length()));
x = x.substring(0, x.length() - 2) + (year < 21 ? "20" : "19") + x.
substring(x.length() - 2, x.length());
}
return x;
}
String inferFormat(String x)
{
for (String format : formats)
{
try
{
DateTimeFormat.getFormat(format).parse(x);
return format;
}
catch (Exception e)
{
//ignore
}
}
throw new RuntimeException("Unparseable date , " + x);
}
static Date today()
{
return new Date();
}
static Date yesterday()
{
Date tmp = new Date();
tmp.setTime(tmp.getTime() - MS_PER_DAY);
return new Date(tmp.getTime());
}
static Date tommorrow()
{
Date tmp = new Date();
tmp.setTime(tmp.getTime() + MS_PER_DAY);
return new Date(tmp.getTime());
}
public Date getDate()
{
return dtf.parse(super.getText());
}
public void setDate(Date x)
{
super.setText(dtf.format(x));
}
}
class MESSAGES
{
static String today()
{
return "today";
}
static String tommorrow()
{
return "tomm";
}
static String yesterday()
{
return "yesterday";
}
static String next()
{
return "next";
}
static String previous()
{
return "previous";
}
static String weekdaysString()
{
return "sunday;monday;tuesday;wednesday;thursday;friday;saturday;";
}
static String weekdaysStringShort()
{
return "sun;mon;tue;wed;thu;fri;sat;";
}
}