Java Unparseable Date difference in formats - java

How to differentiate between data-entry being (a) invalid date or (b) invalid format?
I have the following code for handling date inputs from an text file.
public boolean dateIsValid(String date) {
DateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");
formatter.setLenient(false);
try {
Date dateParsed = (Date) formatter.parse(date);
} catch (ParseException e) {
e.printStackTrace();
}
return false;
}
I have everything working as I want it to. The only problem I have is I am unable to differentiate the different parse exceptions thrown. For example:
if String date = 18/10/2012 --> java.text.ParseException: Unparseable date: "18/10/2012"
if String date = 2-12-2001 --> java.text.ParseException: Unparseable date: "2-12-2001"
As you can see, both the wrong formats throw the same error. How can I differentiate them so that I can handle them differently?
EDIT
To be more precise, in case of date 18/10/2012, I should throw an invalid date error and in the case of date 2-12-2001, I need to throw an invalid format exception. I dont need to handle different formats. I just need a way of getting different exceptions for these two different cases.

The issue seems to be at this line
DateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");
For the first error it looks like that the date is coming first and the month later so it should be like
DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
Second error shows the incorrect format of the date supplied since it is containing - whereas you are expecting the format containing / ie like
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy");
If you want to handle different formats then try like this:
String[] formatDates= {"MM/DD/yyyy", "dd/MM/yyyy", "MM-dd-yyyy","dd-MM-yyyy"};
Date tryParse(String dateString)
{
for (String formatDate: formatDates)
{
try
{
return new SimpleDateFormat(formatDate).parse(dateString);
}
catch (ParseException e) {}
}
return null;
}

Unless you write code to parse the date strings yourself, you will not know why the format threw the exception.
I recommend a variation of the R. T. answer above.
Specifically, instead of creating a new formatter every time, create four (in that example) formatters at startup (in the constructor or in a static block).

