Java setting timezone while converting date from Mountain to Eastern to GMT - java

I am trying to convert mountain time to eastern time to GMT time. But when I am getting the final date in the date field "gmtDate",it's back to my local date in mountain time.
Here are my questions:
I am expecting to see 2 hrs of difference from mountain time to eastern time. But seeing only an hor of difference. What is wrong here?
Again there should a six hours of difference from eastern time to GMT time but it is 5 hours of difference showing here. What is wrong?
Finally, I tried to save the date and time as GMT but looks like it's coming back to mountain time. What is wrong here?
Here is my final output:
DEBUG [main] (MyClass.java:100) - local : 2014-07-14 10:11:04 MDT
DEBUG [main] (MyClass.java:108) - est : 2014-07-14 11:11:04 EST
DEBUG [main] (MyClass.java:110) - =================================================
DEBUG [main] (MyClass.java:113) - gmt : 2014-07-14 16:11:04 GMT
DEBUG [main] (MyClass.java:125) - gmt date : Mon Jul 14 10:11:04 MDT 2014
DEBUG [main] (MyClass.java:127) - =================================================
Here is my example code:
private Date testTimeZone(Date date, TimeZone sourceTimeZone, TimeZone targetTimeZone) {
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
Date localdate = null;
try {
localdate = df.parse("2014-07-14 09:11:04 MST");
} catch (ParseException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
LOG.debug("local : " + df.format(localdate));
df.setTimeZone(TimeZone.getTimeZone("EST"));
LOG.debug("est : " + df.format(localdate));
LOG.debug("=================================================");
df.setTimeZone(TimeZone.getTimeZone("GMT"));
LOG.debug("gmt : " + df.format(localdate));
Date gmtDate = null;
try {
gmtDate = df.parse(df.format(localdate));
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
LOG.debug("gmt date : " + gmtDate);
LOG.debug("=================================================");
return gmtDate;
}

So I ran your code and instead of getting mountain time, I got gmt date : Mon Jul 14 12:11:04 EDT 2014
This timezone corresponds to my timezone which lead me to the discovery that Date.toString() uses the local timezone to format the date. Per the Java date specification, a Date is:
A thin wrapper around a millisecond value that allows JDBC to identify this as an SQL DATE value. A milliseconds value represents the number of milliseconds that have passed since January 1, 1970 00:00:00.000 GMT.
So the whole DateFormat code you are dealing doesn't actually change a value. It just matters how it is output. The underlying number of milliseconds will never actually change
Also, EST is for the winter, and EDT (Eastern Daylight Time) is used in the summer (Change this and your first two questions are resolved)

Java Date represents a moment in time, and does not include an internal TimeZone. Instead, you use the SimpleDateFormat (such as you already have!) to perform the display formatting.
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
try {
Date date = df.parse("2014-07-14 09:11:04 MST");
df.setTimeZone( TimeZone.getTimeZone( "EST" ) );
System.out.println(df.format(date));
df.setTimeZone( TimeZone.getTimeZone( "GMT" ) );
System.out.println(df.format(date));
} catch (ParseException e) {
e.printStackTrace();
}
Which outputs
2014-07-14 11:11:04 EST
2014-07-14 16:11:04 GMT
The reason you get gmt date : Mon Jul 14 10:11:04 MDT 2014 is because the TimeZone associated with the DateFormat is changed to MDT when you parse localdate - which is local : 2014-07-14 10:11:04 MDT in your example.

The default timezone is your local timezone, so you should have used:
df.setTimeZone(TimeZone.getTimeZone("GMT");
LOG.debug("gmt date : " + df.format(gmtDate));
You probably want to be using UCT (Universal Coordated Time) .. that is what you want to store and retrieve (if you use a database or other store. GMT represents an actual timezone now, UCT is the "reference" time.

Related

Java TimeZone Conversion producing opposite results.

Here is the sample I am using.
import java.util.*;
import java.text.*;
public class TimeZoneTest
{
public static final String UTC_ZONE = "UTC";
static String utcDateString = "01/11/2016 11:00:00";
public static void main (String [] args)
{
DateFormat df;
try{
df = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
System.out.println("Original Date : " + utcDateString);
df.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = df.parse(utcDateString);
System.out.println(" In its Date format : " + date.toString());
System.out.println(" In its GMT format : " + date.toGMTString());
System.out.println(" In its Local format : " + date.toLocaleString());
}
catch (ParseException ex)
{
System.out.println("Exception!!!!");
}
}
}
Here is the output produced.
Original Date : 01/11/2016 11:00:00
In its Date format : Mon Jan 11 06:00:00 EST 2016
In its GMT format : 11 Jan 2016 11:00:00 GMT
In its Local format : Jan 11, 2016 6:00:00 AM
When using the time 11:00:00 and setting the TimeZone to UTC, I was expecting that the 11:00:00 which is my local time (Eastern) representation would then be converted to UTC which would produce 16:00:00.
Instead, it seems to take the string value 11:00:00 and process it as the UTC time instead of local time and return back my local time which is 06:00:00.
Is this the expected results?
When you set the timezone, is it supposed to convert the time being parsed (11:00:00 ) to that timezone and produce (16:00:00)?
OR
When you set the timezone, is it supposed to treat the time being parsed (11:00:00 ) as though it was in that timezone and return the local time (06:00:00)?
You're last statement is true: "OR When you set the timezone, is it supposed to treat the time being parsed (11:00:00 ) as though it was in that timezone and return the local time (06:00:00)?"
Basically, you set the timezone in the DateFormat, then you parse a date without timezone information, so it'll use the timezone from the DateFormat, to convert the String to certain amount of milliseconds from January 1, 1970. Then, you print that date with "toString" that will convert it back to String using your machine's timezone. But the date is the same throughout the program, just different format/timezone.

Convert UTC Date to local Date

I am converting from epoch time (which is in UTC) to a format as shown below. Now I tried different SO answers to convert UTCDate from UTC to local time. But I am not getting the local time.
Any help would be appreciated.
String epochTime = "1436831775043";
Date UTCDate = new Date(Long.parseLong(epochTime));
Date localDate; // How to get this?
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("h:mm a");
String result = simpleDateFormat.format(UTCDate);
Also, the conversion has to be done without the help of any external library.
Java 8
String epochTime = "1436831775043";
Instant utcInstant = new Date(Long.parseLong(epochTime)).toInstant();
ZonedDateTime there = ZonedDateTime.ofInstant(utcInstant, ZoneId.of("UTC"));
System.out.println(utcInstant);
LocalDateTime here = there.withZoneSameInstant(ZoneId.systemDefault()).toLocalDateTime();
System.out.println(here);
Which outputs:
2015-07-13T23:56:15.043Z
2015-07-14T09:56:15.043
After thoughts...
I think you're chasing your tail. Date is just a container for the number of milliseconds since the epoch (January 1, 1970, 00:00:00 GMT). It doesn't internally carry a representation of a time zone (AFAIK).
For example...
String epochTime = "1436831775043";
Date UTCDate = new Date(Long.parseLong(epochTime));
// Prints the "representation" of the Date
System.out.println(UTCDate);
// Local date/time format...
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd/MM/yyyy h:mm:ss a");
try {
System.out.println("local format: " + simpleDateFormat.format(UTCDate));
System.out.println("local Date: " + simpleDateFormat.parse(simpleDateFormat.format(UTCDate)));
} catch (ParseException ex) {
Logger.getLogger(JavaApplication203.class.getName()).log(Level.SEVERE, null, ex);
}
// UTC date/time format
try {
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println("utc format: " + simpleDateFormat.format(UTCDate));
System.out.println("utc date: " + simpleDateFormat.parse(simpleDateFormat.format(UTCDate)));
} catch (ParseException ex) {
Logger.getLogger(JavaApplication203.class.getName()).log(Level.SEVERE, null, ex);
}
Which outputs...
Tue Jul 14 09:56:15 EST 2015
local format: 14/07/2015 9:56:15 AM
local Date: Tue Jul 14 09:56:15 EST 2015
utc format: 13/07/2015 11:56:15 PM
utc date: Tue Jul 14 09:56:15 EST 2015
If you have a look at local Date and utc date they are the same thing, even though the local format and utc format are formatted correctly.
So, instead of chasing your tale trying to get Date to "represent" a value you want, either use Java 8's Time API or JodaTime to manage the Time Zone information or simply format the Date into the Time Zone you want...
Further, if we do something like...
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd/MM/yyyy h:mm:ss a");
Date localDate = simpleDateFormat.parse(simpleDateFormat.format(UTCDate));
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Date utcDate = simpleDateFormat.parse(simpleDateFormat.format(UTCDate));
System.out.println(localDate.getTime());
System.out.println(utcDate.getTime());
System.out.println(localDate.equals(utcDate));
It will print...
1436831775000
1436831775000
true
You can set your time zone in the formatter:
simpleDateFormat.setTimeZone(TimeZone.getDefault());

Java date string parse creates difference of timezone

I am bit frustrated by this.
I have a String "2015-02-18T23:44:59" which represents time in GMT format.
I want to parse this date into date object.
String dateStr = "2015-02-18T23:44:59";
Date date = DateUtils.parseDate(dateStr, new String[]{"yyyy-MM-dd'T'HH:mm:ss"});
System.out.println(dateStr + " \t" + date.toString());
This outputs :
2015-02-18T23:44:59 Thu Feb 19 05:14:59 IST 2015
As you can see latter time has time zone IST but my original time was GMT.
I don't think there is any parse function which takes current date's time zone.
One way to answer is this question is that :
date.setTime(date.getTime() + ( date.getTimezoneOffset() * 60 * 1000));
System.out.println("\t" + date.toString());
This outputs:
Wed Feb 18 23:44:59 IST 2015
Which seems correct time (but incorrect time zone). Additionally, getTimezoneOffset() is deprecated.
Can anyone suggest me a better way to deal with String dates considering time zones.
I'd use a date format:
SimpleDateFormat utcFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
utcFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = utcFormat.parse("2015-02-18T23:44:59");

joda + how can we override epoch date with todays date

I have a requirement, where I need to override the date
when I parse time(hh:mm:ss) using SimpleDateFormat, what i get is object of date (Thu Jan 01 hh:mm:ss IST 1970)
i want to overide epoch date with today date(without time).
is there a api or method in joda/jdk, which can do this for me
Basically, you can't, but what you can do, is merge the values from the "time" conversion with another date (like today)...for example
try {
Date date = new SimpleDateFormat("hh:mm:ss").parse("13:30:51");
System.out.println(date);
Calendar time = Calendar.getInstance();
time.setTime(date);
Calendar today = Calendar.getInstance();
today.set(Calendar.HOUR_OF_DAY, time.get(Calendar.HOUR_OF_DAY));
today.set(Calendar.MINUTE, time.get(Calendar.MINUTE));
today.set(Calendar.SECOND, time.get(Calendar.SECOND));
System.out.println(today.getTime());
} catch (ParseException ex) {
ex.printStackTrace();
}
There's probably a really fancy way of doing this with less code, but I was trying to avoid deprecated methods.
For me, this outputs...
Thu Jan 01 13:30:51 EST 1970
Thu Oct 31 13:30:51 EST 2013
Beware though, this does not reset the milliseconds value of the today Calendar, in case that's important...

Get correct long value from parsed Date (Timezone issue)

I'm trying to parse a date from a String and get the long value. The long value will be later sent to an SQL query.
here's my code:
String dayDate = "28-02-2013";
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
Date day = new Date();
try {
day = sdf.parse(dayDate);
} catch (ParseException pe) {
pe.printStackTrace();
}
System.out.println("day : "+day.toString()+ " long : " + day.getTime());
which gives the following output:
day : Thu Feb 28 00:00:00 EET 2013 long : 1362002400000
which is correct but not what I want since the long value results in Wed, 27 Feb 2013 22:00:00 GMT (http://www.epochconverter.com/) (I'm in a GMT+2 timezone). And i need to send to correct long value to sql.
Is there anyway to work around this without using external libraries?
SimpleDateFormat is locale-aware, meaning the date it parses is in your timezone. Midnight 28 Feb in GMT+2 is actually 10pm 27 Feb in GMT, the long value 1362002400000. I would add this to get the parsing right (would't bother using Calendar):
sdf.setTimeZone(TimeZone.getTimeZone("GMT"))
Again, when you print this date it uses SimpleDateFormat and that's why you can see EET in the output.
Passing this to database is a different story though once you get this right.
Use DateFormat.setCalendar(Calendar cal) to set a Calendar with GMT as its timezone, or use DateFormat.setTimeZone(TimeZone zone) with the GMT TimeZone. That will ensure that the resulting Date will be 00:00:00 in GMT instead of in EET.
If you add a timezone specifier to your string you can force java to use GMT for the conversion:
String dayDate = "28-02-2013";
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy z"); // z is a timezone specifier
Date day = new Date();
try {
day = sdf.parse(dayDate + " GMT"); // Use GMT timezone.
} catch (ParseException pe) {
pe.printStackTrace();
}
System.out.println("day : "+day.toString()+ " long : " + day.getTime());
You are converting between text and internal (Date) representations of dates and times without explicitly stating the time-zone. That never goes well.
Calendar calendar = Calendar.getInstance();
calendar.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles"));
Date date = calendar.getTime();
Use your timezone String:
TimeZones

Categories