I'm trying to parse a date with the format "" to Date.
DateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
Date date = sdf.parse(dateStr);
String = sdf.format(date);
An example of the dateStr is "2020-04-14 16:34:40.0117372".
I get an error when trying to parse the string, but I don't know why.
The error I'm getting is the following:
java.text.ParseException: Unparseable date: "2020-04-14 16:34:40.0117372"
Why can't I parse this date? How can I do it?
You are using "dd/MM/yyyy" for date format, but you should be using "yyyy-MM-dd" (inverse order, and dashes instead of slashes)
Also I suggest you use modern java.time packages and do something like this:
String str = "2020-04-14 16:34:40.0117372";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSSS");
LocalDateTime dateTime = LocalDateTime.parse(str, formatter);
Edit: Having 7 digits for milliseconds is correct, first digits for milliseconds and the rest for nanoseconds. strange. Usually you want 3 digits because 1000 milliseconds is a second. You likely have nanoseconds, which should be dealt with by this method.
Related
I´m trying to pase the next String using LocalDateTime, but I always get de unparsed text found error:
java.time.format.DateTimeParseException: Text '2020-10-16T18:04:59+0300' could not be parsed at index 24
Need: from 2020-10-16T18:04:59+0300 to 2020-10-16 18:04.
My code:
public String getFormattingData(String sourceData) {
DateTimeFormatter sourceFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ''e", Locale.ENGLISH);
DateTimeFormatter newFormatter = DateTimeFormatter.ofPattern("dd-MM-yyy HH:mm", Locale.ENGLISH);
LocalDate date = LocalDate.parse("2020-10-16T18:04:59+0300", sourceFormatter);
return newFormatter.format(date);
}
What am I doing wrong?
See the related question: Format a date using the new date time API
The source format you are looking for is: "yyyy-MM-dd'T'HH:mm:ssZ" (as mentioned by #Sweeper in his comment)
If you want the HH:mm in the output format, you need to use a LocalDateTime rather than a LocalDate
The code below works for me:
public String getFormattingData(String sourceData) {
DateTimeFormatter sourceFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ", Locale.ENGLISH);
DateTimeFormatter newFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm", Locale.ENGLISH);
LocalDateTime date = LocalDateTime.parse("2020-10-16T18:04:59+0300", sourceFormatter);
return newFormatter.format(date);
result:
16-10-2020 18:04
You just need to correct the date pattern of source date like this:
public static String formatDate(String strDate, String srcPattern, String tgtPattern) {
DateTimeFormatter srcFormatter = DateTimeFormatter.ofPattern(srcPattern, Locale.ENGLISH);
DateTimeFormatter tgtFormatter = DateTimeFormatter.ofPattern(tgtPattern, Locale.ENGLISH);
return tgtFormatter.format(LocalDateTime.parse(strDate, srcFormatter));
}
You can also use SimpleDateFormat:
public static String formatDate(String strDate, String srcPattern,
String tgtPattern) throws ParseException {
SimpleDateFormat srcFormatter = new SimpleDateFormat(srcPattern, Locale.ENGLISH);
SimpleDateFormat tgtFormatter = new SimpleDateFormat(tgtPattern, Locale.ENGLISH);
return tgtFormatter.format(srcFormatter.parse(strDate));
}
And then call it with any pattern that you want:
System.out.println(formatDate("2020-10-16T18:04:59+0300", "yyyy-MM-dd'T'HH:mm:ssZ", "dd-MM-yyy HH:mm"));
Don’t write a method that converts a date and time from a string in one format to a string in a different format. In your program keep dates and times as proper date-time objects. Just like you don’t keep numbers and Boolean values in strings (I hope!) When you receive string input, parse into a date-time object at once. Only when you need to give string output, format into an appropriate string.
When I receive a string containing date, time and UTC offset, like yours does, I prefer to parse it into a OffsetDateTime so I get all the information. It’s easier to throw unneeded information away later than to invent the information that we neglected to parse. Also a LocalDate will not work for your purpose since it doesn’t contain time of day. So you cannot format one into 2020-10-16 18:04 format.
For parsing your string I would use:
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_LOCAL_DATE)
.appendLiteral('T')
.append(DateTimeFormatter.ISO_LOCAL_TIME)
.appendOffset("+HHmm", "Z")
.toFormatter();
String sourceData = "2020-10-16T18:04:59+0300";
OffsetDateTime dateTime = OffsetDateTime.parse(sourceData, formatter);
System.out.println(dateTime);
Output is:
2020-10-16T18:04:59+03:00
The definition of the formatter is longish but has the advantage of reusing predefined formatters for date and time.
For displaying a formatted date and time to the user, don’t you want to use the user’s time zone rather then the offset that happened to be in the string (+03:00 in your case)?
ZoneId zone = ZoneId.of("Antarctica/South_Pole");
DateTimeFormatter newFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm", Locale.ENGLISH);
String formatted = dateTime.atZoneSameInstant(zone).format(newFormatter);
System.out.println(formatted);
17-10-2020 04:04
What went wrong in your code?
As others have said, yyyy-MM-dd'T'HH:mm:ssZ in your format pattern string for parsing parses your entire date-time string of 2020-10-16T18:04:59+0300 nicely. The ''e at the end of the format pattern is the culprit. This would require an additional single quote (apostrophe) and the number of the day of the week to be present (pattern letter e is for localized day of week). Since Java had successfully parsed 24 chars and then failed to parse an apostrophe, it threw the exception mentioning thst the string could not be parsed at index 24.
I need to format a String that looks like this:
"2018-07-20 18:53:46.598000 +02:00:00"
into a DateTime object like this:
20/07/2018 (HH with Timezone applied):53:46
My approach has been:
String dateTimePattern = "dd/MM/yyyy HH:mm:ss";
SimpleDateFormat dateTimeFormat = new SimpleDateFormat(dateTimePattern);
Date feUltModDateTime = dateTimeFormat.parse(feUltMod);
feUltMod = feUltModDateTime.toString();
But I'm getting a parse error:
java.text.ParseException: Unparseable date: "2018-07-20 18:53:46.598000 +02:00:00"
java.time
DateTimeFormatter origFormatter
= DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SSSSSS XXXXX");
DateTimeFormatter desiredFormatter = DateTimeFormatter.ofPattern("dd/MM/uuuu HH:mm:ss");
ZoneId desiredZone = ZoneId.of("America/Fort_Nelson");
String feUltMod = "2018-07-20 18:53:46.598000 +02:00:00";
OffsetDateTime dateTime = OffsetDateTime.parse(feUltMod, origFormatter);
ZonedDateTime dateTimeWithTimeZoneApplied = dateTime.atZoneSameInstant(desiredZone);
feUltMod = dateTimeWithTimeZoneApplied.format(desiredFormatter);
System.out.println(feUltMod);
Output from this snippet is:
20/07/2018 09:53:46
Generally you need two formatters for converting a date or date-time from one format to another: one that specifies the format to convert from and one that specifies the format to convert to.
into a DateTime object like this
A date-time object doesn’t have a format, so in that respect cannot be “like this”. dateTimeWithTimeZoneApplied in the above snippet is in the specified time zone, so has the hours adjusted. After converting to this time zone I have formatted into a string in the format you mentioned, in case you wanted this (I didn’t find it clear).
I am using and recommending java.time, the modern Java date and time API. The date and time classes you were using, Date and SimpleDateFormat, are long outdated and poorly designed, it’s not worth struggling with them. Also SimpleDateFormat supports only milliseconds so can only work correctly with exactly 3 decimals on the seconds, not with the 6 decimals you have got.
Link: Oracle tutorial: Date Time explaining how to use java.time.
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
Date df = new Date();
String yourString = sdf.format(df);
Date parsedDate = sdf.parse(yourString);
Timestamp sqlDate = new java.sql.Timestamp(parsedDate.getTime());
The above code will give you current Timestamp.Timestamp will provide better feasibilty
Here is my code,
SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
Date dft = (Date) format.parse("16-MAY-2018 09:30:22:000");
I am getting below exception
java.text.ParseException: Unparseable date: "16-MAY-2018 09:30:22"
What's to be used to parse milliseconds?
The pattern should be MMM because there are three characters in the month.
You should also prefer java.time classes to the ones you're currently using if you're on Java 8 or above:
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendPattern("dd-MMM-yyyy")
.appendLiteral(' ')
.append(ISO_LOCAL_TIME)
.toFormatter();
LocalDateTime timestamp = LocalDateTime.parse("16-May-2018 09:30:22", formatter);
Use this pattern: dd-MMM-yyyy HH:mm:ss
Date dft = (Date) format.parse("16-05-2018 09:30:22");
OR change it to
SimpleDateFormat format = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss");
you are using dd-MM-yyyy HH:mm:ss, so parsable is
16-05-2018 09:30:22
and if you want 16-MAY-2018 09:30:22 then use
dd-MMM-yyyy HH:mm:ss
"16-MAY-2018 09:30:22" is not parsable with that time format. If you want to parse that you have to change date format to "dd-MMM-yyyy HH:mm:ss". The double M is only for numbered months (so should be 05 for May).
Check the SimpleDateFormat javadoc for more details: here
I need to convert a String containing a date into a date object.
The String will be in the format "yyyy-mm-dd HH:mm:ss" and I want the "MM/dd/yyyy HH:mm:ss a " format as result.
String dateString = "2018-03-20 09:31:31";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm:ss a",
Locale.ENGLISH);
LocalDate date = LocalDate.parse(dateString , formatter);
The code above is throwing an exception.
You have to use two Formatter, one to covert String to LocalDateTime and the other to format this date as you want :
From String to LocalDateTime :
String dateString = "2018-03-20 09:31:31";
LocalDateTime date = LocalDateTime.parse(
dateString,
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss", Locale.ENGLISH)
);
Now From LocalDateTime to String :
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(
"MM/dd/yyyy HH:mm:ss a", Locale.ENGLISH
);
String newDate = date.format(formatter);
System.out.println(newDate);// 03/20/2018 09:31:31 AM
Note : You have to use LocalDateTime instead of just LocalDate, your format contain both date and time, not just date, else you will get an error :
java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: HourOfDay
That's a common error, based on the misconception that dates have formats - but they actually don't.
Date/time objects have only values, and those values - usually numerical - represent the concept of a date (a specific point in the calendar) and a time (a specific moment of the day).
If you have a String, then you don't actually have a date. You have a text (a sequence of characters) that represents a date. Note that all of the strings below are different (they have a different sequence of characters), but all represent the same date (the same values, the same point in the calendar):
2018-03-20 09:31:31
03/20/2018 9:31:31 AM (using USA's format: month/day/year)
Tuesday, March 20th 2018, 09:31:31 am
and many others...
What you want to do is to get one format (one String, one text representing a date) and transform it to another format (anoter String, another different sequence of characters that represents the same date).
In Java (and in many other languages - if not all - btw) you must do it in 2 steps:
convert the String to a date/time object (convert the text to the numerical values) - that's what the parse method does
convert the date/time object to another format (convert the numerical values to another text)
That said, when you call the parse method, you're trying to transform a String (a text, a sequence of characters) into a date/time object. This means that the DateTimeFormatter must have a pattern that matches the input.
The input is 2018-03-20 09:31:31, which is year-month-day hour:minute:second. And the formatter you used to parse it has the pattern MM/dd/yyyy HH:mm:ss a (month/day/year hour:minute:second am/pm).
You used the output pattern (the one that should be used in step 2) to parse the input. That's why you've got an exception: the formatter tried to parse a month with 2 digits followed by a / when the input actually contains a year with 4 digits followed by a -.
You must use a different DateTimeFormatter for each step, using the correct pattern for each case. YCF_L's answer has the code that does the job, I'd just like to add one little detail. The formatter used for the output (step 2) is:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(
"MM/dd/yyyy HH:mm:ss a", Locale.ENGLISH
);
Note that HH is used for the hours. Take a look at the javadoc and you'll see that uppercase HH represents the hour-of-day fields (values from 0 to 23 - so 1 AM is printed as 01 and 1 PM is printed as 13).
But you're also printing the AM/PM field (the a in the pattern), so maybe what you need is actually the lowercase hh, which is the clock-hour-of-am-pm (values from 1 to 12) or even KK (hour-of-am-pm (values from 0 to 11)).
String dateString = "2018-03-20 09:31:31";
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
Date date = formatter.parse(dateInString);
DateFormat df = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
String reportDate = df.format(date );
} catch (ParseException e) {
e.printStackTrace();
}
You need to do a 2 steps conversion:
from your String date time in the wrong format to a (tempoary) LocalDateTime object.
if you still want to only extract the date (Year-Month-day) do a LocalDateTime.toLocalDate()
From this LocalDateTime object into the your String object in the right format
String dateString = "2018-03-20 09:31:31";
DateTimeFormatter formatterForWrongFormat = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_LOCAL_DATE)
.appendLiteral(" ")
.append(DateTimeFormatter.ISO_LOCAL_TIME)
.toFormatter();
//1- from String(wrong format) into datetime object
LocalDateTime dateTime = LocalDateTime.parse(dateString , formatterForWrongFormat);
// 1.1 extract date object (Optional)
LocalDate myDate = dateTime.toLocalDate();
// 2- now from your LocalDateTime to the String in the RIGHT format
DateTimeFormatter formatterForRightFormat = DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm:ss a",
Locale.ENGLISH);
System.out.println("right format: "+dateTime.format(formatterForRightFormat));
you can test this code here
You can use the SimpleDateFormatter which is easier to implement and permit you to change the format of your date easily.
More here : What are the date formats available in SimpleDateFormat class?
Hope this will help you !
String temp_date="07/28/2011 11:06:37 AM";
Date date = new Date(temp_date); //Depricated
SimpleDateFormat sdf = new SimpleDateFormat("MMM-dd-yyyy hh:mm:ss");
String comp_date= sdf.format(date);
System.out.println(comp_date);
This works, But If I use something like this
String temp_date="07/28/2011 11:06:37 AM";
try{
SimpleDateFormat sdf = new SimpleDateFormat("MMM-dd-yyyy hh:mm:ss");
Date comp_date= sdf.parse(temp_date);
System.out.println(comp_date);
}catch(Exception e){
System.out.println(e);
}
This exception is thrown:
java.text.ParseException: Unparseable date: "07/28/2011 11:06:37 AM"
Your parsing pattern is wrong. It does not match the date string representation. The MMM denotes a 3-letter localized month abbreviation, while you have 2-digit month number in your actual date, you need MM. You've also slashes / as date/month/year separator and not -. For the AM/PM marker you also need an a afterwards so that the right hh can be parsed.
This should work:
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss a");
For an explanation of those patterns, read the SimpleDateFormat javadoc.
I believe that your concrete functional requirement is to convert the given date string as specified by the pattern MM/dd/yyyy hh:mm:ss a into another date string format, as specified by the pattern MMM-dd-yyyy hh:mm:ss. In that case, you should then have two SimpleDateFormat instances, one which parses the string in the given pattern to a Date and another which formats the parsed Date to the given pattern. This should do what you want:
String inputDate = "07/28/2011 11:06:37 AM";
Date date = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss a").parse(inputDate);
String outputDate = new SimpleDateFormat("MMM-dd-yyyy HH:mm:ss").format(date);
System.out.println(outputDate); // Jul-28-2011 11:06:37
Note that I changed hh in output to be HH because it would otherwise end up in 1-12 hour representation without an AM/PM marker. The HH represents it as 0-23 hour.
The format you gave the SimpleDateFormat uses - between the month, date, and year. Your string uses slashes.
At first look, it looks as if your format string is wrong.
MMM -- You specified this for the month, but you aren't passing a 3 char month.
Try MM and see if that helps.
Take a look at this for some additional date format information:
http://www.java2s.com/Tutorial/Java/0040__Data-Type/SimpleDateFormat.htm