Time Zone for iterator and resulting advanceTo date

174 views
Skip to first unread message

Isaac

unread,
Mar 21, 2012, 12:57:57 PM3/21/12
to google-rfc-2445
I was initially using DateIterator with a passed in time zone (often
not UTC) along with a start date and a rule. It appears that it is
applying the rule correctly and advancing to the expected next
occurrence. However, the date returned seems to be off by the UTC
offset. Am I doing something wrong or is this a bug?

// startCal - 21:00 on the 5th day of March local time.
Calendar startCal = Calendar.getInstance(); //Local time zone is
America/Chicago
startCal.set(2012, Calendar.MARCH, 5, 21, 0, 0);
startCal.clear(Calendar.MILLISECOND);

String recurrenceRule = "RRULE:FREQ=MONTHLY;INTERVAL=1;BYMONTHDAY=9";

dateIterator = DateIteratorFactory.createDateIterator(recurrenceRule,
startCal.getTime(), startCal.getTimeZone(), true);

// Set the seed calendar to be 7 days after the start date (March
12th)
Calendar seedCal = (Calendar) startCal.clone();
seedCal.add(Calendar.DAY_OF_MONTH, 7);

Date nextDate = null;
dateIterator.advanceTo(seedCal.getTime());
if (dateIterator.hasNext())
{
nextDate = dateIterator.next();
}

(NOTE: not accounting for daylight saving time in this example, I know
it would actually be an hour different than this. In fact, I'm not
positive DST is being handled correctly, but I'm less worried about
that at the moment.)
I would expect nextDate to be April 10th at 3:00:00 UTC since that is
April 9th at 21:00:00 local time. However, it is actually April 10th
at 9:00:00 UTC



So I have switched to using a RecurrenceIterator and while it requires
a little more code to convert to the DateTimeValue objects, it returns
the correct date. However, the date returned seems to always be UTC
even though the time zone of the start date and the time zone passed
in during creation of the iterator is not UTC. It's simple enough to
handle, but just wondering if it is intended. Or, again, am I doing
something wrong?

// startCal - 21:00 on the 5th day of March local time.
Calendar startCal = Calendar.getInstance(); //Local time zone is
America/Chicago
startCal.set(2012, Calendar.MARCH, 5, 21, 0, 0);
startCal.clear(Calendar.MILLISECOND);

String recurrenceRule = "RRULE:FREQ=MONTHLY;INTERVAL=1;BYMONTHDAY=9";

DateTimeValueImpl startDateTime = new
DateTimeValueImpl(startCal.get(Calendar.YEAR),
startCal.get(Calendar.MONTH) + 1, startCal.get(Calendar.DAY_OF_MONTH),
startCal.get(Calendar.HOUR_OF_DAY), 0, 0);

RecurrenceIterator recurrenceIterator =
RecurrenceIteratorFactory.createRecurrenceIterator(recurrenceRule,
startDateTime, timeZone, false);

// Set the seed calendar to be 7 days after the start date (March
12th)
Calendar seedCal = (Calendar) startCal.clone();
seedCal.add(Calendar.DAY_OF_MONTH, 7);

DateTimeValueImpl seedDateTime = new
DateTimeValueImpl(seedCal.get(Calendar.YEAR),
seedCal.get(Calendar.MONTH) + 1, seedCal.get(Calendar.DAY_OF_MONTH),
seedCal.get(Calendar.HOUR_OF_DAY), seedCal.get(Calendar.MINUTE),
seedCal.get(Calendar.SECOND));

recurrenceIterator.advanceTo(seedDateTime);
if (recurrenceIterator.hasNext())
{
DateTimeValue nextDateVal = (DateTimeValue)
recurrenceIterator.next();

nextCal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
nextCal.clear();
nextCal.set(nextDateVal.year(), nextDateVal.month() - 1,
nextDateVal.day(), nextDateVal.hour(), nextDateVal.minute(),
nextDateVal.second());
nextDate = nextCal.getTime();
}

nextDate is exactly what I expect. And it definitely accounts for
UTC. I am curious though, why the nextCal needs to be in UTC when I
would expect the value returned in nextDateVal to match the time zone
of the iterator.

Thanks,
Isaac

Isaac

