Subject: Re: Recap: Does 1 day == 24 hours?

From: [email-masked]
Date: Mon, 23 Apr 2001 19:56:00 -0400

Eric scribbed:
> To review, the problem is that RFC2445 does not
> specify what 1D really means when used in a DURATION. During the
> discussion, there were three camps:

Ive been too busy w/paying work to wade in on this until now but Ill jump 
right in and try to catch up...

>   1) 1D means 24H. In this case, 1D is a synonym for 24H. [Snip]
> 
>   2) 1D means "the remainder of today".[Snip]
> 
>   3) 1D means "the same time tomorrow" [Snip]
> 
> Now, honestly, none of these options are very good. 

I find one option right on and the other 2 off base by variying amounts 
(why else would I be responding?)  Before progressing w/Erics analysis Id 
like to point out something from the ABNF (and I think that Patrick raised 
it at one point).  From 4.3.6's ABNF:

     dur-date   = dur-day [dur-time]
     dur-time   = "T" (dur-hour / dur-minute / dur-second)
[Snip]
     dur-day    = 1*DIGIT "D"

You will note that dur-day is NOT a time duration; its an implicit date 
unit and as such is not a time unit. There should be no consideration of 
time units when dealing with a date unit.  Sure, you can do some mappings 
that work for nearly all cases (ie: 1 day = 24 hours except for possibly 2 
dates a year which is somewhere around ~0.75% of the calendar days in a 
Gregorian calendar year; not a high percentage occurance case IMHO) but as 
already noted this could confuse some people.

> (1) implies that the end time of a 1D event can move around depending on
> daylight savings time shifts, and it makes the W and D specifiers
> redundant, since they can always be expressed in H, M or S.

This case would be an acceptable idea from a coding model but its possible 
that it could confuse human users, depending on how the CUAs display the 
information.  Its also ambiguous enough that some confusion may exist 
(especially if the receiving CUA does not have the TZ definition of the 
sending CUA and they do not share TZ shift rules).

> (2) is logical, self consistent and non-redundant. It is the RFC
> authors original intent, but I'd suspect that end users will find it
> very strange. Are there use cases that require this behavior?

It may have been Franks intent but I do not recall it being expressed that 
way.  I certainly would have argued against it had he done so in any 
earlier drafts.

Perhaps its splitting hairs (ugh) between saying July 4th is 1 Day long 
(starting at midnight local time and ending at 23:59:59 local time) and my 
"day long" Scavenger Hunt that starts at July 4th @ 9AM (EST) and ends "1 
day later" but I would claim its not.  The former case has implicit time 
values involved (ie: DTSTART;VALUE=DATE:07042001) and the latter case has 
explicit time values.  As noted above, day is NOT time unit based as such 
time units should not be used when 'adjusting' or calculating a date based 
shift.

One cannot reliably use a implicit time case to argue the explicit time 
case; thats like using apples and oranges.  (Well, actually one could 
try...)

I would suggest that using DURATION:1D is an improper use of it if the 
user wanted to indicate "This event ends just before midnight no matter 
the start time".  Thats more properly specified by a 
DTEND;VALUE=DATE:07042001 where the time is implicity assumed to be 
23:59:59.

> (3) may be more expected from the end-users perspective, but is
> complex to implement, since you have to look for timezone shifts every
> time you convert a DURATION of 1D into an end time. 

Not sure I follow that logic.  Simply put for (3), all I have to do is 
(pardon this pseudo script):

        Dim Duration As New DateTime( DTStart.Value )
        Call Duration.AdjustDay (+1) 

This simply moves the 'date' to the 'next day'.  The time value of the 
DTSTART, given to the DURATION value, is unchanged.  This is not rocket 
science nor complex to implement.  It may be complex if your engine 
converts all date values to time values and you do not properly write your 
AdjustDay() to scale the adjust value to the same base units (ie: seconds 
since 01-Jan-2000, etc).  Otherwise its trivial to shift dates.

There is no end time to convert, you inherit the one from the DTSTART.  If 
the DTSTART is of VALUE=DATE, the value is 00:00:00 and the calculated end 
time would use that.

> Personally, I'd reject (1). It is the easiest to understand and is
> logical, but it doesn't add anything to the behavior of DURATION.

A KISS mantra could be that this is useful for the vast majority of cases 
(unless you really only work around a TZ shift and spend the entire rest 
of the year doing nothing) and as such could be used if we codified this 
behaviour.  However I agree that its not the one Id describe as "the 
best".

> I prefer (2), but could live with (3). Both add useful behavior to
> DURATION that cannot be accomplished easily with H,M and S. (3) is nice
> because I think it best matches users expectations. I would naturally
> expect that a 1D event that starts today at 10:00 will end tomorrow at
> 10:00, and (3) ensures this behavior.

Thats partly why I like (3).  The other part is that its not rocket 
science to code it.  I very strongly dislike (2) since it involves unit 
conversion that is not safe or intuitive.

> However (2) makes more sense when the value of DTSTART is DATE. In fact,
> it is probably sensible to restrict DURATION to only using W and D when
> DTSTART:VALUE=DATE. This would eliminate any questions about what it 
means
> to at 2H to a DATE. This points to strengthing the concept of time scale
> vs date scale in RFC2445, and (2) would be an important part of that
> concept. 

