Date formatting using JODA - Malformed at AM - java

I am trying to format the following date
Thu, 15 Jan 2015, 9:56 AM
Using the following:
public String parse(String oldDate){
final String OLD_FORMAT = "EEE, d MMM yyyy, HH:mm:ss zz";
final String NEW_FORMAT = "yyyy/MM/dd";
// August 12, 2010
String oldDateString = oldDate;
String newDateString;
DateTimeFormatter formatterOld = DateTimeFormat.forPattern(OLD_FORMAT);
DateTimeFormatter formatterNew = DateTimeFormat.forPattern(NEW_FORMAT);
LocalDate localDate = formatterOld.parseLocalDate( oldDateString );
return newDateString = formatterNew.print( localDate );
}
I am getting a
Caused by: java.lang.IllegalArgumentException: Invalid format: "Thu, 15 Jan 2015, 9:56 AM" is malformed at " AM"
How do I represent AM/PM properly in that date format? I tried using Z but get the same and changed to zz but invain. What is the correct representation for AM/PM?
I also checked with "hh:mm a" but that again does nto seem to help.

Z and z are for TimeZones - you want a which is the format-code for half-day.
The formatting codes are describe in the JavaDoc for org.joda.time.format.DateTimeFormat
The code below works for me (running on a Java 8 JRE with Joda 2.6)
public static void main(String[] args) {
String format = "EEE, d MMM yyyy, HH:mm a";
DateTimeFormatter formatter = DateTimeFormat.forPattern(format);
final LocalDate date = formatter.parseLocalDate("Thu, 15 Jan 2015, 9:56 AM");
System.out.println(date);
}

Related

Changing date format in Android getting ParseException [duplicate]

