I am parsing multiple String objects containing date in format of mm/dd/yyyy into Date objects using SimpleDateFormatter
Problem I am facing is that, some String contain complete date means it is mm/dd/yyyy while some Strings do not contain year and comes in this format mm/dd
I am using this format to parse dates MM/dd/yyyy but everytime I get a String with only month and day, I get parsing exception.
I want to know, is there any way by which if a year field is missing then I can use something like 0000 or I need to tackle it into exception body only?
Just create 2 separate SimpleDateFormat instances, one that you have and a second one with day and month only. You analyze the string first and pass it to the correct formatter.
Or pass it to the first one and if an exception is thrown, pass it to the second one.
as far as i know you can create an instance of SimpleDateFormat that does not "need" an year.
So just use an try-catch-Block
try{
//try formatting with simpledate instance with year
}catch (Exception thrown when no year){
try{
//try formatting with simple date instace without year
} catch (Exception e)
//something went wrong both did not accept it
}
}
ParseDate(String yourDate);
{
try {
Date reqDate=sdf.parse(yourDate);//sdf is instance of you date formatter
return reqDate;
} catch (ParseException e) {
return null;
e.printStackTrace();
}
}
try Using this function. I think it will work. if thrown exception then null will return. In this way by checking null we know if it is correctly parsed or not.
A code is worth thousand words....
DateFormat df;
Calendar c = Calendar.getInstance();
String s = new String("12/25/2012");
String[] arr = s.split("/");
if(arr.length>2){
c.set(Integer.parseInt(arr[0]), Integer.parseInt(arr[1]),Integer.parseInt(arr[2]));
}
else{
c.set(Integer.parseInt(arr[0]), Integer.parseInt(arr[1]));
}
df = DateFormat.getDateInstance(DateFormat.SHORT);
System.out.println(df.format(c.getTime()));
You can later convert it back to Date object using the df.parse() method...
Related
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.
I have very simple question - I read couple of threads here but I still do not understand how to get simple thing. I want to send string to method and get back joda date. I had no problem to build it up, but return format is 2015-03-11T17:13:09:000+01:00. How can I get desired (e.g. mmm-dd hh:mm) format back from below mentioned method (it mustto be a dateTime for sorting purposes on FX form)? I tried to gamble with another dateTimeFormatter but had no luck. Thank you very much in advance
public static DateTime stringToDateTime(String textDate) throws ParseException
{
DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss.SSS");
DateTime jodaTime = dateTimeFormatter.parseDateTime(textDate);
return jodaTime;
}
What do you mean by "return format"? "Format" term here could only be related to a string representation of a DateTime object. That means you should specify format of your input string (what you've already done in your code) - and a corresponding DateTime object will be created. After that you probably use toString() to check the results, but DateTime.toString() uses ISO8601 format (yyyy-MM-ddTHH:mm:ss.SSSZZ) according to JavaDoc - that gives you your 2015-03-11T17:13:09:000+01:00 result.
So to get it as desired you could try using toString(String pattern) method with format you need. But once again - it's just an output format to convert DateTime to String, it doesn't affect the datetime stored in your DateTime object.
I just use Calendar object so this is a possible way to do it:
static String stringToDateTime(String textDate) {
Calendar c = new GregorianCalendar();
// How you want the input to be formatted
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
Date date = df.parse(textDate);
c.setTime(date);
} catch (ParseException e) {
e.printStackTrace();
}
// How do you want to print your date
df= new SimpleDateFormat("dd-MM-yy");
return df.format(c.getTime());
}
// input
String myDate = "2015-04-15 14:25:25";
System.out.println(stringToDateTime(myDate));
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
Accidentally passing in a phone number string into the format method of SimpleDateFormat sometimes results in a valid date being parsed.
As an example, passing the number "518-123-4567" (literal, with hyphens) somehow results in the date "11/23/0517 05:27 AM"
We are using this in an area where a String could represent a number of different things, and we were under the assumption that a string with digits and hyphens in the way that a phone number is typically written would fail when parsed as a date. Our code simply checks to ParseException, and accepts anything that does not throw such an exception as valid. Why doesn't this sort of string fail parsing? Is there a better way to check to see if a string could potentially be or not be a date?
private static Date getPromisedDate(String promisedText) {
SimpleDateFormat promsiedDateTimeFormat = new SimpleDateFormat("yyyyMMddHHmm");
if(null != promisedText) {
try {
return promsiedDateTimeFormat.parse(promisedText);
}
catch (ParseException e) { }
}
return null;
}
Your SimpleDateFormat is in "lenient" mode - which is very lenient indeed. If you use
promsiedDateTimeFormat.setLenient(false);
it will throw an exception as you'd expect when you try to parse the bogus data.
Personally I think it should be strict by default, but...
From DateFormat#parse(String):
Parses text from the beginning of the given string to produce a date. The method may not use the entire text of the given string.
So, the method might not parse the entire string. It will stop at the position, where the pattern stops matching. In your case, the matching is done in these ways:
yyyy MM dd HH mm
518 -1 23 -4 567
The year parsing yyyy stops at first -, as it can't be parsed as year. So, the year is 518. Then month is taken as -1, then 23 goes as dd, so on.
You can use the overloaded version of parse method and pass a ParsePosition instance to see the details.
From DateFormat#parse(String, ParsePosition):
By default, parsing is lenient: If the input is not in the form used by this object's format method but can still be parsed as a date, then the parse succeeds. Clients may insist on strict adherence to the format by calling setLenient(false)
So, just set the leniency to false, to stop it from parsing date not matching the format:
promsiedDateTimeFormat.setLenient(false);
For example, on using ParsePosition, suppose you pass the date string as - "518-123-4567abc". Surprisingly, it would also be parsed with leniency set to true, because the last part abc would not be parsed at all. To test this, you can try the following code:
private static Date getPromisedDate(String promisedText) throws Exception {
ParsePosition pp = new ParsePosition(0);
SimpleDateFormat promsiedDateTimeFormat = new SimpleDateFormat("yyyyMMddHHmm");
if(null != promisedText) {
try {
Date date = promsiedDateTimeFormat.parse(promisedText);
// If complete string is not parsed, throw ParseException
if (pp.getIndex() != promisedText.length()) {
throw new ParseException("Unparseable date given: " + promisedText, pp.getIndex());
}
return date;
}
catch (ParseException e) { throw e; }
}
return null;
}
To explain what happened: Year 581, Month -1, day 23, Hour -4, Minute 567. Sum everything up and you will get the resulting date. To avid such results, see Post of JonSkeet
I'm trying to parse many string dates to Date(s), some with time part, others without, with the "dd/MM/yyyy HH:mm" format.
public static Date StringToDate (String format, String theDate) {
SimpleDateFormat df = new SimpleDateFormat(format);
Date retDate = null;
try {
df.setLenient(true);
retDate = df.parse(theDate);
}
catch (ParseException e) {
e.printStackTrace();
}
return (retDate);
}
(here, format is always "dd/MM/yyyy HH:mm").
But this causes an exception, even with setLenient forced at true. Do you know how I may convert to Date a lot of strings formatted like "dd/MM/yyyy HH:mm:ss", but with someones without time, some others without secondes, and still other one with everything ?
If you know that some strings have a time and some don't, and there are no other cases, I'd just check the length of the string. However, if you have many different formats available, I'd try each one in some order that makes sense, until you get a valid date.
I always have two parse strings, and I parse twice; once with date/time and once with date only.