I can see uses where I may want the implicit start time (which wont vary 
even w/a TZ shift) but have a duration of 1DT8H (which may end at 7AM, 
8AM, or 9AM depending on if a TZ shift is involved).  However these cases 
are not likely to be the norm for our C&S usage model (lets try to apply 
the 90/10 or 99/1 rule here shall we???).

I would suggest that the restrictions on DURATION 'scale' be:

Duration MUST be of VALUE=DATE if DTSTART is of VALUE=DATE.  This does 
preclude a DURATION:1DT8H case but its an acceptable limitation to me.
Duration MAY be of VALUE=DATE or VALUE=DATE-TIME if DTSTART is of 
VALUE=DATE-TIME
Date units are NOT convertable to Time units.  The time value for the 
calculated or effective DTEND is inherited from the DTSTART when no 
dur-time values are specified
When time units are specified (in addition to date units) then they are 
based on the time inherited from the DTSTART property.

I also think that this would allow us to at some point reintroduce week 
and month duration in a consistant manner (ie: P1W = "Add 1 to the week 
value of the start date" with 1 week = 7 days).  We may have to do some 
tightening of what it means to have a duration of 1 month when the 
following month has fewer days than the current one (ie: DTSTART:01302001 
and DURATION:P1M = what date?) but thats over the horizon now.

I think it bears mentioning that a duration value of P1W suffers from the 
same 'vagueness' that P1D does (just think about it).  May as well clean 
it all up at once...

> (2) is easy to implement, adds additinoal functionality, and although it
> has unusual behavior for DTSTART;VALUE-DATE-TIME, it is a perfect match
> for DTSTART;VALUE=DATE.

Its behaviour is non-intuitive and can more properly be modeled by a 
DTEND;VALUE=DATE.   I see no problem w/(3) matching DTSTART;VALUE=DATE at 
all since times units are not involved.

> Which option do you prefer?

In case its not clear by now: (3) is by far my favorite option with (1) a 
somewhat distant second and (3) absolutely dead last.

Bruce
===========================================================================
Bruce Kahn                                INet: [email-masked]
Iris Associates                          Phone: 978.392.5335
Westford, MA, USA 01886                    FAX: and nothing but the FAX...
Standard disclaimers apply, even where prohibited by law...

---

From: John Stracke <[email-masked]>
Date: Tue, 24 Apr 2001 10:04:31 -0400

[email-masked] wrote:

> > (1)

[...]

> Its also ambiguous enough that some confusion may exist
> (especially if the receiving CUA does not have the TZ
> definition of the sending CUA and they do not share TZ shift
> rules).

This is a strawman, since every VEVENT must contain a VTIMEZONE
for every TZ it uses

--
/==============================================================\
|John Stracke    | http://www.ecal.com |My opinions are my own.|
|Chief Scientist |=============================================|
|eCal Corp.      |We must be devious, cunning, inventive... too|
[email-masked]|bad we're us.                                |
\==============================================================/

---

From: Eric Busboom <[email-masked]>
Date: Wed, 25 Apr 2001 12:54:28 -0700 (PDT)

> preclude a DURATION:1DT8H case but its an acceptable limitation to me.

It's not really a limitation, since if your times are in the date scale
then the end time should be disregarded -- you couldn't do anything with
the 8H anyway. 

And, in this case, 1D, really means "until the end of the day specified in
DTSTART" -- essentiall my option (2).

> Duration MAY be of VALUE=DATE or VALUE=DATE-TIME if DTSTART is of 

And, in this case, we are really in the time scale, so 1D means "same time
tomorrow"

> dur-time values are specified

OK.

> based on the time inherited from the DTSTART property.

As usual. 

( BTW, RFC2445 does not permit a VALUE parameter for DURATION, so I will
suppose that VALUE=DATE implies that the DURATION value has no H, M or S ) 

So, perhaps what we really have is:

	 option (2) -- 1D means "until the end of today" --  when the
 	 DURATION is in the date scale 

	 option (3) -- 1D means "same time tomorrow" when the DURATION is
	 in the time scale

with the scale coming from the value type of DTSTART. 

Here is some proposed text, to be added to the section for the DURATION
property:

--------------------------------------------------------------------------

For the purpose of calculating an end time based on a start time and a
duration. The dur-week ("W") and dur-day ("D") parts of DURATION can
vary their meaning depending on wether the DTSTART is a value of DATE
or DATE-TIME.

If the DTSTART value time is a DATE-TIME, a day (dur-day) MUST be
interpreted as the period spanning between the same times on sucessive
days, not as a period of 24 hours. So, An event of DURATION:P1D that
starts at 10:00 will end the following day at 10:00, regardless of any
intervening shifts between Standard Time and Daylight Savings
Time.
 
Similarly, if the value of DTSTART is DATE-TIME, a week ( dur-week)
MUST be interpreted as a period of seven days (DURATION:7D) , not as
168 hours. 

If the value of DTSTART is DATE, then dur-week and dur-day are interpreted
on an integer day scale. Because DATE values time work off of the
start and end of days, there is no consideration for daylight savings time
shifts. Thus, these two specifications for a time period are always
identical:

	DTSTART;VALUE=DATE:19971103
	DURATION:P1D
and:
	DTSTART;VALUE=DATE:19971103
	DTEND:19971104

If the DTSTART of an event has a value of DATE, then the DURATION MUST 
NOT include dur-hour, dur-minute or dur-second parts. 

---------------------------------------------------------------------------

eric.