How to Handle Calendar Timezones Using Java

How to handle calendar TimeZones using Java?

Thank you all for responding. After a further investigation I got to the right answer. As mentioned by Skip Head, the TimeStamped I was getting from my application was being adjusted to the user's TimeZone. So if the User entered 6:12 PM (EST) I would get 2:12 PM (GMT). What I needed was a way to undo the conversion so that the time entered by the user is the time I sent to the WebServer request. Here's how I accomplished this:

// Get TimeZone of user
TimeZone currentTimeZone = sc_.getTimeZone();
Calendar currentDt = new GregorianCalendar(currentTimeZone, EN_US_LOCALE);
// Get the Offset from GMT taking DST into account
int gmtOffset = currentTimeZone.getOffset(
currentDt.get(Calendar.ERA),
currentDt.get(Calendar.YEAR),
currentDt.get(Calendar.MONTH),
currentDt.get(Calendar.DAY_OF_MONTH),
currentDt.get(Calendar.DAY_OF_WEEK),
currentDt.get(Calendar.MILLISECOND));
// convert to hours
gmtOffset = gmtOffset / (60*60*1000);
System.out.println("Current User's TimeZone: " + currentTimeZone.getID());
System.out.println("Current Offset from GMT (in hrs):" + gmtOffset);
// Get TS from User Input
Timestamp issuedDate = (Timestamp) getACPValue(inputs_, "issuedDate");
System.out.println("TS from ACP: " + issuedDate);
// Set TS into Calendar
Calendar issueDate = convertTimestampToJavaCalendar(issuedDate);
// Adjust for GMT (note the offset negation)
issueDate.add(Calendar.HOUR_OF_DAY, -gmtOffset);
System.out.println("Calendar Date converted from TS using GMT and US_EN Locale: "
+ DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT)
.format(issueDate.getTime()));

The code's output is: (User entered 5/1/2008 6:12PM (EST)

Current User's TimeZone: EST

Current Offset from GMT (in hrs):-4 (Normally -5, except is DST adjusted)

TS from ACP: 2008-05-01 14:12:00.0

Calendar Date converted from TS using GMT and US_EN Locale: 5/1/08 6:12 PM (GMT)

How to change TIMEZONE for a java.util.Calendar/Date

