I currently work in the capacity of Software Engineer at a reputed company in Sri Lanka. I'm most keen in J2EE Technologies and love working with open source libraries which fit my project needs. Very interested in the NoSQL concept and experimenting with various products to find a good blend for our projects within the company. Part time freelancer. Avid contributor in the stackoverflow arena. Android is another area which I am looking at with very keen interest as I believe mobile development is the way forward. Dinuka is a DZone MVB and is not an employee of DZone and has posted 24 posts at DZone. You can read more from them at their website. View Full User Profile

Local time of any country based on GMT with Java

06.20.2011
| 6482 views |
  • submit to reddit

In a recent change request for one application i was working on, it was requested to update the time stamp a certain task was done based on the location of the user. We have a separate Country table stored which has the GMT action and the GMT off set defined in minutes.

I was searching for a way to get the local time of a certain country using the Calendar object. There were many sites that gave various information which led to me finding a work around by testing with various parameters. This is what i came up with in the end.


Following i have encapsulated the final outcome into a method so it would be easier to understand and use if anyone ever needs it;

 public static final String GMT_STR = "GMT";
	public static final String COLON_STR = ":";
	public static final String ZERO = "0";
	
	/**
	 * This method will take as parameters the GMT off set in minutes
	 * as well as the GMT actions i.e + or - and based on that will
	 * output the calendar object representing that specific time in that
	 * location. The GMT is defined in minutes so that the calculation is
	 * simplified.
	 * @param gmtOffSetHrs 
	 * @param gmtAction
	 * @return
	 */
	public static Calendar getLocalTime(int gmtOffSetMins,
			String gmtAction) {

		// This will get the quotient part of the division
		int gmtHours = (gmtOffSetMins / 60);
		// This will get the remainder of the division which will give us the
		// minutes portion
		Integer gmtMins = Integer.valueOf((gmtOffSetMins % 60));
		if (gmtMins < 10) {
			gmtMins = Integer.valueOf(gmtMins + "0");
		}
		
		/**
		 * This will produce a String in the format of GMT+5:30
		 */
		String gmtString = null;
		if (gmtMins == 0) {
			gmtString = GMT_STR + gmtAction + gmtHours + COLON_STR + gmtMins+ ZERO;
		} else {
			gmtString = GMT_STR + gmtAction + gmtHours + COLON_STR + gmtMins;
		}

		/**
		 * This calendar object will give you the local time of the specific country
		 * based on the gmt offset hours and the action passed. 
		 */
		return Calendar.getInstance(TimeZone.getTimeZone(TimeZone.getTimeZone(
				gmtString.trim()).getID()));

	}

Thats all you need. The returned calendar will have the local time of that specific country depending on the GMT minutes and action you passed. Note that i have given the GMT in minutes to ease the calculation. Normally you will get the GMT in hours so you will need to convert that to minutes.

Ofcourse when daylight savings come into play you will need to change this accordingly. For our application this was not needed so we didnt do that change. To handle daylight savings we will have to keep the day light saving changes somewhere and deduct or add appropriately to the base GMT.

If you guys know anyway of doing this in a much simpler way or you have any suggestions for improvements pls do leave by a comment which is as always much appreciated.

Cheers Guys!!!!

From http://dinukaroshan.blogspot.com/2011/06/local-time-of-any-country-based-on-gmt.html

Published at DZone with permission of Dinuka Arseculeratne, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Tags:

Comments

Jose Smith replied on Tue, 2011/06/21 - 12:24am

This seems strange to me. Why not map the countries directly to timezone identifiers in the table?

darryl west replied on Tue, 2011/06/21 - 8:45am

bad on lots of levels. statics methods; adding strings that should be "built"; ignoring well thought out libraries like Joda and JSR-310. this is a poor example...

Dinuka Arseculeratne replied on Tue, 2011/06/21 - 10:29pm in response to: Jose Smith

Hi Jonathan,

 

First of all thank you for leaving by a comment. Can you please let me know what you mean by having timezone identifiers in the table? Myself and everyone reading this would benefit from it. 

 