unread,
Mar 28, 2012, 10:46:19 AM3/28/12
to google-rfc-2445
I've also found that the seed date needs to be supplied in UTC. It
appears that while I provide the time zone to the recurrence iterator
and it is used correctly when iterating, the dates are all still
handled in UTC. So if I pass in a seed date that is not in UTC, it
may incorrectly be considered before or after the start date (or I
suppose the date of any specific occurrence).

I realize that my usage of "seed date" may not be standard. I refer
to the date I pass in to advanceTo() as you can see in the code in the
previous post.

I believe this is all part of one question for the
RecurrenceIterator: Why must I supply a UTC seed date and why do I
get a UTC result when I supply a different time zone to the iterator?
I think it works great once I figured this out, but it seems a little
strange. It's possibly a part of working with the DateTimeValue
objects, but as I stated in the previous post, the DateIterator
doesn't seem to work with non-UTC time zones. I'd prefer to use that
iterator anyway if someone can point out what I was doing wrong with
it. If not, I'll make do.

Thanks,
Isaac

Isaac

unread,
Mar 29, 2012, 11:58:02 AM3/29/12
to google-rfc-2445
Sorry, one more follow up. I just saw the javadoc for
RecurrenceIterator does specifically say that the date passed into
advanceTo needs to be in UTC. And it says that the resulting date is
also in UTC. So while I may find it strange, I suppose it's
understandable and it's definitely documented, so you can disregard
that.

I still don't know what I was doing wrong with the DateIterator. If
anyone can point out my flaw, I'd appreciate it.

Mike Samuel

unread,
Mar 30, 2012, 3:23:26 PM3/30/12
to google-...@googlegroups.com
2012/3/29 Isaac <singer...@gmail.com>:

> Sorry, one more follow up. I just saw the javadoc for
> RecurrenceIterator does specifically say that the date passed into
> advanceTo needs to be in UTC.  And it says that the resulting date is
> also in UTC.  So while I may find it strange, I suppose it's
> understandable and it's definitely documented, so you can disregard
> that.
>
> I still don't know what I was doing wrong with the DateIterator.  If
> anyone can point out my flaw, I'd appreciate it.

Sorry to take so long to respond. I'm having a bit of trouble
understanding your problem. Would you mind restating your problem now
that you understand the UTC convention?


>> > I am curious though, why the nextCal needs to be in UTC when I
>> > would expect the value returned in nextDateVal to match the time zone
>> > of the iterator.

Dates that are not in UTC can be ambiguous.
If clocks in a particular timezone are set back 1 hour at
2000-Jan-1,01:00:00 then knowing that the clock reads
2000-Jan-1,00:30:00 does not let you identify a single instant in
time. That time might refer to half an hour before the clock was set
back, or half an hour after.

It might be the case that a recurrence rule generates
2000-Jan-1,00:30:00 and then generates 2000-Jan-1,00:25:00 and those
dates are in-order according to one interpretation but not another.

So to avoid loss of precision and to avoid subtle bugs in clients that
assume that the returned Dates are monotonic (like the instants in
time to which they refer) the API takes the unambiguous UTC as input
and produces the same output.

Isaac Singer

unread,
Apr 24, 2012, 1:20:55 PM4/24/12
to google-...@googlegroups.com
Thanks for the explanation about using UTC.  I see what you mean about time zones varying quite a bit especially when dealing with DST clock changing.

The problem I'm seeing with DateIterator is that the Date returned is incorrect.  It's suspicious to me that it's off by the same amount as the UTC offset, almost as though it was converted twice.  My example in the first post was:
  • Set the start date/time to 3/5/2012 21:00:00 in local time -- 3/6/2012 3:00:00 in UTC.
  • Set the rule to monthly on the 9th day of the month.  
  • Create the DateIterator with this start time, rule, and the local time zone.
  • AdvanceTo 3/12/2012.
  • next() returns 4/10/2012 9:00:00 UTC, but I would expect it to be 4/10/2012 3:00:00 UTC.  (Or at least close to that depending on DST which starts in between my start date and the next date).
I assume I'm doing something wrong, but I haven't found where.  Like I said, I'm able to use the RecurrenceIterator and DateTimeValue objects correctly, they are just a little more cumbersome to convert to and from instead of using the java date objects, but not a big deal.


--
You received this message because you are subscribed to the Google Groups "google-rfc-2445" group.
To post to this group, send email to google-...@googlegroups.com.
To unsubscribe from this group, send email to google-rfc-24...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-rfc-2445?hl=en.


Reply all
Reply to author
Forward
0 new messages