In Java, Dates are internally represented in UTC milliseconds since the epoch (so timezones are not taken into account, that's why you get the same results, as getTime() gives you the mentioned milliseconds).

In your solution:

Calendar cSchedStartCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
long gmtTime = cSchedStartCal.getTime().getTime();

long timezoneAlteredTime = gmtTime + TimeZone.getTimeZone("Asia/Calcutta").getRawOffset();
Calendar cSchedStartCal1 = Calendar.getInstance(TimeZone.getTimeZone("Asia/Calcutta"));
cSchedStartCal1.setTimeInMillis(timezoneAlteredTime);

you just add the offset from GMT to the specified timezone ("Asia/Calcutta" in your example) in milliseconds, so this should work fine.

Another possible solution would be to utilise the static fields of the Calendar class:

//instantiates a calendar using the current time in the specified timezone
Calendar cSchedStartCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
//change the timezone
cSchedStartCal.setTimeZone(TimeZone.getTimeZone("Asia/Calcutta"));
//get the current hour of the day in the new timezone
cSchedStartCal.get(Calendar.HOUR_OF_DAY);

Refer to stackoverflow.com/questions/7695859/ for a more in-depth explanation.

How to set time zone of a java.util.Date?

Use DateFormat. For example,

SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
isoFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = isoFormat.parse("2010-05-23T09:01:02");

java Calendar, Date, and Time management for a multi-timezone application

In general, scheduling future events is a complex subject. You have to make a distinction in the context of what is going to be scheduled:

  • Does the event occur at a specific universal instant in time? If so, you should record the event time in terms of UTC.

    For example, a task that runs every 24 hours would be scheduled by UTC time and not by the local time. It might start off at some local midnight, but as daylight saving time changes take effect it could be running at 23:00 or 01:00 by the local clock.

  • However, if the event is scheduled by human beings, it is likely to be in terms of a local time, so you should record it that way.

    For example, a meeting that occurs at 08:00 Eastern Time will always occur at that local time. In the winter, that would be 13:00 UTC, and in the summer it would be at 12:00 UTC.

    So in this context, you cannot record the scheduled start time in terms of UTC. This is a very common mistake, as there is a ton of advice on the Internet that says "always store using UTC", which would be wrong in this scenario.

    Instead, you should store two values - the local time such as 08:00 and its IANA time zone identifier, such as America/New_York. You may also need to store a recurrence pattern or specific date depending on how the event is scheduled.

  • Consider using Joda Time instead of Java's Calendar or Date classess. It will save you from many headaches. Make sure you read the Joda Time documentation and understand how it works.

    Joda Time has all of the functions you will need for converting between one time zone and another - which I believe was the primary concern of your question.

  • Be sure to have a procedure in place for updating the time zone data regularly. Updates are pushed out multiple times a year, as the governments of the world make changes to the legal definitions of their time zones. You cannot just deploy it once and forget about it.

  • Also be sure you understand that conversion from local time to a specific UTC moment is not a perfect function due to daylight saving time. If an event is scheduled during an invalid or ambiguous local time, you should have a strategy for detecting and dealing with that in your application. You might just apply some assumptions, or you might want to go out of your way to ask the user what to do.

    For example, if I schedule an event at 2:00 AM Eastern Time every day, then on March 10th 2013, that time does not exist. Should the event occur at 3:00 AM? Or should it not occur at all?

    Another example, if I schedule an event at 1:00 AM Eastern Time every day, then on November 3rd, 2013, that time occurs twice. Should the event happen at the first (daylight time) instance? Or at the second (standard time) instance? Or both? Should I assume one or the other, or should I ask the user which they mean?

    Only you can decide what to do, as it is your application. But ignoring the problem will likely lead to errors.

  • Once an event has passed, you can record it in UTC if you wish, or record it with the full local date time and offset. Either are acceptable. This works just fine for singular past events, just not for recurring future ones.

Calendar.getInstance(TimeZone.getTimeZone( UTC )) is not returning UTC time

The System.out.println(cal_Two.getTime()) invocation returns a Date from getTime(). It is the Date which is getting converted to a string for println, and that conversion will use the default IST timezone in your case.

You'll need to explicitly use DateFormat.setTimeZone() to print the Date in the desired timezone.

EDIT: Courtesy of @Laurynas, consider this:

TimeZone timeZone = TimeZone.getTimeZone("UTC");
Calendar calendar = Calendar.getInstance(timeZone);
SimpleDateFormat simpleDateFormat =
new SimpleDateFormat("EE MMM dd HH:mm:ss zzz yyyy", Locale.US);
simpleDateFormat.setTimeZone(timeZone);

System.out.println("Time zone: " + timeZone.getID());
System.out.println("default time zone: " + TimeZone.getDefault().getID());
System.out.println();

System.out.println("UTC: " + simpleDateFormat.format(calendar.getTime()));
System.out.println("Default: " + calendar.getTime());

Convert Date/Time for given Timezone - java

For me, the simplest way to do that is:

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

//Here you say to java the initial timezone. This is the secret
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
//Will print in UTC
System.out.println(sdf.format(calendar.getTime()));

//Here you set to your timezone
sdf.setTimeZone(TimeZone.getDefault());
//Will print on your default Timezone
System.out.println(sdf.format(calendar.getTime()));

How to get the current date and time of your timezone in Java?

Date is always UTC-based... or time-zone neutral, depending on how you want to view it. A Date only represents a point in time; it is independent of time zone, just a number of milliseconds since the Unix epoch. There's no notion of a "local instance of Date." Use Date in conjunction with Calendar and/or TimeZone.getDefault() to use a "local" time zone. Use TimeZone.getTimeZone("Europe/Madrid") to get the Madrid time zone.

... or use Joda Time, which tends to make the whole thing clearer, IMO. In Joda Time you'd use a DateTime value, which is an instant in time in a particular calendar system and time zone.

In Java 8 you'd use java.time.ZonedDateTime, which is the Java 8 equivalent of Joda Time's DateTime.

Java Calendar: getting time for the timezone

You're printing out the result of Date.toString(), which always uses the default time zone.

I suggest you use DateFormat instead, which is better suited for formatting dates. Date.toString is really only suitable for debugging - it provides no control over the format.

Alternatively, use Joda Time for all your date and time operations - it's a much better API to start with :)

Calendar Object Time Zone conversion

private Calendar getPSTTime(Calendar utcTime)
{
TimeZone americaPacific = TimeZone.getTimeZone("America/Los_Angeles");
Calendar pacificTime = Calendar.getInstance(americaPacific);
pacificTime.setTime(utcTime.getTime());
return pacificTime;
}

FYI: All of the available time zone String identifiers are returned by the method TimeZone.getAvailableIDs(). That's where I got "America/Los_Angeles" from.

How to create Calendar with specific TimeZone?

Just reverse the order of "specify date, specify time zone" to "specify time zone, specify date":

Calendar calendar = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
calendar.set(2014, 0, 1, 0, 0, 0);
calendar.set(Calendar.MILLISECOND, 0);

I'd also recommend avoiding the Calendar/Date API entirely - use java.time for Java 8, and Joda Time for older versions of Java.



Related Topics



Leave a reply



Submit