Regards,

Dinuka

Dinuka Arseculeratne replied on Tue, 2011/06/21 - 10:34pm in response to: darryl west

Hi Darryl,

 

Few questions. Why is having a static method bad here? We are not storing any instance specific details here isnt it. 

Also is there anyway to build the spefic GMT string rather than string manipulation? I did check out Joda but did not want to add another dependecy to the current application as it is a matured product.  But i get what you mean, it is a very well written library.

 

Thx for sharing the JSR-310. I was not aware of it.

 

Cheers

Jose Smith replied on Tue, 2011/06/21 - 11:37pm in response to: Dinuka Arseculeratne

Sure. You stated originally that you have a country table that contains countries and their offsets from GMT.

So for example: "USA", -420

First, I don't really understand this because a country like the USA spans multiple timezones. But if you really want to do this, why not just store the TimeZone identifier directly in the database?

So instead: "USA", "America/Los_Angeles"

Then you don't have to worry about possibly bugs in your method. Multiple timezone ID's might have the same offset. What's the problem you're trying to solve? I'm not quite sure. If you want the current local time in any country it's simply "Date localDateTime = new Date()" regardless of time zone. If you need to create a specific timestamp, like 2:35AM in Shanghai then yeah you'll need to get a calendar instance with the Shanghai timezone and call Calendar methods to configure the date/time. But it seems better to simply store this timezone ID directly in the database.

Dinuka Arseculeratne replied on Wed, 2011/06/22 - 2:46am in response to: Jose Smith

Hi Jonathan,

 

Thx again for the promt response. +1 on your idea of storing the timezone ID it self in the database. As our current product had the GMT offset minutes and GMT offset action already within a database i wanted to make this enhancement with minimal changes that is why i used it as it is. 

 

The reason i had to deal with time zones is because the application is running at our local servers so any time we take from new Date() will be the local time of my country. Our application is accessed from various user accounts created for various users in various locations, so in order to store the time stamp that they did some transaction in their own time zone i used this method.

 

Thank you for your comprehensive response.

 

Cheers

Jose Smith replied on Wed, 2011/06/22 - 7:33am in response to: Dinuka Arseculeratne

"new Date()" represents NOW in all countries. For example:
Date d = new Date();
showLocalTime(d, "America/New_York");
showLocalTime(d, "Europe/Athens");

public void showLocalTime(Date d, String timeZoneId) {
   TimeZone tz = TimeZone.getTimeZone(timeZoneId);
   SimpleDateFormat format = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z");
   format.setTimeZone(tz);
   System.out.println(format.format(d));
}

Dinuka Arseculeratne replied on Thu, 2011/06/23 - 6:36am in response to: Jose Smith

Hi Jonathan,

 

I think you misunderstood my previous statement. If my servers are set to my local time zone then calling new Date() represents the current time in that time zone which will be stored in the database. Ofcourse timeZoneId will work but again my point i made was that i wanted to make this change with the data we had which was the GMT action + GMT minutes that was already stored in our country table. 

 

The solution provided by you is the correct way of doing it, again what i wanted was to come up with a solution with the data in hand.

 

Regards,

Dinuka

Loren Kratzke replied on Thu, 2011/06/23 - 9:50pm in response to: darryl west

Contrary to popular belief, static methods are not evil if you do not care where they are being called from, and as long as they are stateless as this one is. Regarding String concatenation, it happens in one (or the other) statement so will result in exactly one StringBuilder being constructed behind the scenes - no different than creating one yourself and calling ".append()" except his example is more readable. But I respect your attention to these details. Good points.

One fact that many Java programmers do not fully grasp is that System.currentTimeMillis() returns the same value in London as it does in New York. The rest of Date handling is all offsets from this value based upon desired time zone.

 

Sirikant Noori replied on Sun, 2012/01/15 - 1:05pm

First, consider simply storing the TimeZone id for the country rather than the offset. In the simple case it saves you the math and string manipulation. More importantly it gives you a lot more flexibility.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.