I have to accept a date from a user via a simple inputText field (JSF 2). I created a Converter so I can validate the date and now I am running into trouble with 1, 3, and 5+ digit years. All dates entered by the user will be either today or in the future (up to a reasonable maximum).
The below solution accepts three different date formats and will correctly handle 2 and 4 digit years (in the former case by using set2DigitYearStart to convert them to 20XX). I am completely stumped how I can handle other wrong dates.
Code
public static void main(String[] args) throws Exception {
String date = "2/3/111"; // This should be rejected!
List<String> datePatterns = new ArrayList<String>();
datePatterns.add("MM-dd-yy");
datePatterns.add("MM.dd.yy");
datePatterns.add("MM/dd/yy");
for (String pattern : datePatterns) {
SimpleDateFormat formatter = new SimpleDateFormat(pattern);
formatter.set2DigitYearStart(new SimpleDateFormat("MM/dd/yyyy").parse("1/1/2000"));
formatter.setLenient(false);
try {
System.out.println(formatter.parse(date));
break;
} catch (ParseException ignore) {
System.out.println("Date format doesn't match pattern: " + pattern);
}
}
}
Examples That Should be Accepted
02/02/02
02/02/2002
Examples That Should be Rejected
02/02/1
02/02/333
02/02/55555
One Approach
Get some theoretical maxDate and yesterday's date, then compare the output. This seems wrong somehow, though...
SimpleDateFormat f4 = new SimpleDateFormat("MM/dd/yyyy");
Date maxDate = f4.parse("01/01/2099");
DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE, -1);
Date minDate = f4.parse(dateFormat.format(cal.getTime()));
Add some specific validation after your parsing is finished to reject any years that are out of range ie getYear() < 1000 and getYear() > 9999
Warning this code is not compiled or tested as I am typing on a tablet.
String dateStr = "2/3/111"; // This should be rejected!
List<String> datePatterns = new ArrayList<String>();
datePatterns.add("MM-dd-yy");
datePatterns.add("MM.dd.yy");
datePatterns.add("MM/dd/yy");
Date date = null;
for (String pattern : datePatterns) {
SimpleDateFormat formatter = new SimpleDateFormat(pattern);
formatter.set2DigitYearStart(new SimpleDateFormat("MM/dd/yyyy").parse("1/1/2000"));
formatter.setLenient(false);
try {
date = dateformatter.parse(dateStr));
break;
} catch (ParseException ignore) {
continue;
}
}
if (date != null) {
Calendar cal = new GregorianCalendar (date);
int year = cal.get(Calendar.YEAR);
if (year() < 1000 || year() > 9999) {
System.out.println("Date format doesn't match pattern: "
+ datePatterns);
}
} else {
System.out.println("Date format doesn't match pattern: "
+ datePatterns);
{
Related
This question already has answers here:
Parse any date in Java
(6 answers)
Closed 5 years ago.
I'm trying to convert a date string to date object in java regardless of current system date format. Because I want to get my custom date format to store in database. The following is my code and please advice me the way.
public static String dateToString(String date){
if(date.equals("")) return "";
if(date == null || date.length() == 0){
return "";
}
SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
try {
Date l_date = format.parse(date);
Calendar calendar = Calendar.getInstance();
calendar.setTime(l_date);
String year = String.format("%04d", calendar.get(Calendar.YEAR));
String month = String.format("%02d", calendar.get(Calendar.MONTH));
String day = String.format("%02d", calendar.get(Calendar.DATE));
return year + month + day;
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return "";
}
}
For SimpleDateFormat, it can only parse the format I heard coded.
dateToString("16/04/2015");
It can convert for above code. But, when I try with the following format
dateToString("Thursday, April 16, 2015");
I go Unparseable date: "Thursday, April 16, 2015" error.
You're trying to convert a String in EEEE, MMMM dd, yyyy format with the format of dd/MM/yyyy...
Start by using the correct format for the String you trying to convert, the use what ever format you want to convert it back...
SimpleDateFormat from = new SimpleDateFormat("EEEE, MMMM dd, yyyy");
SimpleDateFormat to = new SimpleDateFormat("dd/MM/yyyy");
String value = to.format(from.parse(dateString));
Now you could use something like DateUtils.parseDate(String, String[]) which allows to supply a number of different formats, but is still limited to what you might know.
A better solution would be to store the Date value directly within the database.
You are passing wrong parameter to SimpleDateFormater
Use
SimpleDateFormat format = new SimpleDateFormat("EEEE, MMMM dd, yyyy") instead of SimpleDateFormat to = new SimpleDateFormat("dd/MM/yyyy");
It resolve your Unparseable date issue.
Try to use something like this:
public static String dateToString(String date){
if(date.equals("")) return "";
if(date == null || date.length() == 0){
return "";
}
SimpleDateFormat formatIn = new SimpleDateFormat("dd/MM/yyyy");
SimpleDateFormat formatOut = new SimpleDateFormat("yyyy-dd-MM");
try {
Date l_date = formatIn.parse(date);
String result = formatOut.format(l_date);
return result;
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return "";
}
}
but if you want to put some data into database you may also use instead String java.sql.Date
something like this:
SimpleDateFormat format = new SimpleDateFormat();
Connection conn = ...
PreparedStatement ps = conn.prepareStatement("...");
long lDate = format.parse(sDate).getTime();
java.sql.Date dDate = new java.sql.Date(lDate);
ps.setDate(1, dDate);
I am trying to display Date based on timezone.
If I change my system time zone to US pacific time zone, today's date is displayed correctly. If I want to display 2000-01-01 output shows as 12/31/1969.
Can you please let me know if I have to make any change in system settings or java settings?.
Below is the example code:
package timezoneexample;
import java.text.DateFormat;
import java.util.Date;
import java.util.TimeZone;
public class TimezoneExample {
public static void main(String args[]) {
DateFormat dateFormat = null;
String datePattern = null;
char dateSeperator = '/';
try {
datePattern = "MM/dd/yyyy";
if (datePattern.length() <= 0)
throw new java.util.MissingResourceException(
"Didn't find date format", "", "");
boolean hasSeperatorAlready = false;
for (int i = 0; i < datePattern.length(); i++)
if (!Character.isLetter(datePattern.charAt(i)))
if (hasSeperatorAlready)
throw new java.util.MissingResourceException(
"Unvalid date format", "", "");
else
dateSeperator = datePattern.charAt(i);
} catch (java.util.MissingResourceException mre) {
System.out.println(mre);
}
dateFormat = DateFormat.getDateInstance(DateFormat.MEDIUM);
if (datePattern.length() > 0
&& dateFormat instanceof java.text.SimpleDateFormat) {
java.text.SimpleDateFormat sdf = (java.text.SimpleDateFormat) dateFormat;
sdf.applyPattern(datePattern);
}
dateFormat.setTimeZone(java.util.TimeZone.getDefault());
// enter DOB
Date dob = new Date(2000 - 01 - 01);
Date today = new Date();
String timeZone = System.getProperties().getProperty("user.timezone");
TimeZone tZone = TimeZone.getTimeZone(timeZone);
System.out.println("Timezone : " + tZone);
dateFormat.setTimeZone(tZone);
System.out.println("Date Of Birth : " + dateFormat.format(dob));
System.out.println("Date in Displayed as per Timezone : "
+ dateFormat.format(today));
}
}
Output:
Timezone : sun.util.calendar.ZoneInfo[id="America/Los_Angeles",offset=-28800000,dstSavings=3600000,useDaylight=true,transitions=185,lastRule=java.util.SimpleTimeZone[id=America/Los_Angeles,offset=-28800000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=3,startMonth=2,startDay=8,startDayOfWeek=1,startTime=7200000,startTimeMode=0,endMode=3,endMonth=10,endDay=1,endDayOfWeek=1,endTime=7200000,endTimeMode=0]]
Date Of Birth : 12/31/1969
Date in Displayed as per Timezone : 01/07/2015
Your error is here:
Date dob = new Date(2000 - 01 - 01);
This will be interpreted as:
Date dob = new Date(1998);
This will invoke the Date(long date) constructor, resulting in a date near 1970/01/01.
What you most probably want is:
Date dob = new Date(2000, 1, 1);
new Date(...) requires a long value, expressing the number of milliseconds since 1/1/1970. You're specifying 2000 - 1 - 1. This is NOT "year 2000, month 1 and day 1", it is a numeric expression equal to 1998 milliseconds.
To create a date based on year/month/day, use a Calendar:
Calendar c = Calendar.getInstance();
c.set(y, m-1 /* 0-based */, d); // e.g. c.set(2000, 0, 1);
return c.getTime();
I haven't programmed in Java for many years, but I now have to change a program I wrote some time ago. In this program I need to read a QIF file and find the qif record with the maximum date (Dmm-dd-yyyy).
I could not get this to work in my program so I wrote a simple test to demonstrate the problem I am having. I think there are other ways to do this, like lists and collections. But I still want to know why using SimpleDateFormat won't work. Notice in the output that this method produces the max for July but seems to ignore all August dates.
Thanks, Mike
import java.text.SimpleDateFormat;
import java.util.Date;
class DateParser {
public static void main(String[] args) {
SimpleDateFormat sdf = new SimpleDateFormat("mm-dd-yyyy");
Date nextDate = null;
Date maxDate = null;
String nextStrDate = null;
String maxStrDate = null;
//Fill date array.
String date[] = {"07-14-2014","07-22-2014","07-31-2014",
"08-01-2014","08-04-2014","08-06-2014"};
try {
//Start with early maximum date.
maxDate = sdf.parse("01-01-1800");
// Find Max date in array.
for (int i=0; i<6; ++i) {
nextStrDate = date[i];
nextDate = sdf.parse(nextStrDate);
if(nextDate.after(maxDate)){
maxStrDate = nextStrDate;
maxDate = nextDate;
}
System.out.println( "Next Date = " + nextStrDate);
}
System.out.println("\nMax Date = " + maxStrDate);
} catch (Exception e) {
System.out.println("Got error:" + e);
}
}
}
OUTPUT
Next Date = 07-14-2014
Next Date = 07-22-2014
Next Date = 07-31-2014
Next Date = 08-01-2014
Next Date = 08-04-2014
Next Date = 08-06-2014
Max Date = 07-31-2014
From the Java Docs....
m Minute in hour
What you want is
M Month in year
Change mm-dd-yyyy to MM-dd-yyyy
You format is incorrect, this
SimpleDateFormat sdf = new SimpleDateFormat("mm-dd-yyyy");
should be
SimpleDateFormat sdf = new SimpleDateFormat("MM-dd-yyyy");
because (per the SimpleDateFormat documentation),
Letter Date or Time Component Presentation Examples
...
M Month in year Month July; Jul; 07
...
m Minute in hour Number 30
can any help, how to get the right date from an String like this "2014-01-10T09:41:16.000+0000"
my code is:
String strDate = "2014-01-10T09:41:16.000+0000";
String day = "";
String format = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";
Locale locale = new Locale("es", "ES");
SimpleDateFormat formater = new SimpleDateFormat(format, locale);
formater.setTimeZone(TimeZone.getTimeZone("Europe/Madrid"));
Calendar cal = Calendar.getInstance();
try {
cal.setTimeInMillis(formater.parse(strDate).getTime());
String offerDate = cal.get(Calendar.DAY_OF_MONTH) + "-" + cal.get(Calendar.MONTH) + "-" + cal.get(Calendar.YEAR);
System.out.println(offerDate);
} catch (Exception e){
System.out.println(e.getMessage());
}
in the result i give something like this: "10-0-2014", i want the result like that "10-01-2014"
thanks in advance :)
The documentation states:
java.util.Calendar.MONTH
MONTH public static final int MONTH Field number for get and set
indicating the month. This is a calendar-specific value. The first
month of the year in the Gregorian and Julian calendars is JANUARY
which is 0; the last depends on the number of months in a year.
-> Counting starts at 0 for Calendar.MONTH
I think the easiest would be to use another formatter object to do the formatting instead of building it yourself:
try {
Date d = new Date(cal.setTimeInMillis(formater.parse(strDate).getTime()));
SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyyy");
String offerDate = format.format(d);
System.out.println(offerDate);
} catch (Exception e){
System.out.println(e.getMessage());
}
I want to convert Date in different Format.
For example,
String fromDate = "2011-04-22";
I want to convert this fromDate as "22nd Apr, 2011"
How can I do this?
Thanks in Advance
What you want is a little tricky because of the "nd" in 22nd. Depending on the day it'll need a different suffix. SimpleDateFormat doesn't support formatting like this. You'll have to write some additional code to get it. Here's an example, however it's limited to working in certain locales like US:
SimpleDateFormat fromFormat = new SimpleDateFormat("yyyy-MM-dd");
SimpleDateFormat toFormat = new SimpleDateFormat("d'__' MMM, yyyy");
String fromDate = "2011-04-22";
Date date = fromFormat.parse(fromDate);
String toDate = toFormat.format(date);
Calendar cal = Calendar.getInstance();
cal.setTime(date);
int day = cal.get(Calendar.DAY_OF_MONTH);
if (day % 10 == 1 && day != 11) {
toDate = toDate.replaceAll("__", "st");
} else if (day % 10 == 2 && day != 12) {
toDate = toDate.replaceAll("__", "nd");
} else if (day % 10 == 3 && day != 13) {
toDate = toDate.replaceAll("__", "rd");
} else {
toDate = toDate.replaceAll("__", "th");
}
System.out.println(toDate);
You can parse the given format using a SimpleDateFormat and then write the 2nd form using a different SimpleDateFormat
SimpleDateFormat from = new SimpleDateFormat("yyyy-MM-dd");
SimpleDateFormat to = new SimpleDateFormat("dd MMM, yyyy");
Date dat = from.parse("2011-04-22");
System.out.println(to.format(dat));
Not sure how to if there is a way to add the 'nd' to '22nd' though.
Following this code to remove ordinal of date. It is running successfully.
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class patrn {
private static String deleteOrdinal(String dateString) {
Pattern p1 = Pattern.compile("([0-9]+)(st|nd|rd|th)");
Matcher m = p1.matcher(dateString);
while (m.find()) {
dateString = dateString.replaceAll(Matcher.quoteReplacement(m.group(0)), m.group(1));
}
return dateString;
}
public static void main(String[] args) {
String dateString = "August 21st, 2012";
SimpleDateFormat sdf = new SimpleDateFormat("MMMM dd, yyyy");
Date emp1joinDate = null;
try {
emp1joinDate = sdf.parse(deleteOrdinal(dateString));
} catch (ParseException e) {
e.printStackTrace();
}
}
}
String dateString = "2011-04-22";
SimpleDateFormat format = new SimpleDateFormat("d MMM, yyyy");
try {
Date parsed = format.parse(dateString);
}
catch(ParseException pe) {
System.out.println("ERROR: Cannot parse \"" + dateString + "\"");
}
I would like to point out that format should depend on Locale... Sure, you can do it like this:
String fromDate = "2011-04-22";
DateFormat incomming = new SimpleDateFormat("yyyy-MM-dd");
DateFormat outgoing = DateFormat.getDateInstance(DateFormat.Long, Locale.US);
try {
Date parsed = incomming.parse(fromDate);
String toDate = outgoing.format(parsed);
}
catch (ParseException pe) {
pe.printStackTrace();
}
Of course, instead of Locale.US you need to pass end user's Locale...
BTW. Instead of lousy SimpleDateFormat you might want to use Apache Commons Lang's FastDateFormat. Please also find DateUtils if you are performing a lot of Date-related operations.