struts-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Andrew Hill <andrew.david.h...@gridnode.com>
Subject Re: [OT] java date and time issue
Date Fri, 18 Feb 2005 06:26:49 GMT
<snip>
1. How to find out what time zone the user is in?
</snip>

You cant (afaik). The closest you can get is to use javascript to determine
their current GMT offset, that however will not give you the actual
timezone (including such things as daylight savings rules and so forth)
but it may be close enough for your needs. In one webapp I did the
UI for I used the GMT offset to narrow down the list of timezones
available in java to those with which the gmt offset was compatable and
present these to the user in a select box on the login screen. The
selected timezone is then put into a session attribute. Use this
timezone when formatting any dates that you render so that they show up
to the user in their selected timezone and not the servers timezone.
(Btw: dont cache DateFormat instances in session as they arent threadsafe)

<snip>
2. How to make data updation program use that time zone to update the
database
</snip>

Presumably you will want to convert the users entry from a String into
one of the java date classes at some point before you pass it to the
database? You will parse the dates the users enter using an instance of
DateFormat. You can call its setTimeZone() method to set the timezone
from which the date is coming. This is necessary because a java date
doesnt store any timezone, but rather the date (and time) is represented
internally as a long value which contains the number of milliseconds
past the epoch (which in java is (and also rather conveniently in many
other languages including javascript) 1970-01-01 00:00:00 UTC).

This implies some potential gotchas when using the java date handling.

For example, if you parse the string "1970-01-01 00:00:00" into a Date,
the milliseconds will differ depending on which timezone you tell the
format that the string is coming from. For UTC (aka GMT) the resulting
long value would of course be 0, but for GMT+8 it would be -28800000
(which is of course -8 hours worth of milliseconds). If you then go and
display this very same java.util.Date instance formatted for a user
whose timezone is PST (California) they will see 1969-12-31 16:00:00
because thats what time (and date) it is over there. This of course is
all good and correct, because after all 16:00PST and 00:00UTC are both 
at the same point in time, just represented differently depending
on the local timezone.

As I mentioned earlier however there are some potential gotchas relating
to the java date time handling that may (or may not) cause you some
problems.

For example, for the timezone "Asia/Singapore" parsing the "1970-01-01
00:00:00" string to a Date will get you a long value internally of
-27000000 under a 1.4 JVM. But wait you say! Isn't Singapore 8 hours
ahead of GMT? Yes it is. Now. But in 1970 it was only 7 hours and 30
minutes ahead of GMT. (They didnt move it to 8 hours after GMT until 
1982). The 1.4 JVM actually models
this in its "Asia/Singapore" zone, but not of course under the more
generic "GMT+8" zone. Java 1.3 on the other hand, doesnt model this and 
so uses an 8 hour offset for 1970.

This caused me no end of grief recently (warning: rambling war story
follows!) in an RMI based (ie: not a web app(so actually its more a jar
story than a war story ;->)) timesheet application I wrote a few years
back where I was using the java.sql.Time class to represent time.

Recently we had been getting all sorts of wierd errors
and data corruption due to a combination of dodgy assumptions on the 
part of my code (ie: startTime < endTime, all clients in same timezone, 
etc...) together with the nasty issue that the time as perceived by the 
server was different to that perceived by the client as the server had 
been happily running on a 1.3 JVM for some 3 years, while the clients 
were now upgraded to 1.4 JVMs - some of which had the default timezone 
of GMT+8 and some "Asia/Singapore".

Now obviously the timesheet
system in question wasnt trying to record work done in 1970, but I was
using java.sql.Time to represent times of day for the start and end 
times of blocks of work, with a seperate field for the date. The 
java.sql.Time is a subclass of java.util.Date and as such works the same 
way as Date. Since its only recording a time however, it sets the 'date 
part' to be the epoch date. Its therefore representing a time on the 1st 
of January 1970, and that means that when we parse a string into a Time 
instance, such as its valueOf() method does, the UTC offsets applicable 
to 1970 are used.

