Date parsing in Java using SimpleDateFormat - java

I want to parse a date in this format: "Wed Aug 26 2020 11:26:46 GMT+0200" into a date. But I don't know how to do it. I tried this:
SimpleDateFormat parser = new SimpleDateFormat("EEE MMM dd yyyy HH:mm:ss z");
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
Date date = parser.parse(split[0]); //error line
String formattedDate = formatter.format(date);
I am getting this error: Unparseable date: "Wed Aug 26 2020 11:26:46 GMT+0200". Is my date format wrong? And if so could somebody please point me in the right direction?

I suggest you stop using the outdated and error-prone java.util date-time API and SimpleDateFormat. Switch to the modern java.time date-time API and the corresponding formatting API (java.time.format). Learn more about the modern date-time API from Trail: Date Time.
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
// Given date-time string
String dateTimeStr = "Wed Aug 26 2020 11:26:46 GMT+0200";
// Parse the given date-time string to OffsetDateTime
OffsetDateTime odt = OffsetDateTime.parse(dateTimeStr,
DateTimeFormatter.ofPattern("E MMM d u H:m:s zX", Locale.ENGLISH));
// Display OffsetDateTime
System.out.println(odt);
}
}
Output:
2020-08-26T11:26:46+02:00
Using the legacy API:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class Main {
public static void main(String[] args) throws ParseException {
// Given date-time string
String dateTimeStr = "Wed Aug 26 2020 11:26:46 GMT+0200";
// Define the formatter
SimpleDateFormat parser = new SimpleDateFormat("EEE MMM dd yyyy HH:mm:ss 'GMT'Z", Locale.ENGLISH);
// Parse the given date-time string to java.util.Date
Date date = parser.parse(dateTimeStr);
System.out.println(date);
}
}
Output:
Wed Aug 26 10:26:46 BST 2020

Related

How to convert String with no time into full date with time using DateTimeFormatter

Hi I am trying to convert a String into date using DateTimeFormatter,
such as "20210628" to "Mon Jun 28 00:00:00 UTC 2021".
It can be achieved easily using SimpleDateFormatter but I want to achieve it using DateTimeFormatter.
java.time
The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.
Solution using java.time, the modern Date-Time API:
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.OffsetTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
DateTimeFormatter dtfInput = DateTimeFormatter.ofPattern("uuuuMMdd", Locale.ENGLISH);
LocalDate date = LocalDate.parse("20210628", dtfInput);
OffsetDateTime odt = date.atTime(OffsetTime.of(LocalTime.MIN, ZoneOffset.UTC));
System.out.println(odt);
// Custom format
DateTimeFormatter dtfOutput = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss O uuuu", Locale.ENGLISH);
System.out.println(dtfOutput.format(odt));
}
}
Output:
2021-06-28T00:00Z
Mon Jun 28 00:00:00 GMT 2021
ONLINE DEMO
Alternatively,
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
DateTimeFormatter dtfInput = DateTimeFormatter.ofPattern("uuuuMMdd", Locale.ENGLISH);
LocalDate date = LocalDate.parse("20210628", dtfInput);
ZonedDateTime zdt = date.atStartOfDay(ZoneId.of("Etc/UTC"));
System.out.println(zdt);
// Custom format
DateTimeFormatter dtfOutput = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss O uuuu", Locale.ENGLISH);
System.out.println(dtfOutput.format(zdt));
}
}
Output:
2021-06-28T00:00Z[Etc/UTC]
Mon Jun 28 00:00:00 GMT 2021
ONLINE DEMO
Learn more about the modern Date-Time API from Trail: Date Time.
A different approach using java.time, too...
Use a DateTimeFormatterBuilder to get full control over String conversion.
Here's a small example that really prints UTC instead of GMT or Z in the desired output:
public static void main(String[] args) {
// example String
String value = "20210628";
// define a formatter that parses the example String
DateTimeFormatter dateParser = DateTimeFormatter.ofPattern("uuuuMMdd");
// define a formatter that converts to a String as desired
DateTimeFormatter dtf = new DateTimeFormatterBuilder()
.appendPattern("EEE MMM dd HH:mm:ss")
.appendLiteral(' ')
.appendZoneRegionId()
.appendLiteral(' ')
.appendPattern("uuuu")
.toFormatter(Locale.ENGLISH);
// parse the date and use the formatter in order to get the desired result
String otherValue = LocalDate.parse(value, dateParser)
// add the start of the day
.atStartOfDay()
// apply the desired zone
.atZone(ZoneId.of("UTC"))
// and format it
.format(dtf);
// finally print the conversion
System.out.println(value + " ---> " + otherValue);
}
The output will be as follows:
20210628 ---> Mon Jun 28 00:00:00 UTC 2021
If you already have a LocalDateTime object then you can use the following.
String getFormattedDate(LocalDateTime datetime){
DateTimeFormatter formatterPreUTC = DateTimeFormatter.ofPattern("E MMM dd HH:mm:ss");
DateTimeFormatter formatterPostUTC = DateTimeFormatter.ofPattern("YYYY");
String textPreUTCPart = datetime.format(formatterPreUTC);
String utc = " UTC ";
String textPostUTCPart = datetime.format(formatterPostUTC);
return textPreUTCPart + utc + textPostUTCPart;
}

