File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
The moose likes Java in General and the fly likes Problem computing time based on TimeZones Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login

Win a copy of Java Interview Guide this week in the Jobs Discussion forum!
JavaRanch » Java Forums » Java » Java in General
Bookmark "Problem computing time based on TimeZones" Watch "Problem computing time based on TimeZones" New topic

Problem computing time based on TimeZones

Ritu Bansal

Joined: Nov 07, 2007
Posts: 11
I have a piece of code that generates timestamps based on US TimeZones such as Pacific, Central and Eastern. I get correct results when I run this code locally (EST) but get results an hour off when I run the same code on a server running in US central time. See the results below and the code that I run.

Results from running the code on Dev Server:
ts: 2007-11-05 10:39:03.19 (Default time)
tsEST: 2007-11-05 10:39:03.019 (EST based on TimeZone String America/New_York, should be 11:39)
tsCST: 2007-11-05 09:39:03.019 (Central time based on TimeZone String US/Central, should be 10:39)
tsPST: 2007-11-05 07:39:03.019 (Pacific time based on TimeZone String America/Los_Angeles, should be 8:39)

Results from running the same code on Local machine:
tsEST: 2007-11-05 11:39:01.272 (Eastern Time based on TimeZone String America/New_York)
tsCST: 2007-11-05 10:39:01.272 (Central time based on TimeZone String US/Central)
tsPST: 2007-11-05 08:39:01.272 (Pacific time based on TimeZone String America/Los_Angeles)

Below is the code that I ran.

Timestamp ts = new Timestamp(Calendar.getInstance().getTime().getTime());
DateFormat df1 = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss.SS" );

GregorianCalendar cal1 = new GregorianCalendar();
Timestamp tsNow = new Timestamp(cal1.getTimeInMillis());

TimeZone tsEST = TimeZone.getTimeZone("America/New_York");
String inPattern = "yyyy-MM-dd HH:mm:ss.SS";
DateFormat df = new SimpleDateFormat(inPattern);
Date date = df.parse(tsNow.toString());
ts = new Timestamp( df1.parse( df.format(date) ).getTime() );
System.out.println("tsEST: " + ts.toString());

DateFormat df2 = new SimpleDateFormat(inPattern);
TimeZone tsCST = TimeZone.getTimeZone("US/Central");
ts = new Timestamp( df1.parse( df2.format(date) ).getTime() );
System.out.println("tsCST: " + ts.toString());

TimeZone tsPST = TimeZone.getTimeZone("America/Los_Angeles");
ts = new Timestamp( df1.parse( df.format(date) ).getTime() );
System.out.println("tsPST: " + ts.toString());

Can somone help me identify why the server is not producing correct time.
Ernest Friedman-Hill
author and iconoclast

Joined: Jul 08, 2003
Posts: 24199


Welcome to JavaRanch!

So do you know about Daylight Savings Time, and how wall-clock time in New York is EDT right now, not EST? What time does the clock on the wall near the "central time" server say when you run this code? Have both systems (and JVMs) had the appropriate Daylight Savings Time patches applied, since the dates for DST were changed this year?

[Jess in Action][AskingGoodQuestions]
James Gustavsen

Joined: Nov 07, 2007
Posts: 1
I believe that the time changed from EDT to EST last weekend Nov. 4.
Paul Clapham

Joined: Oct 14, 2005
Posts: 19973

Using a SimpleDateFormat and setting its TimeZone is the correct thing to do. But I don't understand that business with the Timestamp object. So I would just leave it out. Right now you are trying to test too many things with a single test.
Jim Yingst

Joined: Jan 30, 2000
Posts: 18671
Yes, daylight saving time ended last Sunday in the US.

There seems to be a lot of unnecessary code here, formatting and parsing and toStringing back and forth. I can't keep track of what's going on here. Or at least I'm not motivated to try - what you need is much simpler, e.g. for pacific time:

Once the date and time zones are created, the only thing necessary to convert the date to a particular time zone is the call to format(). Not format() and parse() and getTime() and toString() - just format.
[ November 07, 2007: Message edited by: Jim Yingst ]

"I'm not back." - Bill Harding, Twister
Ritu Bansal

Joined: Nov 07, 2007
Posts: 11
Thanks everyone for taking interest in my problem.

The above code looks complicated so I have tried to make it simpler below. I still need to produce a timestamp based on the timezone.

Date date = new Date();
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SS");
Timestamp tsPST = new Timestamp(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SS").parse(df.format(date)).getTime());

My local machine is in Eastern timezone and the server is in US Central time zone. I ran the same piece of code exactly at the same time on both machines and I get 2 different sets of time with an hour difference which I shouldn't. The generated timestamp (from the system out )that I get at my local machine is 2007-11-07 12:28:17.549 and at the server is 2007-11-07 11:28:17.549. The server seems to be not producing correct timestamp.

The server is running jdk 142_11. What patch should be applied to the server to reflect correct results.
Paul Clapham

Joined: Oct 14, 2005
Posts: 19973

I still need to produce a timestamp based on the timezone.
And here's the part of the problem you aren't understanding. A timestamp just contains the number of milliseconds since midnight (GMT) on January 1, 1970. You can certainly format a timezone to show the equivalent time in any timezone you like, and you already know how to do that with SimpleDateFormat. But wanting the timestamp itself to contain the timezone makes no sense. All of that formatting and parsing back and forth is going to get you nowhere.
Ritu Bansal

Joined: Nov 07, 2007
Posts: 11
Thanks everyone. I have it resolved now. I noticed that only the format method produces the correct timezone based time. So I am using the date string produced by the format. If I try to parse it to get the date object, it doesn't work.
I agree. Here's the link:
subject: Problem computing time based on TimeZones
It's not a secret anymore!