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.
Related
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.
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
I am getting the date in the format Mon Nov 09 2015 00:00:00 GMT+0530 (India Standard Time). I have to convert it to sql date of format dd/MM/yyyy. Please help.
I tried below code but did not help
Date date = new java.sql.Date(
(new SimpleDateFormat("EEE MMM dd yyyy HH:mm:ss zz (zzzz)").parse("Mon Nov 09 2015 00:00:00 GMT+0530 (India Standard Time)"))
.getTime());
Something like below, also refer here for Java SimpleDateFormat
public static void main(String[] args) throws ParseException {
String time = "Mon Nov 09 2015 00:00:00 GMT+0530 (India Standard Time)";
DateFormat inputFormat = new SimpleDateFormat(
"E MMM dd yyyy HH:mm:ss 'GMT'z", Locale.ENGLISH);
Date date = inputFormat.parse(time);
System.out.println(date);
SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy", Locale.US);
System.out.println(formatter.format(date));
}
output
Mon Nov 09 00:00:00 IST 2015
09/11/2015
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* .
Since your date-time string has timezone information, parse it into ZonedDateTime which you can convert to other java.time types and if required, format into the desired formats.
Demo:
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.TextStyle;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String strDateTime = "Mon Nov 09 2015 00:00:00 GMT+0530 (India Standard Time)";
DateTimeFormatter dtfInput = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("E MMM d uuuu H:m:s")
.appendLiteral(" ")
.appendZoneId()
.appendPattern("X")
.appendLiteral(" ")
.appendLiteral("(")
.appendGenericZoneText(TextStyle.FULL)
.appendLiteral(')')
.toFormatter(Locale.ENGLISH);
ZonedDateTime zdt = ZonedDateTime.parse(strDateTime, dtfInput);
OffsetDateTime odt = zdt.toOffsetDateTime();
System.out.println(odt);
// To LocalDate, LocalDateTime etc.
LocalDate localDate = odt.toLocalDate();
LocalDateTime localDateTime = odt.toLocalDateTime();
System.out.println(localDate);
System.out.println(localDateTime);
// Get the formatted string
DateTimeFormatter dtfOutput = DateTimeFormatter.ofPattern("dd/MM/uuuu", Locale.ENGLISH);
String formatted = dtfOutput.format(localDate);
System.out.println(formatted);
// In UTC
odt = odt.withOffsetSameInstant(ZoneOffset.UTC);
System.out.println(odt);
}
}
Output:
2015-11-09T00:00+05:30
2015-11-09
2015-11-09T00:00
09/11/2015
2015-11-08T18:30Z
Learn more about the modern date-time API from Trail: Date Time.
Support for OffsetDateTime in JDBC:
Starting with JDBC 4.2, you can use OffsetDateTime directly in your code e.g.
PreparedStatement st = conn.prepareStatement("INSERT INTO mytable (columnfoo) VALUES (?)");
st.setObject(1, odt);
st.executeUpdate();
st.close();
The support for java.time API in JDBC Java SE 8 (JDBC 4.2) came without requiring any public JDBC API changes. The setObject and getObject methods support java.time types as per the following mapping:
Note for PostgreSQL™: ZonedDateTime, Instant and OffsetTime / TIME WITH TIME ZONE are not supported. Also, the OffsetDateTime instances need to be in UTC (have offset 0).
* 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.
I have dealt with something like this right now, and this is my solution:
String dateString = new SimpleDateFormat("dd/MM/yyyy").format(timestamp.toDate()).toString();
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.
Why: When I give input date string with GMT timezone, SimpleDateFormat parses it and outputs EET timezone?
public static String DATE_FORMAT="dd MMM yyyy hh:mm:ss z";
public static String CURRENT_DATE_STRING ="31 October 2011 11:19:56 GMT";
...
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DATE_FORMAT, Locale.US);
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(simpleDateFormat.parseObject(CURRENT_DATE_STRING));
And the output is:
Mon Oct 31 13:19:56 EET 2011
rather than
Mon Oct 31 13:19:56 GMT 2011
You're printing out the result of Date.toString(). A Date doesn't have any concept of a timezone - it's just the number of milliseconds since the UTC Unix epoch. Date.toString() always uses the system default time zone.
Note that you shouldn't be expecting "Mon Oct 31 13:19:56 GMT 2011" given that you've given a time which specifies a GMT hour of 11, not 13.
If you want to use a specific time zone for printing, you should use another DateFormat for the printing, rather than using Date.toString(). (Date.toString() keeps causing confusion like this; it's really unfortunate.)
java.util.Date does not hold timezone information.
A java.util.Date object simply represents the number of milliseconds since the standard base time known as "the epoch", namely January 1, 1970, 00:00:00 GMT (or UTC). Since it does not hold any timezone information, its toString function applies the JVM's timezone to return a String in the format, EEE MMM dd HH:mm:ss zzz yyyy, derived from this milliseconds value. To get the String representation of the java.util.Date object in a different format and timezone, you need to use SimpleDateFormat with the desired format and the applicable timezone.
Apart from this, there are a couple of problems with your code:
Use H instead of h for the 24-Hour format. The letter, h is used for the 12-Hour format (i.e. with AM/PM marker).
Even though MMM works for parsing the long name of the month (e.g. January) with SimpleDateFormat, it is meant for the 3-letter month name (e.g. Jan). If you try doing it with the modern Date-Time API, you will be greeted with the DateTimeParseException. You should use MMMM for the long name of the month.
Demo incorporating these points:
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) throws ParseException {
String strDateTime = "31 October 2011 11:19:56 GMT";
SimpleDateFormat sdf = new SimpleDateFormat("dd MMMM yyyy HH:mm:ss z", Locale.ENGLISH);
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
Date date = sdf.parse(strDateTime);
String strDate = sdf.format(date);
System.out.println(strDate);
// Some other format
sdf = new SimpleDateFormat("MMMM dd HH:mm:ss z yyyy", Locale.ENGLISH);
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
strDate = sdf.format(date);
System.out.println(strDate);
// The last format with some other timezone
sdf.setTimeZone(TimeZone.getTimeZone("America/New_York"));
strDate = sdf.format(date);
System.out.println(strDate);
}
}
Output:
31 October 2011 11:19:56 GMT
October 31 11:19:56 GMT 2011
October 31 07:19:56 EDT 2011
ONLINE DEMO
Switch to java.time API.
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.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String strDateTime = "31 October 2011 11:19:56 GMT";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd MMMM uuuu HH:mm:ss z", Locale.ENGLISH);
ZonedDateTime zdt = ZonedDateTime.parse(strDateTime, dtf);
System.out.println(zdt);
// Some other format
DateTimeFormatter dtfAnother = DateTimeFormatter.ofPattern("MMMM dd HH:mm:ss z uuuu", Locale.ENGLISH);
String strDate = dtfAnother.format(zdt);
System.out.println(strDate);
}
}
Output:
2011-10-31T11:19:56Z[GMT]
October 31 11:19:56 GMT 2011
ONLINE DEMO
The Z in the output is the timezone designator for zero-timezone offset. It stands for Zulu and specifies the Etc/UTC timezone (which has the timezone offset of +00:00 hours).
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.