This question already has answers here:
DateTimeParse Exception
(2 answers)
Closed 2 years ago.
I've tried several methods with Java Joda Time, Date Time with locale and commons-lang and can't get this date formatted.
Input
Mon Dec 28 15:18:16 UTC 2020
Output
Desired output format yyyy-MM-dd HH:mm:ss.SSS
When I use a format pattern like EEE MMM dd HH:mm:ss Z YYYY the date is off my a couple days and the timezone seems completely wrong.
Formatter:
private static final DateTimeFormatter DATE_TIME_FORMATTER =
DateTimeFormatter
.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")
.withLocale(Locale.US)
.withZone(ZoneId.systemDefault());
DateUtils.parseDate (Optional
.ofNullable(record)
.map(CustomerModel::getCustomerAudit)
.map(customerAudit::getCreated)
.map(auditItem::getDate).get ().toString (), "EEE MMM dd HH:mm:ss YYYY")
When debugging parsing issues, if possible, reverse the operation and generate the text you're supposed to be parsing, to verify the parsing rules, i.e. the date format string. This applies to date parsing, JAXB parsing, and any other (de)serializing operation that is bi-directional. It makes finding conversion rule issues a lot easier.
So, let us check the format string in the question, with the shown date value:
ZonedDateTime dateTime = ZonedDateTime.of(2020, 12, 28, 15, 18, 16, 0, ZoneOffset.UTC);
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss Z YYYY", Locale.US);
System.out.println(dateTime.format(fmt));
Output
Mon Dec 28 15:18:16 +0000 2021
Oops! That doesn't fit the expected output, aka the input we desire to parse:
Mon Dec 28 15:18:16 UTC 2020
So what went wrong?
The year is wrong because it's supposed to be uuuu (year), not YYYY (week-based-year).
The time zone is wrong because Z does support a text representation. Use VV or z instead.
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss z uuuu", Locale.US);
ZonedDateTime dateTime = ZonedDateTime.parse("Mon Dec 28 15:18:16 UTC 2020", fmt);
System.out.println(dateTime);
System.out.println(dateTime.format(DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SSS")));
Output
2020-12-28T15:18:16Z[UTC]
2020-12-28 15:18:16.000
As you can see, it now parsed correctly.
The code in the question makes little sense:
It is formatting a Date value to text using toString(), just to attempt parsing that back.
It is using Optional for simple null-handling (which is discouraged), but then unconditionally calling get(), which means a null value will throw exception anyway.
The code should be:
record.getCustomerAudit().getCreated().getDate().toInstant()
This of course makes the entire question moot.
Works fine for me.
String s = "Mon Dec 28 15:18:16 UTC 2020";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss VV yyyy",
Locale.ENGLISH);
ZonedDateTime zdt = ZonedDateTime.parse(s, formatter);
formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS", Locale.ENGLISH);
System.out.println(zdt.format(formatter));
Output is
2020-12-28 15:18:16.000
Am I missing something?
Have you tried with SimpleDateFormat?
String dateString = "Mon Dec 28 15:18:16 UTC 2020";
SimpleDateFormat input = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy", Locale.ENGLISH);
SimpleDateFormat output = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.ENGLISH);
System.out.println(output.format(input.parse(dateString)));
With timezone:
String dateString = "Mon Dec 28 15:18:16 UTC 2020";
SimpleDateFormat input = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy");
SimpleDateFormat output = new SimpleDateFormat("yyyy-MM-dd z HH:mm:ss.SSS");
input.setTimeZone(TimeZone.getTimeZone("UTC"));
output.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(output.format(input.parse(dateString)));
Related
This question already has answers here:
Java date format - including additional characters
(5 answers)
Closed 2 years ago.
I want to display time as "02 Sep 2020 at 12:24 AM" (mind the at between date and time).
The current format I am using is "dd MMM yyyy hh:mm aaa",
which displays time as "28 Aug 2020 11:32 AM".
How can I put an at before the time?
You can add string literals to a date format by surrounding them with single quotes ('):
SimpleDateFormat sdf = new SimpleDateFormat("dd MMM yyyy 'at' hh:mm aaa");
// Here -------------------------------------------------^--^
String formatted = sdf.format(myDateVariable);
If you use java.time for this, you can define a java.time.format.DateTimeFormatter to parse a String, use it to parse the String to a java.time.LocalDateTime and define & use another DateTimeFormatter that includes the at escaping it in the pattern by enclosing it in single-quotes:
public static void main(String[] args) {
String dateTime = "02 Sep 2020 12:24 AM";
DateTimeFormatter parserDtf = DateTimeFormatter.ofPattern("dd MMM uuuu hh:mm a",
Locale.ENGLISH);
DateTimeFormatter outputDtf = DateTimeFormatter.ofPattern("dd MMM uuuu 'at' hh:mm a",
Locale.ENGLISH);
LocalDateTime ldt = LocalDateTime.parse(dateTime, parserDtf);
System.out.println(ldt.format(outputDtf));
}
This code produces the output
02 Sep 2020 at 12:24 AM
Just wrap the word in single quotes.
"dd MMM yyyy 'at' hh:mm aaa"
SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy 'at' HH:mm:ss z");
Date date = new Date(System.currentTimeMillis());
System.out.println(formatter.format(date));
I have a date object with
"Sun Apr 26 11:44:00 GMT+03:00 2020"
I tried to format it but it will always ignore the timezone "+3:00" and show the hour without changing it
what I have tried :
val sdf = SimpleDateFormat("dd MM yyyy HH:mm:ss", Locale.US)
return sdf.format(this)
I don't exactly understand your question but I guess you meant you need DateTime related to a particular zone. In kotlin we've ZonedDateTime class
import java.time.ZoneId
import java.time.ZonedDateTime
import java.time.format.DateTimeFormatter
import java.time.format.FormatStyle
val londonZone = ZoneId.of("Europe/London")
val londonCurrentDateTime = ZonedDateTime.now(londonZone)
println(londonCurrentDateTime) // Output: 2018-01-25T07:41:02.296Z[Europe/London]
val londonDateAndTime = londonCurrentDateTime.format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL, FormatStyle.MEDIUM))
println(londonDateAndTime) // Output: Thursday, January 25, 2018 7:40:34 AM
You also might need to take a look at LocalDateTime class.
If you just want to parse a datetime String with the given pattern and then convert the result to a different offset, you can go like this:
fun main() {
// provide the source String
val datetime = "Sun Apr 26 11:44:00 GMT+03:00 2020"
// provide a pattern for parsing
val parsePattern = "E MMM dd HH:mm:ss O yyyy";
// parse the String to an OffsetDateTime
val parsedOffsetDateTime = java.time.OffsetDateTime.parse(
datetime,
java.time.format.DateTimeFormatter.ofPattern(parsePattern))
// print the result using the default format
println(parsedOffsetDateTime)
// then get the same moment in time at a different offset
val adjustedOffsetDateTime = parsedOffsetDateTime.withOffsetSameInstant(
java.time.ZoneOffset.of("+02:00"))
// and print that, too, in order to see the difference
println(adjustedOffsetDateTime)
}
which produces the output
2020-04-26T11:44+03:00
2020-04-26T10:44+02:00
The format string depends on which SimpleDateFormat you use:
If using java.text.SimpleDateFormat with API Level 24+, the format string needs to be:
"EEE MMM d HH:mm:ss 'GMT'XXX yyyy"
If using android.icu.text.SimpleDateFormat, the format string needs to be:
"EEE MMM d HH:mm:ss OOOO yyyy".
Demo (in plain Java)
TimeZone.setDefault(TimeZone.getTimeZone("Asia/Jerusalem"));
Date date = new Date(1587890640000L); // date object with "Sun Apr 26 11:44:00 GMT+03:00 2020"
SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM d HH:mm:ss 'GMT'XXX yyyy", Locale.US);
String dateString = sdf.format(date);
System.out.println("Formatted : " + dateString);
Date parsed = sdf.parse(dateString);
System.out.println("Parsed back: " + parsed);
System.out.println("Millis since Epoch: " + parsed.getTime());
Output
Formatted : Sun Apr 26 11:44:00 GMT+03:00 2020
Parsed back: Sun Apr 26 11:44:00 IDT 2020
Millis since Epoch: 1587890640000
This question already has answers here:
Formatting LocalDate in Java: What's the pattern for "March 26 2020"
(2 answers)
Closed 1 year ago.
I'm trying to parse this string in the following way but I get an exception. Can anyone help me please?
String dateStr = "Thu 14 Feb 2019 15:05:48 +0200";
LocalDateTime datetime = LocalDateTime.parse(dateStr, DateTimeFormatter.ofPattern("EEE d MMM yyyy HH:mm:ss Z"));
Exception:
java.time.format.DateTimeParseException: Text 'Thu 14 Feb 2019 15:05:48 +0200' could not be parsed at index 0
String dateStr = "Thu 14 Feb 2019 15:05:48 +0200";
Locale bLocale = new Locale.Builder().setLanguage("en").setRegion("US").build();
LocalDateTime datetime = LocalDateTime.parse(dateStr, DateTimeFormatter.ofPattern("EEE d MMM yyyy HH:mm:ss Z", bLocale));
System.out.println(datetime);
You should create a locale as the parameter.
I'm not sure, but I think EEE only works if you specify locale. Anyway, it will work if you just ignore the day of the month.
LocalDateTime datetime = LocalDateTime.parse(
dateStr.substring(4), // skip "Thu "
DateTimeFormatter.ofPattern("d MMM yyyy HH:mm:ss Z"));
I am getting the above error, but to me everything seems to be correct.
What I am doing wrong?
DateTimeFormatter simpleDateFormatInput= DateTimeFormat.forPattern("EEE, dd MMM yyyy HH:mm:ss Z");
DateTime datetime = simpleDateFormatInput.parseDateTime(pubDate);
Where pubDate is Sat, 30 Jan 2016 12:23:53 +0100
The day and/or month from your input String may not match those from your default Locale. Try
DateTimeFormatter simpleDateFormatInput =
DateTimeFormat.forPattern("EEE, dd MMM yyyy HH:mm:ss Z").withLocale(Locale.US);
I use below code in Java and works perfect!
SimpleDateFormat format = new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss z");
Date date = format.parse("Sun, 11 May 2014 23:11:51 +0430");
but in Android I got exception !
java.text.ParseException: Unparseable date: "Sun, 11 May 2014 23:11:51 +0430" (at offset 0)
what's wrong ?!
The problem is that the code will execute correctly if the default locale is english, otherwise will throw an exception. You can solve it adding the correct Locale.
//Locale locale = new Locale("en-US");
Locale locale = Locale.US;
SimpleDateFormat format = new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss z", locale);
Date date = format.parse("Sun, 11 May 2014 23:11:51 +0430");
Probably the android device has a different language setting. Consider using a constant Locale as RC stated in the comment, in that case you wouldn't need the extra variable, use the constant directly in the constructor.
SimpleDateFormat format = new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss z", Locale.US);
Date date = format.parse("Sun, 11 May 2014 23:11:51 +0430");
If the Locale on your device is German for example your code executes if you parse this date:
SimpleDateFormat format = new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss z", Locale.GERMAN);
Date date = format.parse("So, 11 Mai 2014 23:11:51 +0430");