This question already has answers here:
Java - Unparseable date
(3 answers)
how to parse output of new Date().toString()
(4 answers)
Closed 2 years ago.
I'm new in Android and Java development.
I have this day type "Fri Jan 27 00:00:00 GMT+00:00 1995". <-- (input)
I want to get "1995/27/01" <-- (output)
I'm using this code :
String inputPattern = "EEE MMM dd HH:mm:ss z yyyy";
String outputPattern = "yyyy-MM-dd";
SimpleDateFormat inputFormat = new SimpleDateFormat(inputPattern);
SimpleDateFormat outputFormat = new SimpleDateFormat(outputPattern);
Date date = inputFormat.parse("Fri Jan 27 00:00:00 GMT+00:00 1995");
String str = outputFormat.format(date);
but I get a ParseException.
Any idea why?
If you were using java.time (available from Java 8), you could do it like this:
public static void main(String[] args) {
// example input String
String datetime = "Fri Jan 27 00:00:00 GMT+00:00 1995";
// define a pattern that parses the format of the input String
String inputPattern = "EEE MMM dd HH:mm:ss O uuuu";
// define a formatter that uses this pattern for parsing the input
DateTimeFormatter parser = DateTimeFormatter.ofPattern(inputPattern, Locale.ENGLISH);
// use the formatter in order to parse a zone-aware object
ZonedDateTime zdt = ZonedDateTime.parse(datetime, parser);
// then output it in the built-in ISO format once,
System.out.println("date, time and zone (ISO):\t"
+ zdt.format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
// then extract the date part
LocalDate dateOnly = zdt.toLocalDate();
// and output that date part using a formatter with a date-only pattern
System.out.println("date only as desired:\t\t"
+ dateOnly.format(DateTimeFormatter.ofPattern("uuuu/dd/MM")));
}
The output of this piece of code is
date, time and zone (ISO): 1995-01-27T00:00:00Z
date only as desired: 1995/27/01
Maybe add applyPattern function in code
String inputPattern = "EEE MMM dd HH:mm:ss z yyyy";
String outputPattern = "yyyy-MM-dd";
SimpleDateFormat sdf = new SimpleDateFormat(inputPattern);
Date date = sdf.parse("Fri Jan 27 00:00:00 GMT+00:00 1995");
sdf.applyPattern(outputPattern);
String str = sdf.format(date);

How can i convert String to Date when it has "TRT" in it

String sDate = "06.08.2020" // 06 day 08 month 2020 is year
This is the date i have in my txt file. I use them in JTable. To sort the table i convert them to date with this DateFormatter.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy");
And it does convert the string to date as this.
LocalDate date = LocalDate.parse(sDate,formatter);
//The date : Thu Aug 06 00:00:00 TRT 2020
Now i need to convert it like the first date 06.08.2020.
But i can't use date as input. Because i get it from JTable so i get it as String.
So i tryed this code.
String sDate1 = "Thu Aug 06 00:00:00 TRT 2020";// The date i get from JTable
LocalDate lastdate = LocalDate.parse(sDate1,formatter);
sDate1 = formatter.format(lastdate);
But i get an error as this Text 'Thu Aug 06 00:00:00 TRT 2020' could not be parsed at index 0.
So this cone not works fine : LocalDate lastdate = LocalDate.parse(sDate1,formatter);
I cant see where is the problem.
I cannot reproduce the behaviour you describe. The following code worked fine for me:
import java.util.*;
import java.text.*;
public class MyClass {
public static void main(String args[]) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy");
String date = "06.08.2020";
Date date1 = sdf.parse(date);
String result = sdf.format(date1);
System.out.println("Date = " + result);
}
}
Output: Date = 06.08.2020
That being said, if at all possible you should switch to the new java.time.* API.
Where your code failed:
SimpleDateFormat sdf1=new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy");
String dateStr = "06.08.2020";
sdf1.parse(dateStr);
As you can see, the pattern of the SimpleDateFormat and that of the date string do not match and therefore, this code will throw ParseException.
How to make it work?
SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy");
String dateStr = "06.08.2020";
Date date = sdf.parse(dateStr);
You must have already got why it worked. It worked because the pattern of the SimpleDateFormat matches with that of the dateStr string.
Can I format the Date object (i.e. date) into the original string?
Yes, just use the same format which you used to parse the original string as shown below:
SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy");
String dateStr = "06.08.2020";
Date date = sdf.parse(dateStr);
// Display in the default format
System.out.println(date);
// Format into the string
dateStr = sdf.format(date);
System.out.println(dateStr);
A piece of advice:
I recommend you switch from the outdated and error-prone java.util date-time API and SimpleDateFormat to the modern java.time date-time API and the corresponding formatting API (package, java.time.format). Learn more about the modern date-time API from Trail: Date Time.
Using the modern date-time API:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy");
String dateStr = "06.08.2020";
LocalDate date = LocalDate.parse(dateStr, formatter);
// Display in the default format
System.out.println(date);
// Format into the string
dateStr = formatter.format(date);
System.out.println(dateStr);
I don't see any difference using the legacy API and the modern API:
That's true for this simple example but when you will need to do complex operations using date and time, you will find the modern date-time API smart and clean while the legacy API complex and error-prone.
Demo:
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
// Given date-time string
String strDate = "Thu Aug 06 00:00:00 TRT 2020";
// Replace TRT with standard time-zone string
strDate = strDate.replace("TRT", "Europe/Istanbul");
// Define formatter
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss zzzz yyyy");
// Parse the date-time string into ZonedDateTime
ZonedDateTime zdt = ZonedDateTime.parse(strDate, formatter);
System.out.println(zdt);
// If you wish, convert ZonedDateTime into LocalDateTime
LocalDateTime ldt = zdt.toLocalDateTime();
System.out.println(ldt);
}
}
Output:
2020-08-06T00:00+03:00[Europe/Istanbul]
2020-08-06T00:00

How do I Date format for dd MMM yyyy, as in 01 Apr 2020 [duplicate]

