I am having a problem using the parseDateTime method in joda time. When I try to parse the date below, the result is one day off. I know there is already a similar thread about this, and I know that if your dayOfWeek and dayOfMonth are mismatched, it prioritizes the dayOfWeek. But my date is valid -- I have checked that february 22 falls on a Friday. But when I parse it, I am getting thursday, february 21. Here is the code:
DateTimeFormatter NBSfmt = DateTimeFormat.forPattern("EEE, dd MMM yyyy HH:mm:ss Z");
DateTimeFormatter MYfmt = DateTimeFormat.forPattern("yyyy-MM-dd");
String date ="Fri, 22 Feb 2013 00:00:00 +0000";
DateTime datetime = NBSfmt.parseDateTime(date);
System.out.println(datetime.toString());
And here is the output:
2013-02-21T19:00:00.000-05:00
Anyone have any idea what is going on here? Any insight would be greatly appreciated.
Thanks,
Paul
This is caused by your timezone. You define it in +0000 but then you're viewing it in -05:00. That makes it appear one day before. If you normalize it to UTC, it should be the same.
Try this code, as evidence:
package com.sandbox;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
public class Sandbox {
public static void main(String[] args) {
DateTimeFormatter NBSfmt = DateTimeFormat.forPattern("EEE, dd MMM yyyy HH:mm:ss Z");
String date = "Fri, 22 Feb 2013 00:00:00 -0500";
DateTime datetime = NBSfmt.parseDateTime(date);
System.out.println(datetime.toString());
}
}
For you, this should show the "right day". But for me, it shows 2013-02-21T21:00:00.000-08:00 because I'm in a different timezone than you. The same situation is happening to you in your original code.
Here's how you can print the string out in UTC:
package com.sandbox;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
public class Sandbox {
public static void main(String[] args) {
DateTimeFormatter NBSfmt = DateTimeFormat.forPattern("EEE, dd MMM yyyy HH:mm:ss Z");
String date = "Fri, 22 Feb 2013 00:00:00 +0000";
DateTime datetime = NBSfmt.parseDateTime(date);
System.out.println(datetime.toDateTime(DateTimeZone.UTC).toString());
}
}
This prints 2013-02-22T00:00:00.000Z.
The timezone of yours is -5, and joda treats the input as UTC in the example. You can use withZone to get a new formatter if needed.
Related
how to convert date from "Tue May 08 2018 13:15:00" to "2018-05-08 13:15:00.000" in java, As i have to use it for where clause in custom sql query ex- TO_timestamp('2018-05-08 13:15:00.000', 'YYYY-MM-DD HH24:MI:SS.FF')
I think I have a suggestion to try to resolve your problem...
Note: You may have to configure the Locale of the SimpleDateFormat because of the translation of dates in the String. Otherwise the exception java.text.ParseException will be thrown.
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class Test {
public static void main(String[] args) {
try {
String dateStr = "Tue May 08 2018 13:15:00";
SimpleDateFormat sdfBefore = new SimpleDateFormat("EEE MMM dd yyyy HH:mm:ss", Locale.ENGLISH);
SimpleDateFormat sdfAfter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
Date date = sdfBefore.parse(dateStr);
System.out.println(sdfAfter.format(date));
} catch (ParseException e) {
e.printStackTrace();
}
}
}
I hope I've helped.
First you need to parse your string:
DateTimeFormatter formatter
= DateTimeFormatter.ofPattern("EEE MMM dd uuuu H:mm:ss", Locale.ENGLISH);
String dateTimeString = "Tue May 08 2018 13:15:00";
LocalDateTime dateTime = LocalDateTime.parse(dateTimeString, formatter);
System.out.println(dateTime);
This prints
2018-05-08T13:15
As has been said in the comments, don’t transfer a string to your database. Assuming you are using at least Java 8 and at least JDBC 4.2 just give the parsed LocalDateTime object to the database through your PreparedStatement, for example:
PreparedStatement queryStatement = yourDbConnection.prepareStatement(
"select * from your_table where your_column = ?");
queryStatement.setObject(1, dateTime);
I am assuming that the source of your string and your database agree about in which time zone the date and time should be interpreted. For most purposes you should prefer to be explicit about time zone.
For anyone reading along and needing a string like 2018-05-08 13:15:00.000 for some other purpose than a database query, the way to obtain this format is through one more formatter:
DateTimeFormatter targetFormatter = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SSS");
String formattedDateTimeString = dateTime.format(targetFormatter);
System.out.println(formattedDateTimeString);
This prints
2018-05-08 13:15:00.000
Link: The Java™ Tutorials: Trail: Date Time explaining how to use java.time, the modern Java date and time API.
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class Test {
public static void main(String[] args) {
String dateStr = "Tue May 08 2018 13:15:00";
DateTimeFormatter formatterFrom = DateTimeFormatter.ofPattern("EEE MMM dd yyyy HH:mm:ss");
LocalDateTime localDate = LocalDateTime.parse(dateStr, formatterFrom);
DateTimeFormatter formatterTo = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
String localDate1 = formatterTo.format(localDate);
System.out.println(localDate1); // 2018-05-08 13:15:00.000
}
}
How to make the date to have a GMT offset like mentioned here
import java.util.*;
import java.text.*;
import java.lang.*;
class TFTest
{
public static void main(String[] args)
{
SimpleDateFormat sdf = new SimpleDateFormat("dd MMM, yyyy z");
Date dt = new Date();
System.out.println("\n\n\nparsed date:"+sdf.format(dt)+"\n\n");
}
}
the above program outputs the value as
parsed date:02 Aug, 2016 IST.
But I want the value to be parsed date:02 Aug, 2016 GMT +05:30
How to get in the specified format ..?
The pattern that should work is dd MMM, yyyy 'GMT' XXX indeed X is the timezone in ISO 8601 which seems to be what you are looking for.
Output:
parsed date:02 Aug, 2016 GMT +05:30
Try, for more documentation visit simpledateformat
"dd MMM, yyyy 'GTM' XXX"
This pattern "dd MMM, yyyy z ZZZZ" will print in the given format
Format formatter = new SimpleDateFormat("dd MMM, yyyy z ZZZZ");
Result like :
02 Aug, 2016 GMT +0000
Consider this program that format the current date, and try to parse it again. It succeeds in French, but fails in English and I don't understand why.
import java.util.Locale;
import java.text.DateFormat;
import java.time.Instant;
import java.util.Date;
import java.text.SimpleDateFormat;
public class HelloWorld{
public static void main(String []args){
try{
SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm:ss", Locale.ENGLISH);
DateFormat.getDateTimeInstance(DateFormat.DEFAULT,DateFormat.DEFAULT, Locale.ENGLISH).parse(formatter.format(new Date()));
System.out.println("English - success");
}catch(Exception ex){
System.out.println(ex);
}
try{
SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm:ss", Locale.FRENCH);
DateFormat.getDateTimeInstance(DateFormat.DEFAULT,DateFormat.DEFAULT, Locale.FRENCH).parse(formatter.format(new Date()));
System.out.println("French - success");
}catch(Exception ex){
System.out.println(ex);
}
System.out.println(Locale.getDefault());
}
}
Output:
java.text.ParseException: Unparseable date: "11 Feb 2015 11:09:26"
French -success
en_US
Please look at http://docs.oracle.com/javase/7/docs/api/java/text/DateFormat.html#parse%28java.lang.String,%20java.text.ParsePosition%29 before telling me that I should use a pattern or anything else. This method is meant to parse a String without a pattern.
I suspect your input format string is wrong.
As per documentation Jun 30, 2009 7:03:47 AM would be a valid format for en_US on Default settings.
You could always check if your format is right by formatting a given Date first.
For example
System.out.println(DateFormat.getDateTimeInstance(DateFormat.DEFAULT,DateFormat.DEFAULT, Locale.ENGLISH).format(new Date())); gives Feb 11, 2015 12:34:48 PM, which doesn't fit 11 Feb 2015 11:09:26.
This should be your correct formatted string for en_US parsing: Feb 11, 2015 11:09:26 AM. Remember, this is AM / PM 12 hour time format, which can be annoying.
are you sure that dd MMM yyyy HH:mm:ss is a correct english format dont they use month before days like US format ?
The default format for English is like this:
SimpleDateFormat formatter = new SimpleDateFormat("MMM dd, yyyy HH:mm:ss a", Locale.ENGLISH);
How can I parse this date format Mon May 14 2010 00:00:00 GMT+0100 (Afr. centrale Ouest) to this date format 05-14-2010 I mean mm-dd-yyyy
it's telling me this error :
java.text.ParseException: Unparseable date: "Mon May 14 2010 00:00:00 GMT+0100 (Afr. centrale Ouest)"
EDIT
SimpleDateFormat formatter = new SimpleDateFormat("M-d-yyyy");
newFirstDate = formatter.parse(""+vo.getFirstDate()); //here the error
Thanks in advance!
This code first adapts the string a bit and then goes on to parse it. It respects the timezone, just removes "GMT" because that's how SimpleDateFormat likes it.
final String date = "Mon May 14 2010 00:00:00 GMT+0100 (Afr. centrale Ouest)"
.replaceFirst("GMT", "");
System.out.println(
new SimpleDateFormat("MM-dd-yyyy").format(
new SimpleDateFormat("EEE MMM dd yyyy HH:mm:ss Z").parse(date)));
Prints:
05-14-2010
Bear in mind that the output is also timezone-sensitive. The instant defined by your input string is being interpreted in my timezone as belonging to the date that the program printed. If you just need to transform "May 14 2010" into "05-14-2010", that's another story and SimpleDateFormat is not well suited for that. The JodaTime library would handle that case much more cleanly.
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Test
{
public static void main( String args[] ) throws ParseException
{
// Remove GMT from date string.
String string = "Mon May 14 2010 00:00:00 GMT+0100 (Afr. centrale Ouest)".replace( "GMT" , "" );
// Parse string to date object.
Date date = new SimpleDateFormat( "EEE MMM dd yyyy HH:mm:ss Z" ).parse( string );
// Format date to new format
System.out.println( new SimpleDateFormat( "MM-dd-yyyy" ).format( date ) );
}
}
Outputs:
05-13-2010
I have a string named DateCompareOld, it has the value "Fri Aug 12 16:08:41 EDT 2011". I want to convert this to a date object.
SimpleDateFormat dateType = new SimpleDateFormat("E M dd H:m:s z yyyy");
Date convertDate = dateType.parse(DateCompareOld);
But everytime I try this, I get a parse exception. I have tried other SimpleDateFormat formatting criteria, but it always fails.
Suggestions?
Try this format:
EEE MMM dd HH:mm:ss zzz yyyy
Quick test:
public static void main(String[] args) throws Exception {
DateFormat df = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
System.out.println(df.parse("Fri Aug 12 16:08:41 EDT 2011"));
}
// outputs
Fri Aug 12 15:08:41 CDT 2011
Output is in CDT, since that's where I am, but the value is right.
DateFormat dateType = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
dateType.setLenient(false);
Date convertDate = dateType.parse(DateCompareOld);
java.time
The legacy date-time API (java.util date-time types and their formatting API, SimpleDateFormat) are outdated and error-prone. It is recommended to stop using them completely and switch to java.time, the modern date-time API*.
Another important thing to note is that your string has English text and therefore you must use Locale.ENGLISH so that you do not get an exception or some wrong result when your code is run on a JVM whose Locale is not English. Anyway, NEVER use a date-time parsing/formatting type (e.g. SimpleDateFormat, DateTimeFormatter etc.) without Locale because these types are Locale-sensitive.
Demo using 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 = "Fri Aug 12 16:08:41 EDT 2011";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("E MMM d H:m:s z u", Locale.ENGLISH);
ZonedDateTime zdt = ZonedDateTime.parse(strDateTime, dtf);
System.out.println(zdt);
}
}
Output:
2011-08-12T16:08:41-04:00[America/New_York]
If at all, you need a java.util.Date object, you can obtain it as follows:
Date date = Date.from(zdt.toInstant());
Learn more about the modern date-time API from Trail: Date Time.
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 {
String strDateTime = "Fri Aug 12 16:08:41 EDT 2011";
SimpleDateFormat sdf = new SimpleDateFormat("E MMM d H:m:s z y", Locale.ENGLISH);
Date date = sdf.parse(strDateTime);
// ...
}
}
Note that the java.util.Date object is not a real date-time object like the modern date-time types; rather, it represents the number of milliseconds since the standard base time known as "the epoch", namely January 1, 1970, 00:00:00 GMT (or UTC). When you print an object of java.util.Date, its toString method returns the date-time in the JVM's timezone, calculated from this milliseconds value. If you need to print the date-time in a different timezone, you will need to set the timezone to SimpleDateFormat and obtain the formatted string from it.
* 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.
Note the String passed to SimpleDateFormat() should be corrected to "EEE MMM dd HH:mm:ss z yyyy"
Here is the code:
import java.util.Date;
import java.text.SimpleDateFormat;
import java.text.ParseException;
public class DateTest{
public static void main(String []args){
String DateCompareOld = "Fri Aug 12 16:08:41 EDT 2011";
SimpleDateFormat dateType = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy");
Date convertDate = new Date();
try{
convertDate = dateType.parse(DateCompareOld);
}catch(ParseException pex){
pex.printStackTrace();
}
System.out.println(convertDate.toString());
}
}