SimpleDateFormat ignores TimeZone - java

I have read a bunch of posts on this, but, I am obviously missing something. I have date string, and a time zone. I am trying to instantiate a date object as follows:
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
java.util.Date dateObj = sdf.parse("2013-10-06 13:30:00");
System.out.println(dateObj);
What is printed is:
Sun Oct 06 09:30:00 EDT 2013
What I want is a date object in UTC format. Not one converted to EDT. What am I doing wrong?
Thanks.

This is because a Date object does not store any timezone information. Date basically only stores the number of milliseconds since the epoch (Jan. 1, 1970). By default Date will use the timezone associated with the JVM. In order to preserve timezone information you should continue using the DateFormat object that you've already got.
See DateFormat#format(Date): http://docs.oracle.com/javase/7/docs/api/java/text/DateFormat.html#format(java.util.Date)
The following should give you what you're looking for:
System.out.println(sdf.format(dateObj));

Try below code, you'll see that the date parsed 1st time is different from the one parsed after setting timezone. Actually the date is parsed as expected in right timezone. It s while printing it gives you get the machines's default TZ.
You could have printed the dateObj.toGMTString() to check the same, but that is deprecated.
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date dateObj = sdf.parse("2013-10-06 13:30:00");
System.out.println(dateObj.toString());
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
dateObj = sdf.parse("2013-10-06 13:30:00");
System.out.println(dateObj.toString());

Related

How do I update a String value into MySQL Datetime in java code using PreparedStatement?