java parse date GRAVE null

In this code,
String str="Sun Feb 07 00:27:16 CET 2021";
SimpleDateFormat sdf=new SimpleDateFormat("E MMM dd HH:mm:ss z yyyy");
try {
java.util.Date date=sdf.parse(str);
System.out.print(date.getTime());
} catch (ParseException ex) {
Logger.getLogger(NewClass.class.getName()).log(Level.SEVERE, null, ex);
}
It shows
GRAVE: null
java.text.ParseException: Unparseable date: "Sun Feb 07 00:27:16 CET 2021"
How to solve it plz!
There are two problems with your code:
Not using the correct format: you have used E instead of EEE
Not using Locale: make it a habit to use the applicable Locale with date-time parsing/formatting API. Your date-time string is in English and therefore you should use an English-specific locale e.g. Locale.ENGLISH, Locale.US etc.
Correct code:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Locale;
public class Main {
public static void main(String[] args) throws ParseException {
String str = "Sun Feb 07 00:27:16 CET 2021";
SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy", Locale.ENGLISH);
java.util.Date date = sdf.parse(str);
System.out.print(date.getTime());
}
}
Output:
1612654036000
The date-time API of java.util and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern date-time API.
For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7.
If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
Using the modern date-time API:
import java.text.ParseException;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) throws ParseException {
String str = "Sun Feb 07 00:27:16 CET 2021";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss z uuuu", Locale.ENGLISH);
ZonedDateTime zdt = ZonedDateTime.parse(str, dtf);
System.out.println(zdt);
System.out.println(zdt.toInstant().toEpochMilli());
}
}
Output:
2021-02-07T00:27:16+01:00[Europe/Paris]
1612654036000
Learn more about the modern date-time API from Trail: Date Time.

Parse String to TimeZone ICT in Calendar java

I am trying to parse a String into a Calendar but right now I'm having problems at TimeZone:
My code:
public static Calendar convertStringToFullDates(String dateString) {
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat(PATTENT_FULL_DATE_FORMAT, Locale.US);
try {
cal.setTime(sdf.parse(dateString));
} catch (ParseException e) {
DebugLog.e(e.getLocalizedMessage());
}
return cal;
}
and String :
String str = "Fri May 11 00:00:00 ICT 2018";
and pattern:
private static final String PATTENT_FULL_DATE_FORMAT = "EEE MMM dd HH:mm:ss z yyyy";
I tried but it throws an exception like this:
Unparseable date: "Fri May 11 00:00:00 ICT 2018"
How to solve this problem?
The following code works for me:
public class Main {
public static void main(String[] args) throws ParseException {
String str = "Fri May 11 00:00:00 ICT 2018";
final String PATTENT_FULL_DATE_FORMAT = "EEE MMM dd HH:mm:ss z yyyy";
SimpleDateFormat sdf = new SimpleDateFormat(PATTENT_FULL_DATE_FORMAT, Locale.US);
Date date = sdf.parse(str);
System.out.println(date);
}
}
Note that java.util date-time classes are outdated and error-prone and so is their formatting API, SimpleDateFormat. I suggest you should stop using them completely and switch to the modern date-time API.
If you are doing it for your Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
Using the modern date-time API:
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String str = "Fri May 11 00:00:00 ICT 2018";
final String PATTENT_FULL_DATE_FORMAT = "EEE MMM dd HH:mm:ss z yyyy";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern(PATTENT_FULL_DATE_FORMAT, Locale.US);
ZonedDateTime zdt = ZonedDateTime.parse(str, dtf);
System.out.println(zdt);
// Print the date-time in a custom format
System.out.println(zdt.format(dtf));
}
}
Output:
2018-05-11T00:00+07:00[Asia/Bangkok]
Fri May 11 00:00:00 ICT 2018
Learn more about the modern date-time API at Trail: Date Time.

How to parse dates from other timezones that occur during daylight savings switchover using java.util.Date