I would use
public Date dateIfValid(String format, String date) {
DateFormat formatter = new SimpleDateFormat(format);
formatter.setLenient(false);
try {
return dateParsed = (Date) formatter.parse(date);
} catch (ParseException e) {
return null;
}
}
Date mmddyy = dateIfavlid("MM/dd/yy", date.replace("[^0-9]", "/"));
Date ddmmyy = dateIfavlid("dd/MM/yy", date.replace("[^0-9]", "/"));
if (mmddyy != null && ddmmyy == null) {
Note: this can be used to detect ambigous dates such as 01/02/03 which might be 3rd Feb 2001

Related

String to Date Conversion mm/dd/yy to YYYY-MM-DD in java [duplicate]

This question already has answers here:
Java Date Error
(8 answers)
Closed 4 years ago.
I want to convert String values in the format of mm/dd/yy to YYYY-MM-DD Date. how to do this conversion?
The input parameter is: 03/01/18
Code to convert String to Date is given below
public static Date stringToDateLinen(String dateVlaue) {
Date date = null;
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
try {
date = formatter.parse(dateVlaue);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
When tried to convert using this method it shows the following error
java.text.ParseException: Unparseable date: "03/01/18"
As you say the input is in a different format, first convert the String to a valid Date object. Once you have the Date object you can format it into different types , as you want, check.
To Convert as Date,
SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yy");
date = formatter.parse(dateVlaue);
To Print it out in the other format,
SimpleDateFormat formatter1 = new SimpleDateFormat("yyyy-MM-dd");
dateString = formatter1.format(date)
You are writing it the wrong way. In fact, for the date you want to convert, you need to write
SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yy");
The format you are passing to SimpleDateFormat is ("yyyy-MM-dd") which expects date to be in form 2013-03-01 and hence the error.
You need to supply the correct format that you are passing your input as something like below
public static Date stringToDateLinen(String dateVlaue) {
Date date = null;
SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yy");
try {
date = formatter.parse(dateVlaue);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
The solution for the above problem
Convert the String date value in the Format of "dd/mm/yy" to Date.
By using the converted Date can able to frame the required date format.
The method has given below
public static String stringToDateLinen(String dateVlaue) {
Date date = null;
SimpleDateFormat formatter = new SimpleDateFormat("dd/mm/yy");
String dateString = null;
try {
// convert to Date Format From "dd/mm/yy" to Date
date = formatter.parse(dateVlaue);
// from the Converted date to the required format eg : "yyyy-MM-dd"
SimpleDateFormat formatter1 = new SimpleDateFormat("yyyy-MM-dd");
dateString = formatter1.format(date);
} catch (ParseException e) {
e.printStackTrace();
}
return dateString;
}
EDIT: Your question said “String values in the format of mm/dd/yy”, but I understand from your comments that you meant “my input format is dd/mm/yy as string”, so I have changed the format pattern string in the below code accordingly. Otherwise the code is the same in both cases.
public static Optional<LocalDate> stringToDateLinen(String dateValue) {
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("dd/MM/yy");
try {
return Optional.of(LocalDate.parse(dateValue, dateFormatter));
} catch (DateTimeParseException dtpe) {
return Optional.empty();
}
}
Try it:
stringToDateLinen("03/01/18")
.ifPresentOrElse(System.out::println,
() -> System.out.println("Could not parse"));
Output:
2018-01-03
I recommend you stay away from SimpleDateFormat. It is long outdated and notoriously troublesome too. And Date is just as outdated. Instead use LocalDate and DateTimeFormatter from java.time, the modern Java date and time API. It is so much nicer to work with. A LocalDate is a date without time of day, so this suites your requirements much more nicely than a Date, which despite its name is a point in time. LocalDate.toString() produces exactly the format you said you desired (though the LocalDate doesn’t have a format in it).
My method interprets your 2-digit year as 2000-based, that is, from 2000 through 2099. Please think twice before deciding that this is what you want.
What would you want to happen if the string cannot be parsed into a valid date? I’m afraid that returning null is a NullPointerException waiting to happen and a subsequent debugging session to track down the root cause. You may consider letting the DateTimeParseException be thrown out of your method (just declare that in Javadoc) so the root cause is in the stack trace. Or even throw an AssertionError if the situation is not supposed to happen. In my code I am returning an Optional, which clearly signals to the caller that there may not be a result, which (I hope) prevents any NullPointerException. In the code calling the method I am using the ifPresentOrElse method introduced in Java 9. If not using Java 9 yet, use ifPresent and/or read more about using Optional elsewhere.
What went wrong in your code?
The other answers are correct: Your format pattern string used for parsing needs to match the input (not your output). The ParseException was thrown because the format pattern contained hyphens and the input slashes. It was good that you got the exception because another problem is that the order of year, month and day doesn’t match, neither does the number of digits in the year.
Link
Oracle tutorial: Date Time explaining how to use java.time.

Convert `Java.lang.String` TO `oracle.sql.TIMESTAMPTZ`

I have these following Java.lang.String values that represents String value of TIMESTAMPTZ. I need to convert these Java.lang.String TO oracle.sql.TIMESTAMPTZ.
"2016-04-19 17:34:43.781 Asia/Calcutta",
"2016-04-30 20:05:02.002 8:00",
"2003-11-11 00:22:15.0 -7:00",
"2003-01-01 02:00:00.0 -7:00",
"2007-06-08 15:01:12.288 Asia/Bahrain",
"2016-03-08 17:17:35.301 Asia/Calcutta",
"1994-11-24 11:57:17.303"
I tried it by many ways.
Sample 1:
Tried it by using SimpleDateFormat
String[] timeZoneValues = new String[]{"2016-04-19 17:34:43.781 Asia/Calcutta", "2016-04-30 20:05:02.002 8:00", "2003-11-11 00:22:15.0 -7:00", "2003-01-01 02:00:00.0 -7:00", "2007-06-08 15:01:12.288 Asia/Bahrain", "2016-03-08 17:17:35.301 Asia/Calcutta", "1994-11-24 11:57:17.303"};
for(String timeZoneValue: timeZoneValues){
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS XXX");
try {
simpleDateFormat.parse(timeZoneValue);
} catch (ParseException e) {
e.printStackTrace();
}
}
That thrown an Exception:
java.text.ParseException: Unparseable date: "2016-04-19 17:34:43.781 Asia/Calcutta"
at java.text.DateFormat.parse(DateFormat.java:357)
Sample 2:
Tried it by converting these String values directly into Timestamp or oracle.sql.TIMESTAMPTZ
String parse = "2016-04-19 17:34:43.781 8:00";
try {
Timestamp timestamp = Timestamp.valueOf("2016-04-19 17:34:43.781 8:00");
}catch (Exception ex){
ex.printStackTrace();
}
Exception:
java.lang.NumberFormatException: For input string: "781 8:000"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:492)
at java.lang.Integer.parseInt(Integer.java:527)
at java.sql.Timestamp.valueOf(Timestamp.java:253)
Sample 3:
String parse = "2016-04-19 17:34:43.781 Asia/Calcutta";
DateTimeFormatter dateTimeFormatter = ISODateTimeFormat.dateTimeNoMillis();
DateTime dateTime = dateTimeFormatter.parseDateTime(parse);
Timestamp timeStamp = new Timestamp(dateTime.getMillis());
Exception:
Invalid format: "2016-04-19 17:34:43.781 Asia/Calcutta" is malformed at " 17:34:43.781 Asia/Calcutta"
Sample 4:
try {
TIMESTAMPTZ timestamptz = new TIMESTAMPTZ(connection, (String) colValue);
}catch (Exception ex){
ex.printStackTrace();
}
Exception:
java.lang.IllegalArgumentException: Timestamp format must be yyyy-mm-dd hh:mm:ss[.fffffffff]
at java.sql.Timestamp.valueOf(Timestamp.java:249)
at oracle.sql.TIMESTAMPTZ.toBytes(TIMESTAMPTZ.java:1919)
at oracle.sql.TIMESTAMPTZ.<init>(TIMESTAMPTZ.java:253)
I am trying to insert the TIMESTAMPTZ value into Oracle database using Apache Metamodel and I have Java 1.7 installed on my system.
Your timestamps are not in a standard java parseable formats. So in order to parse them you need to write custom code for handling such formats.
Couple of observations:
Asia/Calcutta is not a valid Parseable TimeZone, hence you need some
mechanism to get corresponding timezone.
8:00 is also not a valid Parseable Timezone in java, hence you need
some mechanism to format it in a valid value +08:00
Keeping above points in mind, following code will do the needful for you.
SimpleDateFormat dateFormatTZGeneral = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS z");
SimpleDateFormat dateFormatTZISO = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS XXX");
SimpleDateFormat dateFormatWithoutTZ = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
String[][] zoneStrings = DateFormatSymbols.getInstance().getZoneStrings();
Date date = null;
String[] timeStampSplits = timestamp.split(" ");
if(timeStampSplits.length>2) {
String timezone = timeStampSplits[2];
//First Case Asia/Calcutta
if(Character.isAlphabetic(timezone.charAt(timezone.length()-1))) {
for(String[] zoneString: zoneStrings) {
if(zoneString[0].equalsIgnoreCase(timezone)) {
timeStampSplits[2] = zoneString[2];
break;
}
}
timestamp = createString(timeStampSplits," ");
date = getDate(timestamp, dateFormatTZGeneral);
} else {
//Second Case 8:00
timeStampSplits[2] = formatTimeZone(timeStampSplits[2]);
timestamp = createString(timeStampSplits," ");
date = getDate(timestamp, dateFormatTZISO);
}
} else {
// Third Case without timezone
date = getDate(timestamp, dateFormatWithoutTZ);
}
System.out.println(date);
TIMESTAMPTZ oraTimeStamp = new TIMESTAMPTZ(<connection object>,new java.sql.Timestamp(date.getTime());
Above code uses following utility methods
private static Date getDate(String timestamp, SimpleDateFormat dateFormat) {
Date date = null;
try {
date = dateFormat.parse(timestamp);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return date;
}
private static String createString(String[] contents, String separator) {
StringBuilder builder = new StringBuilder();
for (String content : contents) {
builder.append(content).append(separator);
}
builder.deleteCharAt(builder.length()-separator.length());
return builder.toString();
}
private static String formatTimeZone(String timeZone) {
String[] timeZoneSplits = timeZone.split(":");
DecimalFormat formatter = new DecimalFormat("+##;-#");
formatter.setMinimumIntegerDigits(2);
timeZoneSplits[0] = formatter.format(Integer.parseInt(timeZoneSplits[0]));
return createString(timeZoneSplits, ":");
}
This code is specifically written to cater your timestamp examples, any deviation might not be handled by this and it will need more customization.
Hope this helps you.
You have to parse the date according to the data coming i.e dynamic. For information about What constant used by android you have to follow the link
and in case of Java you have to follow link
Here is the code snippet of some different format
Sample 1
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS zzzz");
Date date = null;
try {
date = sdf.parse("2016-04-19 17:34:43.781 Pacific Standard Time");
Log.e("date",""+date);
} catch (ParseException e) {
e.printStackTrace();
}
sdf.setTimeZone(TimeZone.getTimeZone("IST"));
System.out.println(sdf.format(date));
Sample 2
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS z");
Date date = null;
try {
date = sdf.parse("2016-04-19 17:34:43.781 -08:00");
Log.e("date",""+date);
} catch (ParseException e) {
e.printStackTrace();
}
sdf.setTimeZone(TimeZone.getTimeZone("IST"));
System.out.println(sdf.format(date));
Sample 3
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
Date date = null;
try {
date = sdf.parse("2016-04-19 17:34:43.781");
Log.e("date",""+date);
} catch (ParseException e) {
e.printStackTrace();
}
sdf.setTimeZone(TimeZone.getTimeZone("IST"));
System.out.println(sdf.format(date));
So as per these three set of sample you can parse any type of date time except the one format i.e "2016-04-19 17:34:43.781 Asia/Calcutta" as the time zone Asia/Calcutta or Asia/Bahrain can not get read by android or java. This is the format which gets supported by PHP as per my understanding. SO If you want to parse these type of format then I guess you have to write your custom SimpleDateFormat and have to identify these content and perform the calculation according to your need.
The Timestamp strings are in different format,
Ex-Here SimpleDateFormat uses pattern :
'yyyy-MM-dd HH:mm:ss.SSS XXX'
where X is to represent timezone in [ISO 8601 time zone][1] format.For this
timezone valid Timestamp Strings are (-08; -0800; -08:00).So,'Asia/Kolkata'
will not be parsed for Sample 1.
There are three type of Timezone pattern to be assigned to SimpleDateFormat.
**'Z'** - RFC 822 time zone.
**'z'** - General time zone.
**'X'** - ISO 8601 time zone.
So,either use different SimpleDateFormat's,or convert Timezone of all timestamp into same pattern of timezone and use a single SimpleDateFormat.

How do I convert 09/24/2015 into 20150924?

How can one convert the input date formatted as mm/dd/yyyy into an integer formatted as yyyymmdd.
I tried:
SimpleDateFormat ft = new SimpleDateFormat("yyyyMMdd");
String input = "09/25/2015";
String t;
t = ft.format(input);
and
SimpleDateFormat ft = new SimpleDateFormat("yyyyMMdd");
String input = "09/25/2015";
String t;
try{
t = ft.parse(input);
}catch (ParseException e){
}
}
Neither of these worked; The first one gave me a runtime error.
Assuming the input date is in type of a String:
String strDate = "09/24/2015";
String[] tok = strDate.split("/");
System.out.println(tok[2] + tok[0] + tok[1]);
You can split them into tokens.
You can do it in two ways: String manipulation, or date parsing and reformatting.
// String substitution using regular expression
System.out.println("09/24/2015".replaceFirst("^(\\d{2})/(\\d{2})/(\\d{4})$", "$3$1$2"));
// Lenient date reformatting
System.out.println(new SimpleDateFormat("yyyyMMdd").format(new SimpleDateFormat("MM/dd/yyyy").parse("09/24/2015")));
String substitution will do nothing for bad formats, and will convert good formats even if date values are bad.
The date reformatting will fail (exception) for bad formats, and will "adjust" bad date values (see below), because it's lenient by default. Change to strict to also fail on bad date values:
// Strict date reformatting
SimpleDateFormat mdy = new SimpleDateFormat("MM/dd/yyyy");
mdy.setLenient(false);
SimpleDateFormat ymd = new SimpleDateFormat("yyyyMMdd");
System.out.println(ymd.format(mdy.parse("09/24/2015")));
The above three methods will all print:
20150924
To show the effect of bad date values,a dn with bad formats:
// Showing results with bad date
System.out.println("09/34/2015".replaceFirst("^(\\d{2})/(\\d{2})/(\\d{4})$", "$3$1$2"));
System.out.println(new SimpleDateFormat("yyyyMMdd").format(new SimpleDateFormat("MM/dd/yyyy").parse("09/34/2015")));
try { ymd.format(mdy.parse("09/34/2015")); } catch (Exception e) { System.out.println(e); }
// Showing results with bad formats
System.out.println("Hello".replaceFirst("^(\\d{2})/(\\d{2})/(\\d{4})$", "$3$1$2"));
try { new SimpleDateFormat("MM/dd/yyyy").parse("Hello"); } catch (Exception e) { System.out.println(e); }
try { ymd.format(mdy.parse("Hello")); } catch (Exception e) { System.out.println(e); }
Output
20150934
20151004
java.text.ParseException: Unparseable date: "09/34/2015"
Hello
java.text.ParseException: Unparseable date: "Hello"
java.text.ParseException: Unparseable date: "Hello"

Android date format parse throwing an Unhandled Exception

I'm storing dates in a database as a single string in the format "2 15 2015" (presumably "M d yyyy"?). strDate in the code below contains the return value of a method that grabs the date. I want to parse the date so as to set a datepicker. Based on the examples in Java string to date conversion
I've created the following code for parsing the date, but am getting an "Unhandled Exception: java.text.ParseException" at
Date date = format.parse(strDate);
Scratching my head.
Calendar mydate = new GregorianCalendar();
String strDate = datasource.get_Column_StrVal(dbData,
MySQLiteHelper.dbFields.COLUMN_SPECIAL_DAYS_DATE);
SimpleDateFormat format = new SimpleDateFormat("M d yyyy", Locale.ENGLISH);
Date date = format.parse(strDate);
mydate.setTime(date);
You are getting this compile-time error because you are not handling the ParseException that the parse method throws. This is necessary because ParseException is not a runtime exception (it is a checked exception since it extends directly from java.lang.Exception).
You need to surround your code with try/catch to handle the exception, like this :
try {
SimpleDateFormat format = new SimpleDateFormat("M d yyyy", Locale.ENGLISH);
Date date = format.parse(strDate);
mydate.setTime(date);
} catch (ParseException e) {
//handle exception
}
Well, you indeed have it. Just surround it with try/catch as the compiler will hint you.

error on converting string to date in java

2014-04-23T18:30:00.000Z need to convert in this format yyyy-MM-dd'T'hh:mm:sszzz in java
I am using this
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.zzzZ");
Date newfromDate = new Date();
try {
//Convert into date
newfromDate = (Date)formatter.parse(fromDate);
// get required Format of date in string format
SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:sszzz");
} catch (ParseException e) {
e.printStackTrace();
}
but this is not working
error :- java.text.ParseException: Unparseable date: "2014-03-31T18:30:00.000Z"
try this
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX").parse(s);
or this
javax.xml.bind.DatatypeConverter.parseDateTime("2014-04-23T18:30:00.000Z");
the last version is supposed to be faster (no need to parse pattern) and thread-safe

Categories