I have a date/time value in String form like "11/28/2017 4:00:49 PM" in my java code. Now how can I take this same value to MySQL column of type datetime?
Please note, I'm using PreparedStatement to insert the record in MySQL DB.
Here are the few ways I tried...
DateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
DateFormat outputFormat = new SimpleDateFormat("MM-dd-yyyy KK:mm:ss a");
ps.setString(outputFormat.format(inputFormat.parse(rs.getString(1))));
I used the above code and I'm getting the below exception...
com.mysql.jdbc.MysqlDataTruncation: Data truncation: Incorrect datetime value: '08-09-0017 02:46:57 AM' for column 'column_name' at row 1
If I use the below code, I'm getting only Date but time with AM/PM is lost
ps.setDate(inputFormat.parse(rs.getString(1)));
If I use the below code, I'm getting only Time but without AM/PM and Date
ps.setTime(inputFormat.parse(rs.getString(1).getTime()));
If I use the below code, I get error
ps.setDate(1, (java.sql.Date) new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("11/28/2017 4:00:49 PM"));
java.lang.ClassCastException: java.util.Date cannot be cast to java.sql.Date
After several tries, I found that MySQL DB won't accept the 12 hour format for datetime type column.
The Code I used is below shown.
ps.setTimestamp(i, new java.sql.Timestamp(new SimpleDateFormat("MM-dd-yyyy KK:mm:ss a").parse("10-26-2017 2:46:57 PM").getTime()));
Output I got in MySQL DB is as shown below, which is in 24 hour format.
2017-10-26 14:46:57.000000
java.util.Date date1=new java.util.Date();
java.sql.Date currentdate=new java.sql.Date(date1.getTime());
java.sql.Time currenttime=new java.sql.Time(date1.getTime());
prepareStatement.setDate(1,currentDate);
prepareStatement.setTime(2,currentTime);
see this code it will current Date and Time
Since you want to parse into a Date your String, and that your problem is the AM/PM, you can see in the SimpleDateFormat documentation :
Letter Date or Time Component Presentation Examples
a Am/pm marker Text PM
So this should be something like :
String s = "11/28/2017 4:00:49 PM";
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy k:mm:ss a");
java.util.Date myDate = sdf.parse(s);
System.out.println(myDate);
Tue Nov 28 16:00:49 CET 2017
Note that in your code, you are not using a format that match at all
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
.parse("11/28/2017 4:00:49 PM"))
For the way to use a java.util.Date in a PreparedStatement, I prefer to let you see that in the complete post : Using setDate in PreparedStatement
But basically, you just need to
ps.setDate(i, new java.sql.Date(myDate.getTime());
or (not sur if Date manage the time part in mysql... it might depends on the jdbc version)
ps.setTimestamp(i, new java.sql.TimeStamp(myDate.getTime());

Convert String to GMT timezone date. JAVA

I am getting a date/time string from web in the format of yyyy-mm-dd HH:MM:SS and it is in UTC.
I have to create a Date object and print the date object in GMT format, but I don't want the to change, for example if I read the date as 2014-10-22 09:00:00, then it should be displayed as 2014-10-22 09:00:00 GMT instead of 2014-10-22 13:30:00
How do I do this? Please suggest me.
(FYI, Currently, UTC time is 10:25 AM, in india current time is 3:55 PM).
I am using Jaxb parser to parse the XML. Any suggestions are invited
You could use a SimpleDateFormat to parse the date, and then reformat it to a different timezone.
String toTimeZone = "GMT";
String fromTimeZone = "UTC";
String stingvalue = "2014-10-14 03:05:39";
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
dateFormat.setTimeZone(TimeZone.getTimeZone(fromTimeZone));
Date parsedDate = dateFormat.parse(stingvalue);
dateFormat.setTimeZone(TimeZone.getTimeZone(toTimeZone));
String newDate = dateFormat.format(parsedDate);
Explanation
The Java Date class counts time in milliseconds from January 1, 1970 00:00:00.000 GMT. As such, your Dates are time zone neutral. To get date in a different time zone, simply format it differently

Read date without timezone information

I receive datetime strings with no timezone qualifier in the format:
2014-01-30 07:48:25
I know that the strings are produced by a server in Florida. Is there a way using java.util or joda Date libs to specify that the date is from Florida then parse it with the appripriate UTC offset, depending on where it falls in the calendar for daylight savings time?
Assuming you are referring to the part of Florida following EST, you can set the timezone for SimpleDateFormat and set your TimeZone to EST.
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
format.setTimeZone(TimeZone.getTimeZone("America/New_York"));
Date date = format.parse("2014-01-30 07:48:25");
Your parsed date now can be utilized by your default TimeZone of the system (or set it to your liking as we did in the first place).
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
System.out.println(date);
The output I get for your date offset to UTC:
Thu Jan 30 12:48:25 UTC 2014
You can provide a "source timezone" to an instance of SimpleDateFormat and the to-be-parsed date string is then converted to your local/default timezone.
TimeZone timeZone = TimeZone.getTimeZone("America/New_York")
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
sdf.setTimeZone(getTimeZone(source));
Be careful when providing the time zone name. TimeZone will silently fail over to GMT if you pass in a string it does not understand as a timezone.
Just to complete previous answers. The same funcionality with Joda-Time:
DateTime dateTime = DateTime.parse("2014-01-30 07:48:25", DateTimeFormat
.forPattern("yyyy-MM-dd HH:mm:ss")
.withZone(DateTimeZone.forID("America/New_York")));
System.out.println(dateTime);
System.out.println(dateTime.withZone(DateTimeZone.UTC));
System.out.println(dateTime.withZone(DateTimeZone.forID("Europe/Madrid")));
---
2014-01-30T07:48:25.000-05:00
2014-01-30T12:48:25.000Z
2014-01-30T13:48:25.000+01:00

Parsing date gives Date of different format to what is specified. (Java)

I get dates as Strings (ie: 2013-04-07 17:20:16.0) and I need to create Date objects to represent these so that I can set the date's in JSpinners.
I am using this to format the date strings I get:
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
I am using it like this:
df.setLenient(false);
Date tempDateOld = new Date();
tempDateOld = df.parse("2013-04-07 17:20:16.0");
However this:
System.out.println(tempDateOld.toString());
gives this:
Sun Apr 07 17:20:16 CAT 2013
Why does it not just give me a Date with the date in the same format? How do I take a date of a given format and create a Date object with the date of the same format.
Any help will save my sanity, thanks.
Try
System.out.println(df.format(tempDateOld));
The date by itself does not keep the format.

String to Date in a PreparedStatement

I am trying to use setDate() in a PreparedStatement, however the date that I have is in the format of 2008-07-31. The code is:
pstmt.setDate(f++, (Date) DateFormat.getDateInstance(DateFormat.DEFAULT).parse(value.substring(0, 10)));
However, it gives me the error:
Exception in thread "main" java.text.ParseException: Unparseable date: "2008-07-31"
Why is this?
If you have a very specific date, don't ask Java to use a default date format - set it yourself.
For example:
DateFormat parser = new SimpleDateFormat("yyyy-MM-dd");
Date date = parser.parse(value.substring(0, 10));
You should also potentially set the time zone of the parser... my guess is that UTC is the most appropriate time zone here.
Note that this has nothing to do with prepared statements as such - it's just date parsing.
(As an alternative to using DateFormat and SimpleDateFormat, you could use Joda Time which has a nicer API and thread-safe formatters/parsers. You can ask Joda Time to convert from its own types to Date values. Possibly overkill if you only need it for parsing here, but if you're doing anything else with dates, it's well worth looking into.)
You need make sure the default DateFormat is in yyyy-MM-dd format (usually it's a config in OS), or you can use SimpleDateFormat or java.sql.Date to parse date string.
java.util.Date d;
SimpleDateFormat sdf = new SimpleDateFormat ("yyyy-MM-dd");
d = sdf.parse ("2008-07-31");
// or
d = java.sql.Date.valueOf ("2008-07-31");
or, you could just set parameter as String, if the underlying database driver support the VARCHAR/CHAR to DATE conversion.
DateFormat.DEFAULT points to MEDIUM format and MEDIUM format looks like Jan 12, 1952. So, you may have create a SimpleDateFormat object with the format you are using.
I think there is mismatch in the format of the date that you are providing as input and the format in which you have specified while formatting which is default in your case.
SimpleDateFormat parser = new SimpleDateFormay("yyyy-MM-dd");
Try using the same format for both the dates.
First convert String to Date and then set that to PreparedStatement. Check with below code.
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-mm-dd");
Date convertedDate = dateFormat.parse(dateString);
I'd use
pstmt.setDate(f++,
new java.sql.Date(
new SimpleDateFormat("yyyy-MM-dd")
.parse(value.substring(0, 10))
.getTime()
)
);

Categories