If we then serialise this to another machine (and the only actual data 
recorded in a Date is a long as you will recall) and that machine has a 
different JVM or uses a different timezone, its going to consider the 
value as being different to what the client was considering it as.

For the most part this just meant time being recorded half an hour off 
from what the user intended, and since the process operated in reverse
when loading the sheets from the server back to the same client it wasnt
usually noticed.

Where we were recording time near midnight however (and being an IT 
company we are often working well past midnight) several of the 
assumptions made by the code would be broken when the time was 
reinterpreted as being at the other end of the day and 'bad things' 
would happen.

Took me ages to figure out what was happening:

JVM Version=1.4.2_06
Timezone=GMT+08:00
Current UTC Offset=28800000
Epoch UTC Offset=28800000
00:00:00=-28800000
07:30:00=-1800000
08:00:00=0

JVM Version=1.4.2_06
Timezone=Asia/Singapore
Current UTC Offset=28800000
Epoch UTC Offset=27000000
00:00:00=-27000000
07:30:00=0
08:00:00=1800000

JVM Version=1.3.0
Timezone=Asia/Singapore
Current UTC Offset=28800000
Epoch UTC Offset=28800000
00:00:00=-28800000
07:30:00=-1800000
08:00:00=0

In your case I should hope that most of these traps wont apply, but its 
still worthwhile to be aware of such potentials, as they can be darn 
hard to track down sometimes!

<snip>
3. How to test this function is working, with out traveling to different 
parts of world
</snip>

Nah, you will have travel to test it. Be sure to claim the expense from 
your company of course, and Id advise you pay special attention to 
testing from places like Tahiti, Bali, The French Riviera, Hawaii, and 
so forth. Wouldnt want any bugs to slip through now would we? ;-)

hth
Andrew


ps: heres some code you can play with to get familiar with DateFormat 
class if your not already:

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;

public class DateParsing
{
   public static void main(String[] args)
   {
     try
     {
       TimeZone singapore = TimeZone.getTimeZone("Asia/Singapore");
       TimeZone greenwitch = TimeZone.getTimeZone("UTC");
       TimeZone california = TimeZone.getTimeZone("PST");
       String inPattern = "yyyy-MM-dd HH:mm:ss";
       String outPattern = "dd/MM/yyyy 'at' hh:mm a";
       DateFormat df = new SimpleDateFormat(inPattern);
       df.setTimeZone(singapore);
       Date date = df.parse("2005-02-18 14:08:59");
       df = new SimpleDateFormat(outPattern);
       df.setTimeZone(singapore);
       System.out.println("SGT:"+df.format(date));
       df.setTimeZone(greenwitch);
       System.out.println("UTC:"+df.format(date));
       df.setTimeZone(california);
       System.out.println("PST:"+df.format(date));
     }
     catch(ParseException e)
     {
       throw new RuntimeException("oops!",e);
     }
   }
}

which gives:

SGT:18/02/2005 at 02:08 PM
UTC:18/02/2005 at 06:08 AM
PST:17/02/2005 at 10:08 PM



Ashish Kulkarni wrote:
> Hi
> We have a situtation where we will be hosting our web
> server in USA and users from all over the world will
> be accessing this, these users will do some
> transaction which will update the database.
> Now the problem is with date and time, we dont want to
> enter system date and time, but the local date and
> time for the user, 
> here are the possible situtation and i need some
> suggestions on handling them
> 1. How to find out what time zone the user is in?
> 2. How to make data updation program use that time
> zone to update the database
> 3. How to test this function is working, with out
> traveling to different parts of world, 
> Regards
> Ashish
> 
> 
> 		
> __________________________________ 
> Do you Yahoo!? 
> All your favorites on one personal page – Try My Yahoo!
> http://my.yahoo.com 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> For additional commands, e-mail: user-help@struts.apache.org
> 
> 



---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Mime
View raw message