opike opike -4 years ago 113
Java Question

Question about java.util.Calendar

I'm trying to understand the behavior with the following code.
My local time zone is UTC -7 (Arizona).

Calendar cal = Calendar.getInstance();
cal.set(Calendar.MINUTE,40);
cal.set(Calendar.AM_PM,Calendar.PM);
System.out.println("1 UTC -4 Hour:" + cal.get(Calendar.HOUR_OF_DAY));
System.out.println("1 UTC -4 Day:" + cal.get(Calendar.DAY_OF_MONTH));
System.out.println("1 UTC -7 Time Stamp:" + cal.getTime().toString());
cal.set(Calendar.HOUR,12);
System.out.println("2 UTC -4 Hour:" + cal.get(Calendar.HOUR_OF_DAY));
System.out.println("2 UTC -4 Day:" + cal.get(Calendar.DAY_OF_MONTH));
System.out.println("2 UTC -7 Time Stamp:" + cal.getTime().toString());
cal.setTimeZone(TimeZone.getTimeZone("America/New_York")); //set time zone to UTC -4
System.out.println("3 UTC -4 Hour:" + cal.get(Calendar.HOUR_OF_DAY));
System.out.println("3 UTC -4 Day:" + cal.get(Calendar.DAY_OF_MONTH));
System.out.println("3 UTC -7 Time Stamp:" + cal.getTime().toString());
cal.set(Calendar.HOUR,12);
System.out.println("4 UTC -4 Hour:" + cal.get(Calendar.HOUR_OF_DAY));
System.out.println("4 UTC -4 Day:" + cal.get(Calendar.DAY_OF_MONTH));
System.out.println("4 UTC -7 Time Stamp:" + cal.getTime().toString());


It generates this output:


1 UTC -4 Hour:12

1 UTC -4 Day:27

1 UTC -7 Time Stamp:Tue Sep 27 12:40:37 MST 2011

2 UTC -4 Hour:0

2 UTC -4 Day:28

2 UTC -7 Time Stamp:Wed Sep 28 00:40:37 MST 2011

3 UTC -4 Hour:3

3 UTC -4 Day:28

3 UTC -7 Time Stamp:Wed Sep 28 00:40:37 MST 2011

4 UTC -4 Hour:12

4 UTC -4 Day:28

4 UTC -7 Time Stamp:Wed Sep 28 09:40:37 MST 2011


What I don't understand is why the first cal.set(Calendar.HOUR,12) causes the date to flip to the next day. It makes sense that using add() on one value would cause other values to be adjusted, but it doesn't make sense for set() to do that as well.

Is there some way to do an absolute set() where all other values are preserved?

Answer Source

You're setting "HOUR" rather than "HOUR_OF_DAY". It's therefore setting it to be "12 hours after the start of the afternoon" - i.e. midnight at the end of that day, so the start of the next. Think of it as saying, "I'm meant to be PM, so setting the hour is midday + hours * 12"

Personally I think that's still a bit odd behaviour, but I'd stick to using HOUR_OF_DAY instead... or preferrably, using Joda Time in the first place.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download