I'm trying convert a String to Date, but I haven't gotten it.
My String is in the format:
"Fri Jun 13 10:24:01 BRT 2014"
I have Googled and found this resolution, but still continue catching an Exception.
Here is my code:
java.text.SimpleDateFormat df = new java.text.SimpleDateFormat("EEE MMM dd HH:mm:ss 'BRT' yyyy", Locale.getDefault());
df.setTimeZone(TimeZone.getTimeZone("BRT"));
try {
return df.parse(dateString);
} catch (Exception e) {
return null;
}
You need:
SimpleDateFormat df = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy", Locale.ENGLISH);
df.setTimeZone(TimeZone.getTimeZone("BRT"));
DateFormat utcFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
Date d = df.parse("Fri Jun 13 10:24:01 BRT 2014");
System.out.println(utcFormat.format(d)); // output: 2014-06-13T12:24:01+0200
Consider following corrections:
Locale.ENGLISH instead of Locale.getDefault() enables reliable parsing of english names like "Jun" or "Fri"
Use pattern symbol z instead of literal 'BRT' because else the parser cannot interprete the string "BRT" as an abbreviation of a timezone name that is interpreting as Brazil Standard Time (in your case just parsing as literal hence not taking in account the timezone offset of UTC-03:00).
The answer by Meno Hochschild is correct. Pay attention to those items (1) & (2).
Joda-Time
FYI, using Joda-Time or java.time (new package in Java 8) is recommended over the notoriously troublesome java.util.Date and .Calendar classes.
Example in Joda-Time 2.3.
String input = "Fri Jun 13 10:24:01 BRT 2014";
Via a Locale object, specify the language by which to interpret the day-of-week and month names during the parsing.
DateTimeFormatter formatter = DateTimeFormat.forPattern( "EEE MMM dd HH:mm:ss z yyyy" ).withLocale( Locale.ENGLISH );
Rather than rely on the default, specify a time zone to assign to the fresh DateTime object resulting from the parsing. Unlike a java.util.Date object, a DateTime truly knows its own assigned time zone.
DateTimeZone timeZone = DateTimeZone.forID( "America/Sao_Paulo" ); // Arbitrary choice of example time zone.
DateTime dateTime = formatter.withZone( timeZone ).parseDateTime( input );
Usually you should be working in Universal Time (UTC). Easy to convert.
DateTime dateTimeUtc = dateTime.withZone( DateTimeZone.UTC );
Built-in formatter is based on ISO 8601 format.
String output = dateTime.toString();
Or define your own pattern, or use one of the other pre-defined formats.
String outputInAwkwardFormat = formatter.print( dateTime );
Related
I have date of type "EEE MM DD HH:mm:ss zzz yyyy" (Wed Mar 04 03:34:45 GMT+08:00 2020) and "yyyy-MM-dd hh:mm:ss" (2020-02-04 02:10:58).How to compare this two date in java?
Both dates are in same timezone.
If you assume that the timezone of the second date is the same as for the first one then you can just use java.time. It has all parsing tools you need. Any other fixed timezone works as well.
Here is an example:
String a = "Wed Mar 04 03:34:45 GMT+08:00 2020";
String b = "2020-02-04 02:10:58";
ZonedDateTime parsedA;
ZonedDateTime parsedB;
DateTimeFormatter formatterA = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss zzz yyyy");
parsedA = ZonedDateTime.parse(a, formatterA);
DateTimeFormatter formatterB = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
parsedB = LocalDateTime.parse(b, formatterB).atZone(parsedA.getZone());
// What do you want to compare? For example you can tell if a is after b.
System.out.println(parsedA.isAfter(parsedB));
Have a look here if you need another format and need a listing of Pattern Letters and Symbols.
First of all these two dates are not comparable because of missing timezone in the second date.
Secondly, If you still want to do that with system's default time zone then you need to bring both the dates into common format.
Parse the dates into Date object and then you can play around it:
DateFormat dateFormat1 = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy");
Date date1 = dateFormat1.parse("Wed Mar 04 03:34:45 GMT+08:00 2020");
DateFormat dateFormat2 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Date date2 = dateFormat2.parse("2020-02-04 02:10:58");
System.out.println(date1.after(date2));
There is a difference between time zone and time zone offset. The Date-Time string Wed Mar 04 03:34:45 GMT+08:00 2020 has a time zone offset, not a time zone. A time zone is unique and therefore it has an ID e.g. ZoneId.of("America/New_York") whereas a time zone offset tells you about the amount of time by which a given time is offset from the UTC time. There can be many time zones falling on the same time zone offset. Check List of tz database time zones to learn more about it. So, the most appropriate type to parse Wed Mar 04 03:34:45 GMT+08:00 2020 into is OffsetDateTime.
Since the second Date-Time string 2020-02-04 02:10:58 has neither a time zone nor a time zone offset, parse it into LocalDateTime.
Make sure to use Locale with the formatter because Date-Time parsing/formatting API is Locale-sensitive.
As long as the second Date-Time string refers to a Date-Time at the same timezone offset (i.e. GMT+08:00), you can do either of the two to compare them
Convert the first Date-Time string into LocalDateTime after parsing and then compare it with the second Date-Time string parsed into a LocalDateTime.
Convert the second Date-Time string into an OffsetDateTime after parsing and then compare it with the first Date-Time string parsed into an OffsetDateTime.
I would prefer the first approach as it is simpler. However, for the sake of completeness, I've shown below both approaches.
First approach:
DateTimeFormatter odtFormatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss O uuuu", Locale.ENGLISH);
OffsetDateTime firstOffsetDateTime = OffsetDateTime.parse("Wed Mar 04 03:34:45 GMT+08:00 2020", odtFormatter);
LocalDateTime firstLocalDateTime = firstOffsetDateTime.toLocalDateTime();
DateTimeFormatter ldtFormatter = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss", Locale.ENGLISH);
LocalDateTime secondLocalDateTime = LocalDateTime.parse("2020-02-04 02:10:58", ldtFormatter);
// Compare the two LocalDateTime values using isBefore, isAfter, equals etc.
if (firstLocalDateTime.isBefore(secondLocalDateTime)) {
// ...
}
Second approach:
DateTimeFormatter odtFormatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss O uuuu", Locale.ENGLISH);
OffsetDateTime firstOffsetDateTime = OffsetDateTime.parse("Wed Mar 04 03:34:45 GMT+08:00 2020", odtFormatter);
DateTimeFormatter ldtFormatter = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss", Locale.ENGLISH);
LocalDateTime secondLocalDateTime = LocalDateTime.parse("2020-02-04 02:10:58", ldtFormatter);
OffsetDateTime secondOffsetDateTime = secondLocalDateTime.atOffset(firstOffsetDateTime.getOffset());
// Compare the two OffsetDateTime values using isBefore, isAfter, equals etc.
if (firstOffsetDateTime.isBefore(secondOffsetDateTime)) {
// ...
}
I also prefer u to y with a DateTimeFormatter.
Learn more about the the modern date-time API from Trail: Date Time.
I am trying to convert EEE MMM dd HH:mm:ss ZZZ yyyy to YYYY-MM-DD format, so I can insert it into a MySQL database. I do not get any error, but the date inserted into my db is wrong and the same for every row...
String date = Sat Mar 04 09:54:20 EET 2017;
SimpleDateFormat formatnow = new SimpleDateFormat("EEE MMM dd HH:mm:ss ZZZ yyyy");
SimpleDateFormat formatneeded=new SimpleDateFormat("YYYY-MM-DD");
java.util.Date date1 = (java.util.Date)formatnow.parse(date);
String date2 = formatneeded.format(date1);
java.util.Date date3= (java.util.Date)formatneeded.parse(date2);
java.sql.Date sqlDate = new java.sql.Date( date3.getTime() );
pst.setDate(1, sqlDate);
LocalDate date4 = ZonedDateTime
.parse(date, DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss zzz yyyy", Locale.ENGLISH))
.toLocalDate();
java.sql.Date date5 = java.sql.Date.valueOf(date4);
I am using the modern classes in the java.time package. You notice that the code is not only simpler, once you get acquainted with the fluent writing style of the newer classes, it is also clearer.
If you wanted to be 100 % modern, you should also check out whether your latest MySQL JDBC driver wouldn’t accept a LocalDate directly without conversion to java.sql.Date. It should.
A few details to note
If you need your code to run on computers outside your control, always give locale to your formatter, or your date string cannot be parsed on a computer with a non-English-speaking locale. You may use Locale.ROOT for a locale neutral locale (it speaks English).
If you can, avoid the three letter time zone abbreviations. Many are ambiguous. EET is really only half a time zone since some places where it’s used are on EEST (summer time) now. Better to use either a long time zone ID like Europe/Bucharest or an offset from UTC like +02:00.
These points are valid no matter if you use DateTimeFormatter or SimpleDateFormat.
If you cannot or do not want to move on to the recommended newer classes, the fix to your code is:
SimpleDateFormat formatnow
= new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.ENGLISH);
SimpleDateFormat formatneeded = new SimpleDateFormat("yyyy-MM-dd");
I am using lowercase zzz since this is documented to match a three-letter time zone name, I know that uppercase ZZZ works too. I have added locale. And maybe most importantly, in the needed format I have changed YYYY (week-based year) to yyyy (calendar year) and DD (day of year) to dd (day of month). All those letters are in the documentation.
I know this question is related to java.sql.Date but as additional information, if you want to convert the date into LocalDate then below code might help:
private LocalDate getLocalDate(String date){
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd hh:mm:ss Z yyyy", Locale.getDefault());
return LocalDate.parse(date, formatter);
}
And once you get the LocalDate, you can transform it to any format. As the question expects yyyy-MM-dd then just call toString() on LocalDate object.
LocalDate curr = LocalDate.now();
System.out.println(curr.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
System.out.println(curr.toString());
It will display the date like "2019-11-20".
Hope this helps to someone.
This question already has answers here:
Java string to date conversion
(17 answers)
Closed 6 years ago.
I am trying to parse this date with SimpleDateFormat and it is not working:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Formaterclass {
public static void main(String[] args) throws ParseException{
String strDate = "Thu Jun 18 20:56:02 EDT 2009";
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
Date dateStr = formatter.parse(strDate);
String formattedDate = formatter.format(dateStr);
System.out.println("yyyy-MM-dd date is ==>"+formattedDate);
Date date1 = formatter.parse(formattedDate);
formatter = new SimpleDateFormat("dd-MMM-yyyy");
formattedDate = formatter.format(date1);
System.out.println("dd-MMM-yyyy date is ==>"+formattedDate);
}
}
If I try this code with strDate="2008-10-14", I have a positive answer. What's the problem? How can I parse this format?
PS. I got this date from a jDatePicker and there is no instruction on how modify the date format I get when the user chooses a date.
You cannot expect to parse a date with a SimpleDateFormat that is set up with a different format.
To parse your "Thu Jun 18 20:56:02 EDT 2009" date string you need a SimpleDateFormat like this (roughly):
SimpleDateFormat parser=new SimpleDateFormat("EEE MMM d HH:mm:ss zzz yyyy");
Use this to parse the string into a Date, and then your other SimpleDateFormat to turn that Date into the format you want.
String input = "Thu Jun 18 20:56:02 EDT 2009";
SimpleDateFormat parser = new SimpleDateFormat("EEE MMM d HH:mm:ss zzz yyyy");
Date date = parser.parse(input);
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
String formattedDate = formatter.format(date);
...
JavaDoc: http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html
The problem is that you have a date formatted like this:
Thu Jun 18 20:56:02 EDT 2009
But are using a SimpleDateFormat that is:
yyyy-MM-dd
The two formats don't agree. You need to construct a SimpleDateFormat that matches the layout of the string you're trying to parse into a Date. Lining things up to make it easy to see, you want a SimpleDateFormat like this:
EEE MMM dd HH:mm:ss zzz yyyy
Thu Jun 18 20:56:02 EDT 2009
Check the JavaDoc page I linked to and see how the characters are used.
We now have a more modern way to do this work.
java.time
The java.time framework is bundled with Java 8 and later. See Tutorial. These new classes are inspired by Joda-Time, defined by JSR 310, and extended by the ThreeTen-Extra project. They are a vast improvement over the troublesome old classes, java.util.Date/.Calendar et al.
Note that the 3-4 letter codes like EDT are neither standardized nor unique. Avoid them whenever possible. Learn to use ISO 8601 standard formats instead. The java.time framework may take a stab at translating, but many of the commonly used codes have duplicate values.
By the way, note how java.time by default generates strings using the ISO 8601 formats but extended by appending the name of the time zone in brackets.
String input = "Thu Jun 18 20:56:02 EDT 2009";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern ( "EEE MMM d HH:mm:ss zzz yyyy" , Locale.ENGLISH );
ZonedDateTime zdt = formatter.parse ( input , ZonedDateTime :: from );
Dump to console.
System.out.println ( "zdt : " + zdt );
When run.
zdt : 2009-06-18T20:56:02-04:00[America/New_York]
Adjust Time Zone
For fun let's adjust to the India time zone.
ZonedDateTime zdtKolkata = zdt.withZoneSameInstant ( ZoneId.of ( "Asia/Kolkata" ) );
zdtKolkata : 2009-06-19T06:26:02+05:30[Asia/Kolkata]
Convert to j.u.Date
If you really need a java.util.Date object for use with classes not yet updated to the java.time types, convert. Note that you are losing the assigned time zone, but have the same moment automatically adjusted to UTC.
java.util.Date date = java.util.Date.from( zdt.toInstant() );
How about getSelectedDate? Anyway, specifically on your code question, the problem is with this line:
new SimpleDateFormat("yyyy-MM-dd");
The string that goes in the constructor has to match the format of the date. The documentation for how to do that is here. Looks like you need something close to "EEE MMM d HH:mm:ss zzz yyyy"
In response to:
"How to convert Tue Sep 13 2016 00:00:00 GMT-0500 (Hora de verano central (México)) to dd-MM-yy in Java?", it was marked how duplicate
Try this:
With java.util.Date, java.text.SimpleDateFormat, it's a simple solution.
public static void main(String[] args) throws ParseException {
String fecha = "Tue Sep 13 2016 00:00:00 GMT-0500 (Hora de verano central (México))";
Date f = new Date(fecha);
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
sdf.setTimeZone(TimeZone.getTimeZone("-5GMT"));
fecha = sdf.format(f);
System.out.println(fecha);
}
So, I'm experimenting with the Calendar class in Java, and I'm writing a method which returns a Calendar object.
What I want for said method is to return a Calendar object containing "Sun Feb 09 22:49:36 +0000 2014".
Now I'm (debatably) not lazy and I have done some work on my method.
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat(
"EEE MMM dd HH:mm:ss Z yyyy");
try {
cal.setTime(sdf.parse("Sun Feb 09 22:49:36 +0000 2014"));
} catch (ParseException e) {
e.printStackTrace();
}
return cal;
The problem is it keeps telling me that I got a ParseException, that it's an "Unparseable date".
I thought my logic was pretty correct, but I'm starting to doubt it.
I'd prefer it without importing any more than Calendar, but SimpleDateFormat seems to be pretty handy too.
The less imports the better, I always say.
Anyone see how what I want can be achieved?
EDIT 1
Tried to run the code in a main method and just print out the result, with no difference in Exception.
The following is my main:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
public class TestingMyCalendar {
public static void main(String[] args) {
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat(
"EEE MMM dd HH:mm:ss Z yyyy");
try {
cal.setTime(sdf.parse("Sun Feb 09 22:49:36 +0000 2014"));
} catch (ParseException e) {
e.printStackTrace();
}
System.out.println(cal);
}
}
For those interested, the following is my entire console text after the main crashed:
java.text.ParseException: Unparseable date: "Sun Feb 09 22:49:36 +0000 2014"
at java.text.DateFormat.parse(Unknown Source)
at TestingMyCalendar.main(TestingMyCalendar.java:15)
java.util.GregorianCalendar[time=1391987659892,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Europe/Berlin",offset=3600000,dstSavings=3600000,useDaylight=true,transitions=143,lastRule=java.util.SimpleTimeZone[id=Europe/Berlin,offset=3600000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=2,startMonth=2,startDay=-1,startDayOfWeek=1,startTime=3600000,startTimeMode=2,endMode=2,endMonth=9,endDay=-1,endDayOfWeek=1,endTime=3600000,endTimeMode=2]],firstDayOfWeek=2,minimalDaysInFirstWeek=4,ERA=1,YEAR=2014,MONTH=1,WEEK_OF_YEAR=7,WEEK_OF_MONTH=2,DAY_OF_MONTH=10,DAY_OF_YEAR=41,DAY_OF_WEEK=2,DAY_OF_WEEK_IN_MONTH=2,AM_PM=0,HOUR=0,HOUR_OF_DAY=0,MINUTE=14,SECOND=19,MILLISECOND=892,ZONE_OFFSET=3600000,DST_OFFSET=0]
You may need to set your default locale to Locale.ENGLISH, otherwise the parser might choke on the Sun for Sunday.
Try:
Locale.setDefault(Locale.ENGLISH);
Or, specify it as part of the constructor call:
SimpleDateFormat sdf = new SimpleDateFormat(
"EEE MMM dd HH:mm:ss Z yyyy", Locale.ENGLISH);
Your stacktrace indicates Europe/Berlin as the timezone suggests that you are using a German Locale. The day or month fields may not match those from your default locale, Try
SimpleDateFormat sdf =
new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy", Locale.ENGLISH);
The other answers are correct. I'll add a few thoughts.
Defaults Are Tricky
Probably the most common source of trouble in date-time work is inadvertently relying on:
Default time zone
Default locale
I've come to the conclusion that both should be specified in all my code, as a habit. I don't want my code changing its behavior (or breaking, as in your case) if it happens to be run with a different time zone or locale setting.
The only case where date-time code should use the default is when you truly want to detect and utilize the user's (the JVM's) own settings for localization. And even in this case, I explicitly make a call to retrieve and use the default rather than rely on the implicit default, so as to make my code obvious and self-documenting.
DateTimeZone.getDefault()
java.util.Locale.getDefault()
Joda-Time
As a commenter said, minimizing your imports is indeed a queer goal. Especially with java.util.Calendar and java.util.Date – If ever there were a case for imports it would be those two classes. They are notoriously troublesome, and should be avoided. Use Joda-Time. Or, in Java 8, use the bundled new java.time.* package, inspired by Joda-Time, defined by JSR 310.
Note that in Joda-Time, a DateTime object truly knows its own assigned time zone. That's a big contrast to java.util.Date which has no assigned time zone but its toString applies the JVM's default time zone which leads to much confusion.
Here is some example code in Joda-Time 2.3.
String input = "Sun Feb 09 22:49:36 +0000 2014";
DateTimeZone timeZone = DateTimeZone.forID( "America/Montreal" );
DateTimeFormatter formatter = DateTimeFormat.forPattern( "EEE MMM dd HH:mm:ss Z yyyy" ).withLocale( Locale.ENGLISH ).withZone( timeZone );
DateTime dateTime = formatter.parseDateTime( input );
Dump to console…
System.out.println( "dateTime: " + dateTime );
System.out.println( "Same dateTime in UTC/GMT: " + dateTime.withZone( DateTimeZone.UTC ) );
When run…
dateTime: 2014-02-09T17:49:36.000-05:00
Same dateTime in UTC/GMT: 2014-02-09T22:49:36.000Z
I have a requirement where the date is in UTC format like: Thu Jan 1 19:30:00 UTC+0530 1970. I want to convert in to normal date format dd-MM-yyyy HH:mm:ss.Below is the code that i tried.
DateFormat formatter = new SimpleDateFormat("E,MMM dd,yyyy h:mmaa");
String today = formatter.format("Thu Jan 1 19:30:00 UTC+0530 1970");
SimpleDateFormat f = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
Date d = f.parse(masterDetailsJsonObject.get("cols1").toString());
But it throws an exception saying unparseable date. Please guide. Thanks in advance.
You can try this
java.util.Date dt = new java.util.Date("Thu Jan 1 19:30:00 UTC+0530 1970");
String newDateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss").format(dt);
System.out.println(""+newDateFormat);
Joda-Time
This kind of work is much easier with the third-party open-source date-time library, Joda-Time.
Note that unlike a java.util.Date, a Joda-Time DateTime knows its own time zone.
Here is some example code using Joda-Time 2.3.
String input = "Thu Jan 1 19:30:00 UTC+0530 1970";
DateTimeFormatter formatter = DateTimeFormat.forPattern( "EEE MMM dd HH:mm:ss 'UTC'Z yyyy" );
// Adding "withOffsetParsed()" means "set new DateTime's time zone offset to match input string".
DateTime dateTime = formatter.withOffsetParsed().parseDateTime( input );
// Convert to UTC/GMT (no time zone offset).
DateTime dateTimeUtc = dateTime.toDateTime( DateTimeZone.UTC );
// Convert to India time zone. That is +05:30 (notice half-hour difference).
DateTime dateTimeIndia = dateTimeUtc.toDateTime( DateTimeZone.forID( "Asia/Kolkata" ) );
Dump to console…
System.out.println( "dateTime: " + dateTime );
System.out.println( "dateTimeUtc: " + dateTimeUtc );
System.out.println( "dateTimeIndia: " + dateTimeIndia );
When run…
dateTime: 1970-01-01T19:30:00.000+05:30
dateTimeUtc: 1970-01-01T14:00:00.000Z
dateTimeIndia: 1970-01-01T19:30:00.000+05:30
Back To Date
If you need a java.util.Date for other purposes, convert your DateTime.
java.util.Date date = dateTime.toDate();
Formatted String
To represent your DateTime as a new String in a certain format, search StackOverflow for "joda format". You'll find many questions and answers.
Joda-Time offers many features for generating strings, including default formatters for ISO 8601 formats (seen above), Locale-sensitive formats that automatically change order of elements and even translate words to various languages, formats sensed from the user's computer's settings. If none of those meet your peculiar needs, you may define your own formats with the help of Joda-Time.
Locale.setDefault(Locale.US);
SimpleDateFormat sourceDateFormat = new SimpleDateFormat("E MMM d HH:mm:ss 'UTC'Z yyyy");
Date sourceDate = sourceDateFormat.parse("Thu Jan 1 19:30:00 UTC+0530 1970");
System.out.println(sourceDate);
SimpleDateFormat targetFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
String targetString = targetFormat.format(sourceDate);
System.out.println(targetString);
Use "E MMM d HH:mm:ss 'UTC'Z yyyy" as the source format. I don't like Java's Date API, especially for the TimeZone case. Joda-Time seems good.