This question already has answers here:
java DateTimeFormatterBuilder fails on testtime [duplicate]
(2 answers)
Closed 2 years ago.
I have a pdf file where I want to know if the next line is a date, or just a string (there are two types of formats of the listing, and knowing if I've arrived at a date is important.) The trouble is, there appears to be no way to use date formatting to arrive at a date of 01 Apr 2020
LocalDate date = parseDate( "dd MMM yyyy", "01 Apr 2020" );
Throws ... Text '01 Apr 2020' could not be parsed at index 3
private static LocalDate parseDate( final String format, final String s ) {
final DateTimeFormatter df = DateTimeFormatter.ofPattern( format );
LocalDate ld; // Check if this was a legal LocalDate.
try {
ld = LocalDate.parse(s, df);
} catch (java.time.format.DateTimeParseException pe) {
System.out.println( pe.getMessage() );
ld = null; // This will signal an error
}
return ld;
}
Is there really no way to parse that format of date, like a bank uses in their pdf?
Replace
final DateTimeFormatter df = DateTimeFormatter.ofPattern( format );
With
final DateTimeFormatter df = DateTimeFormatter.ofPattern( format , Locale.US );
Hopefully, this will resolve your issue.
I believe you're using java8, You can do
LocalDate date = LocalDate.parse("01 Apr 2020", DateTimeFormatter.ofPattern("dd MMM yyyy", Locale.ROOT));
Edited: After pointed out that it doesn't work for all locales. Locale.ROOT should be used for neutral locale.

Date to local time kotlin

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

Old Date Formatting incompatible with Java 8 ZonedDateTime API

I am updating my old date formatting code to Java 8 and trying the ZonedDateTime API.
The format of date is same as the Javascript Date object format, e.g. -
Thu May 25 2017 10:00:00 GMT+1200 (New Zealand Standard Time)
I was using the below format previously -
EEE MMM dd yyyy hh:mm:ss 'GMT'Z '('zzzz')'
This format fails to parse the date string using DateTimeFormatter.ofPattern method.
Here's the code:
public static final String DATE_FORMAT = "EEE MMM dd yyyy hh:mm:ss 'GMT'Z '('zzzz')'";
public static void main(String[] args) throws ParseException {
String sDate = "Thu May 25 2017 10:00:00 GMT+1200 (New Zealand Standard Time)";
parseDate(sDate);
}
private static void parseDate(String sDate) throws ParseException {
// works
DateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
Date oldDate = dateFormat.parse(sDate);
//FIXME: can't parse?!
ZonedDateTime newDate = ZonedDateTime.parse(
sDate, DateTimeFormatter.ofPattern(DATE_FORMAT)); // <- this is the line 25!
}
Here's my full code for reference that can be compiled and run - https://gist.github.com/bhabanism/470e03db54981ad6ddedbba316dcaa9a
This fails at line#25 with:
Exception in thread "main" java.time.format.DateTimeParseException:
Text 'Thu May 25 2017 10:00:00 GMT+1200 (New Zealand Standard Time)'
could not be parsed: Unable to obtain ZonedDateTime from
TemporalAccessor: {HourOfAmPm=10, MilliOfSecond=0, MinuteOfHour=0,
OffsetSeconds=43200, MicroOfSecond=0, NanoOfSecond=0,
SecondOfMinute=0},ISO,Pacific/Auckland resolved to 2017-05-25 of type
java.time.format.Parsed
Note, I can't change the input format of the Date, it has to be
Thu May 25 2017 10:00:00 GMT+1200 (New Zealand Standard Time)
I can surely modify the formatter
EEE MMM dd yyyy hh:mm:ss 'GMT'Z '('zzzz')'
It seems there was a bug in your format string all the time. Lowercase hh is for hour within AM or PM, in the range 1 through 12. Since you don’t have AM/PM in your string, I suspect this was never what you wanted, and I wonder how the error went unnoticed.
Uppercase HH is for hour of day, 0 through 23:
public static final String DATE_FORMAT = "EEE MMM dd yyyy HH:mm:ss 'GMT'Z '('zzzz')'";
With this change both the old and the new way of parsing works on my computer.
When adding Locale.ENGLISH to both formatters, that is. You may want to do the same.
The results I get are
Thu May 25 00:00:00 CEST 2017
2017-05-25T10:00+12:00[Pacific/Auckland]
Since CEST is 2 hours ahead of UTC, this is the same point in time, only rendered differently.

Categories