I ran into an issue while parsing the following date.
08 März 2015 02:15:20
Code
SimpleDateFormat fmt = new SimpleDateFormat("dd MMM yyyy HH:mm:ss", Locale.GERMAN);
fmt.setLenient(false);
try {
System.out.println(fmt.parse("08 März 2015 02:15:20"));
} catch (ParseException e) {
e.printStackTrace();
}
After some investigation, I found out that due to how DST works, 2 AM in my timezone does not exist. Once the clock strikes 1:59 AM, the next time it updates will be 3 AM. I have checked that this is the case with the following dates:
"08 März 2015 01:59:59"
"08 März 2015 03:00:00"
Both of which can be parsed correctly.
What I want is a date object that correctly interprets the input date exactly as I see it:
Mar 8, 2015 at 2:15:20 AM
How can I accomplish this?
Ideally, you'd use a parser that allowed you to parse date/time values without trying to apply a time zone at all - both java.time.* and Joda Time allow for this, IIRC, and both are much cleaner than java.util.*.
However, if you have to use Date, and you don't know the origin time zone, the safest approach is to use TimeZone:
SimpleDateFormat parser = new SimpleDateFormat(
"dd MMM yyyy HH:mm:ss",
Locale.GERMAN);
parser.setLenient(false);
parser.setTimeZone(TimeZone.getTimeZone("UTC"));
So, that will parse it as if it were originally in UTC - so when you want to format it back to text, you need to do the same thing:
SimpleDateFormat formatter = new SimpleDateFormat(
"EEE d, yyyy at h:mm:ss tt",
Locale.US);
formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
String text = formatter.format(date);
TL;DR
Set TimeZone.getTimeZone("Europe/Berlin") as the timezone to fmt.
Demo:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
public class Main {
public static void main(String[] args) {
SimpleDateFormat fmt = new SimpleDateFormat("dd MMM yyyy HH:mm:ss", Locale.GERMAN);
fmt.setLenient(false);
fmt.setTimeZone(TimeZone.getTimeZone("Europe/Berlin"));
try {
Date date = fmt.parse("08 März 2015 02:15:20");
System.out.println(fmt.format(date));
} catch (ParseException e) {
e.printStackTrace();
}
}
}
Output:
08 März 2015 02:15:20
ONLINE DEMO
In case you want the output with AM/PM marker, the technique will stay the same with an additional step to create another SimpleDateFormat instance for output (because the format of the output will be different from the input).
Demo:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
public class Main {
public static void main(String[] args) {
SimpleDateFormat parser = new SimpleDateFormat("dd MMM yyyy HH:mm:ss", Locale.GERMAN);
parser.setLenient(false);
parser.setTimeZone(TimeZone.getTimeZone("Europe/Berlin"));
SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy hh:mm:ss a", Locale.GERMAN);
formatter.setTimeZone(TimeZone.getTimeZone("Europe/Berlin"));
try {
Date date = parser.parse("08 März 2015 02:15:20");
System.out.println(formatter.format(date));
} catch (ParseException e) {
e.printStackTrace();
}
}
}
Output:
08 März 2015 02:15:20 AM
ONLINE DEMO
java.time
The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.
Also, quoted below is a notice from the home page of Joda-Time:
Note that from Java SE 8 onwards, users are asked to migrate to java.time (JSR-310) - a core part of the JDK which replaces this project.
Solution using java.time, the modern Date-Time API:
Unlike java.util.Date which is simply a wrapper around the number of milliseconds since the UNIX epoch (January 1, 1970, 00:00:00 GMT), java.time types truly represent a date, a time, a date-time, with and without timezone information.
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
DateTimeFormatter parser = DateTimeFormatter.ofPattern("dd MMM uuuu HH:mm:ss", Locale.GERMAN);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd MMM uuuu hh:mm:ss a", Locale.GERMAN);
LocalDateTime ldt = LocalDateTime.parse("08 März 2015 02:15:20", parser);
System.out.println(parser.format(ldt));
System.out.println(formatter.format(ldt));
}
}
Output:
08 März 2015 02:15:20
08 März 2015 02:15:20 AM
ONLINE DEMO
Learn more about the modern Date-Time API from Trail: Date Time.
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

JAVA Date Conversion

How can I convert
Wed Apr 27 17:53:48 PKT 2011
to
Apr 27, 2011 5:53:48 PM.
new SimpleDateFormat("MMM dd, yyyy hh:mm:ss a.").format(yourDate);
You can use SimpleDateFormat or JodaTime's parser.
However it might be simple enough to write your own String parser as you are just rearranging fields.
You can do it using a mix of JDK and Joda time:
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
public class SO5804637 {
public static void main(String[] args) throws ParseException {
DateFormat df =
new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy");
Date d = df.parse("Wed Apr 27 17:53:48 PKT 2011");
DateTimeFormatter dtf =
DateTimeFormat.forPattern("MMM dd, yyyy hh:mm:ss a");
DateTime dt = new DateTime(d);
System.out.println(dt.toString(dtf));
}
}
Note: I've included the import statements to make it clear what classes I'm using.
SimpleDateFormat sdf = new SimpleDateFormat ("MMM dd, yyyy hh:mm:ss a");
String str = sdf.format(date)
You can use SimpleDateFormat to convert a string to a date in a defined date presentation. An example of the SimpleDateFormat usage can be found at the following place: http://www.kodejava.org/examples/19.html
new java.text.SimpleDateFormat("MMM d, yyyy h:mm:ss a").format(date);
I noticed your desired output had the hour of day not prefixed by 0 so the format string you need should have only a single 'h'. I'm guessing you want the day of the month to have a similar behavior so the pattern contains only a single 'd' too.

Categories