Reputation: 544
I have a timestamp that I am trying to put into a Date
object, however when I use Calendar, I am running into a strange problem. I seem to be able to unable to create a Date object with the values I want:
public static void main(String args[]){
Date today = new Date();
int hour = 4, min=0, sec=0, ms=64;
Calendar cal = GregorianCalendar.getInstance();
cal.clear();
cal.setTimeZone(TimeZone.getTimeZone("EDT"));
cal.setTime(today);
cal.set(Calendar.HOUR_OF_DAY,hour);
cal.set(Calendar.MINUTE,min);
cal.set(Calendar.SECOND,sec);
cal.set(Calendar.MILLISECOND,ms);
System.out.println("Time is: "+cal.getTime());
}
This produces:
Time is: Mon Jan 13 23:00:00 EST 2014
which is not the result I am looking for.
However, if I comment out the 'setTimeZone' method call, I get the following result:
Time is: Tue Jan 14 04:00:00 EST 2014
This is the result that I am looking for but I am concerned that if I am running on a machine that is not running in the same time zone, I will not get consistent behavior.
Upvotes: 1
Views: 6413
Reputation: 338574
For comparison, here is that same kind of code but using Joda-Time 2.3.
Avoid the java.util.Date & .Calendar classes.
Never use three-letter codes for time zones. They are neither standardized nor unique. Instead use proper time zone names. In this case, use "America/New_York" or "America/Montreal".
// Use time zone names, such as from this slightly outdated list: http://joda-time.sourceforge.net/timezones.html
DateTimeZone timeZone = DateTimeZone.forID( "America/New_York" );
// Input.
int hour = 4, min = 0, sec = 0, ms = 64;
// Start with now, then adjust the time of day.
DateTime now = new DateTime( timeZone );
DateTime dateTime = now.withHourOfDay( hour ).withMinuteOfHour( min ).withSecondOfMinute( sec ).withMillisOfSecond( ms );
// If needed, translate to a java.util.Date for use with other classes.
java.util.Date date = dateTime.toDate();
Dump to console…
System.out.println( "now: " + now );
System.out.println( "dateTime: " + dateTime );
System.out.println( "date: " + date );
When run…
now: 2014-01-20T21:04:51.237-05:00
dateTime: 2014-01-20T04:00:00.064-05:00
date: Mon Jan 20 01:00:00 PST 2014
Upvotes: 0
Reputation: 544
The problem here is that Java does not know of the timezone "EDT" (Eastern Daylight Time). As a result, Calendar seems to be setting the timezone to GMT.
The timezone needed here is "America/New_York" or "EST5EDT". When either of these values are used, the correct result is produced.
The list of valid Time Zones can be obtained by calling TimeZone.getAvailableIDs()
It is unfortunate that no warnings are produced when the requested Time Zone is not found.
Upvotes: 1
Reputation: 23
Java Date objects represent the number of milliseconds seconds since January 1, 1970, 00:00:00 GMT due to the fact that the other methods are deprecated. The two ways to "view" a Date object directly are "getTime()" and "toString()" (using "dow mon dd hh:mm:ss zzz yyyy"). Therefore, you are formatting the GMT value to your local timezone.
When working with dates, it is best to think of them as GMT values, and then as a "formatting" exercise when viewing the date.
Upvotes: 0
Reputation: 206816
Calendar.getTime()
returns a java.util.Date
object. Date
objects do not know anything about timezones. The Date
object that Calendar.getTime()
returns does not know to what timezone the Calendar
that it came from is set.
When you print a Date
object (for example, by implicitly calling toString()
object, as you are doing) it is formatted in the default time zone of the machine you are running it on.
If you want to print a Date
in a specific timezone, use a SimpleDateFormat
, and set the desired timezone on the SimpleDateFormat
object. For example:
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
df.setTimeZone(TimeZone.getTimeZone("EDT"));
// Will display the date that the calendar is set to in the EDT timezone
System.out.println(df.format(cal.getTime()));
Upvotes: 0
Reputation: 8617
If you can do away with java.util.Date
, you can use joda time API to conveniently set these values as desired:
For your query, you can set your already created Calendar instance as a constructor parameter to DateTime
.
DateTime dt = new DateTime(cal);
System.out.println(dt.toDateTimeISO());
Output:
2014-01-14T04:00:00.064-05:00
Upvotes: 0
Reputation: 7717
This is the result that I am looking for but I am concerned that if I am running on a machine that is not running in the same time zone
it is the problem. The internal representation should be ok, but it prints on local timezone: representation differs from real content.
use SimpleDateFormat
http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html and set TimeZone to see the date on the Zone desired.
Upvotes: 2