pike.git / lib / modules / Calendar.pmod / TimeRanges.pmod

version» Context lines:

pike.git/lib/modules/Calendar.pmod/TimeRanges.pmod:1:   //! module Calendar + //! + //! submodule TimeRanges    - // $Id: TimeRanges.pmod,v 1.13 2001/01/10 23:44:13 mirar Exp $ -  +    #pike __REAL_VERSION__      #define zero int(0..0)    - import "."; -  +    program SuperTimeRange=cSuperTimeRange;      string calendar_name() { return "TimeRanges"; }    - object calendar_object=this_object(); + object calendar_object=this;    - string _sprintf(int t) { return (t=='O')?calendar_name():0; } + protected string _sprintf(int t) { return t=='O' && calendar_name(); }    - Ruleset default_rules= -  master()->resolv("Calendar")["default_rules"]; + Calendar.Ruleset default_rules=Calendar.default_rules;      //------------------------------------------------------------------------   //! class TimeRange - //! This is the base class for any time measurement - //! and calendrar information. It defines all the - //! things you can do with a time range, any time - //! period. + //! This is the base class (usually implemented by e.g. Calendar + //! subclasses like Calendar.Second) for any time measurement and + //! calendrar information. It defines all the things you can do + //! with a time range or any time period.   //!   //! A TimeRange doubles as both a fixed period in   //! time, and an amount of time. For instance,   //! a week plus a day moves the week-period one day   //! ahead (unaligning it with the week period,   //! and thereby reducing it to just 7 days),   //! no matter when in time the actual day were.   //!   //------------------------------------------------------------------------      class TimeRange   {    constant is_timerange=1;    -  Ruleset rules; +  Calendar.Ruleset rules;      //! method void create("unix",int unixtime)   //! method void create("unix",int unixtime,int seconds_len)   //! Create the timerange from unix time (as given by   //! <tt>time(2)</tt>), with eventually the size of   //! the time range in the same unit, seconds.   //!   //! method void create("julian",int|float julian_day)   //! Create the timerange from a julian day, the   //! standardized method of counting days. If
pike.git/lib/modules/Calendar.pmod/TimeRanges.pmod:61:   //! transferred to the new object, so this method   //! can't be used to convert between timezones   //! or languges - use <ref>set_timezone</ref>,   //! <ref>set_language</ref> or <ref>set_ruleset</ref>   //! to achieve this.   //!   //! note:   //! The size of the new object may be inexact;   //! a Month object can't comprehend seconds, for instance.    -  static void create_unixtime(int unixtime,int len); -  static void create_unixtime_default(int unixtime); -  static void create_julian_day(int jd); +  protected void create_unixtime(int unixtime,int len); +  protected void create_unixtime_default(int unixtime); +  protected void create_julian_day(int jd);    -  void create(mixed ...args) +  protected void create(mixed ...args)    {    if (sizeof(args)) switch (args[0])    {    case "unix":    if (sizeof(args)==2)    create_unixtime_default(args[1]);    else if (sizeof(args)>2)    create_unixtime(@args[1..]);    else break;    return;
pike.git/lib/modules/Calendar.pmod/TimeRanges.pmod:115:    default:    if (objectp(args[0]) && args[0]->is_timerange)    {    convert_from([object(TimeRange)]args[0]);    return;    }    break;    }       error("%O.%O: Illegal parameters %O,%O,%O...\n", -  function_object(object_program(this_object())), -  object_program(this_object()), -  @args,0,0,0); +  function_object(this_program), +  this_program,@args,0,0,0);    }    -  static void convert_from(TimeRange other) +  protected void convert_from(TimeRange other)    {   // inheriting class must take care of size -  if (other->julian_day) -  { -  int|float jd=other->julian_day(); -  if (floatp(jd) && other->unix_time) -  create("unix_r",other->unix_time(),other->ruleset()); -  else -  create("julian_r",jd,other->ruleset()); -  } -  else if (other->unix_time) -  create("unix_r",other->unix_time(),other->ruleset()); -  else +  if (other->unix_time) { +  rules = other->ruleset(); +  create_unixtime_default(other->unix_time()); +  } else if (other->julian_day) { +  rules = other->ruleset(); +  create_julian_day(other->julian_day()); +  } else    error("Can't convert %O->%s.%O\n",other, -  calendar_name(), -  object_program(this_object())); +  calendar_name(), this_program);    }      //! method TimeRange set_size(TimeRange size)   //! method TimeRange set_size(int n,TimeRange size)   //! Gives back a new (or the same, if the size matches)   //! timerange with the new size.   //! If <i>n</i> are given, the resulting size   //! will be <i>n</i> amounts of the given size.   //! note:   //! A negative size is not permitted; a zero one are.      // virtual -  static TimeRange _set_size(int n,TimeRange x); +  protected TimeRange _set_size(int n,TimeRange x);       TimeRange set_size(function|TimeRange|int(0..0x7fffffff) a,    void|function|TimeRange b)    {    function|object(TimeRange) x;    int(0..0x7fffffff) n;    if (!b)    if (intp(a)) -  x=[function|object(TimeRange)]this_object(), -  n=[int(0..0x7fffffff)]a; +  x=this,n=[int(0..0x7fffffff)]a;    else    x=a,n=1;    else    x=b,n=a;    if (functionp(x)) x=promote_program(x);    if (n<0)    error("Negative size (%d)\n",n);    return _set_size(n,[object(TimeRange)]x);    }   
pike.git/lib/modules/Calendar.pmod/TimeRanges.pmod:194:   //! TimeRange orig_day=month()->day(5);   //! for (int i=0; i&lt;10; i++)   //! {   //! month++;   //! TimeRange day=month->place(orig_day);   //! <i>...use day...</i>   //! }   //! </pre>      // virtual -  static this_program _add(int n,this_program step); +  protected this_program _add(int n,this_program step);       this_program add(function|this_program|int a,    void|function|this_program b)    {    function|object(this_program) x;    int n;    if (!b)    if (intp(a)) -  x=[function|object(this_program)]this_object(), -  n=[int]a; +  x=this,n=[int]a;    else    x=a,n=1;    else    x=b,n=a;    if (functionp(x)) x=promote_program(x);    return _add(n,[object(this_program)]x);    }      //! method TimeRange place(TimeRange this)   //! method TimeRange place(TimeRange this,int(0..1) force)
pike.git/lib/modules/Calendar.pmod/TimeRanges.pmod:263:   //! </pre>   //!   //! note:   //! a-b does not give the distance between the start of a and b.   //! Use the <ref>distance</ref>() function to calculate that.   //!   //! The integer used to `+, `- and add are the <i>number</i>   //! of steps the motion will be. It does <i>never</i> represent   //! any <i>fixed</i> amount of time, like seconds or days.    -  TimeRange `+(program|this_program|int n) +  TimeRange `+(program|this_program|int n, +  program|this_program|int ... more)    { -  if (objectp(n)) return add(1,n); -  return add(n); +  TimeRange res; +  if (objectp(n)) res = add(1,n); +  else res = add(n); +  if (sizeof(more)) +  return predef::`+(res, @more); +  return res;    }    -  TimeRange ``+(int n) +  TimeRange ``+(int n, int ... more)    { -  +  if (sizeof(more)) n = predef::`+(n, @more);    return add(n);    }    -  TimeRange `-(TimeRange|program|int n) +  TimeRange `-(program|this_program|int n, +  TimeRange|this_program|int ... more)    { -  +  if (sizeof(more)) n = predef::`+(n, @more);    if (objectp(n)) return add(-1,n);    return add(-n);    }      //! method TimeRange next()   //! method TimeRange prev()   //! Next and prev are compatible and convinience functions;   //! <tt>a->next()</tt> is exactly the same as <tt>a+1</tt>;   //! <tt>a=a->next()</tt> is <tt>a++</tt>.       TimeRange next()    { -  return this_object()+1; +  return this+1;    }       TimeRange prev()    { -  return this_object()-1; +  return this-1;    }      //! method TimeRange `*(int n)   //! This changes the amount of time in   //! the time period. <tt>t*17</tt> is   //! the same as doing <tt>t-><ref>set_size</ref>(t,17)</tt>.    -  function ``* = `*; -  TimeRange `*(int n) +  TimeRange ``* (int n) {return `* (n);} +  TimeRange `*(int|float n)    { -  return set_size(n,this_object()); +  return set_size((int)n,this);    }    - //! method array(TimeRange) `/(int n) - //! method array(TimeRange) split(int n) + //! method array(TimeRange) `/(int|float n) + //! method array(TimeRange) split(int|float n, void|TimeRange with)   //! This divides the called timerange into   //! n pieces. The returned timerange type   //! is not neccesarily of the same type as the called one. -  + //! If the optional timerange is specified then the resulting timeranges + //! will be multiples of that range (except for the last one).   //!   //! known bugs:   //! These are currently not defined for   //! <ref to=SuperTimeRange>supertimeranges</ref>.      //! method int `/(TimeRange with)   //! method int how_many(TimeRange with)   //! This calculates how many instances of the given   //! timerange has passed during the called timerange.   //!   //! For instance, to figure out your age,   //! create the timerange of your lifespan, and divide   //! with the instance of a <ref to=YMD.Year>Year</ref>.      // virtual -  array(TimeRange) split(int n); +  array(TimeRange) split(int|float n, void|function|TimeRange with);       int how_many(function|TimeRange with)    {    if (functionp(with)) with=promote_program(with);   // default method; not optimized - guessing       TimeRange start=beginning();    TimeRange end=end();      // find low and high 2^n
pike.git/lib/modules/Calendar.pmod/TimeRanges.pmod:392:       t=start+with*nn;    if (t==end) return nn;    if (t<end) low=nn+1;    else high=nn-1;       if (low>high) return high; // can't go further    }    }    -  array(TimeRange)|int `/(TimeRange|program|int x) +  array(TimeRange)|int `/(TimeRange|program|int|float x)    { -  if (intp(x)) return split(x); +  if (intp(x) || floatp(x)) return split(x);    else return how_many(x);    }      //! method int offset_to(TimeRange x)   //! Calculates offset to x; this compares   //! two timeranges and gives the integer offset   //! between the two starting points.   //!   //! This is true for suitable a and b:   //! <tt>a+a->offset_to(b)==b</tt>   //!   //! By suitable means that a and b are of the same   //! type and size. This is obviously true only   //! if a+n has b as a possible result for any n.       int offset_to(TimeRange x)    { -  if (x==this_object()) return 0; -  if (x<this_object()) -  return -(x->distance(this_object())/this_object()); -  return this_object()->distance(x)/this_object(); +  if (x==this) return 0; +  if (x<this) +  return -(x->distance(this)/this); +  return this->distance(x)/this;    }      //! method TimeRange beginning()   //! method TimeRange end()   //! This gives back the zero-sized beginning   //! or end of the called time period.   //!   //! rule:   //! <tt>range(t->beginning(),t->end())==t</tt>   
pike.git/lib/modules/Calendar.pmod/TimeRanges.pmod:491:   //!   //! |----A----| A preceeds B,   //! |----B----| A overlaps B, A touches B   //!   //! |-------A-------| A preceeds B, A ends with B   //! |----B----| A overlaps B, A contains B, A touches B,   //!   //! |-------A-------| A preceeds B, A succeeds B,   //! |---B---| A overlaps B, A contains B, A touches B   //! - //! |----A----| A overlaps B, A touches B + //! |----A----| A overlaps B, A touches B, A contains B   //! |----B----| A equals B, A starts with B, A ends with B   //!   //! |-------A-------| A succeeds B, A starts with B   //! |----B----| A overlaps B, A contains B, A touches B   //!   //! |----A----| A succeeds B,   //! |----B----| A overlaps B, A touches B   //!   //! |----A----| A strictly succeeds B, A succeeds B   //! |----B----| A is next to B, A touches B   //!   //! |----A----| A strictly succeeds B,   //! |----B----| A succeeds B   //!   //! </pre> -  + //! + //! note: + //! These methods only check the range of the first to the + //! last time in the period; + //! use of combined time periods (<ref>SuperTimeRange</ref>s) + //! might not give you the result you want. + //! + //! see also: `&    -  +    //- internal method   //- returns [-1,0,1] for comparison between   //- (in order) begin/begin,begin/end,end/begin and end/end      // virtual, default    array(int(-1..1)) _compare(TimeRange what)    {    if (objectp(what) && what->is_supertimerange)    { -  array(int(-1..1)) cmp=what->_compare(this_object()); +  array(int(-1..1)) cmp=what->_compare(this);       return ({-cmp[0],    -cmp[2],    -cmp[1],    -cmp[3]});    }    return ({-1,-1,-1,-1});   // error("_compare: incompatible classes %O <-> %O\n", - // object_program(this_object()),object_program(what)); + // this_program,object_program(what));    }       string _describe_compare(array(int(-1..1)) c,TimeRange a,TimeRange b)    {    mapping desc=([-1:"<",0:"=",1:">"]);    return sprintf("%O start %s %O start\n"    "%O start %s %O end\n"    "%O end %s %O start\n"    "%O end %s %O end\n",    a,desc[c[0]],b,
pike.git/lib/modules/Calendar.pmod/TimeRanges.pmod:665:   //!   //! <tt>equal(</tt>a<tt>,</tt>b<tt>)</tt> are considered   //! true if a and b are the same timerange, exactly the same   //! as the <ref>equals</ref> method.   //!   //! The <tt>__hash</tt> method is also present,   //! to make timeranges possible to use as keys in mappings.   //!   //! known bugs:   //! _equal is not currently possible to overload, - //! due to wierd bugs, so equal uses `== for now. + //! due to weird bugs, so equal uses `== for now.    -  int(0..1) `==(TimeRange what) +  int(0..1) `==(mixed what)    { -  return object_program(what)==object_program(this_object()) && -  what->ruleset()==ruleset() && -  equals(what); +  return objectp(what) && functionp(what->ruleset) && +  what->ruleset()==ruleset() && equals(what);    }       int __hash();      // int(0..1) _equal(TimeRange what)   // {   // return equals(what);   // }      //! method TimeRange `&(TimeRange with)   //! Gives the cut on the called time period   //! with another time period. The result is   //! zero if the two periods doesn't overlap.   //! <pre>   //! &gt;- the past the future -&lt;   //! |-------called-------|   //! |-------other--------|   //! &gt;----- cut -----&lt;   //! </pre>    -  function ``& = `&; +  TimeRange|zero ``& (TimeRange with, mixed... extra) +  {return `& (with, @extra);}    TimeRange|zero `&(TimeRange with, mixed ...extra)    {    if (with->is_nulltimerange)    return with;    array(int(-1..1)) a=_compare(with);    if (a[END_BEGIN]<0 || a[BEGIN_END]>0)    return nulltimerange; // no overlap, no extra       if (with->is_supertimerange) -  return predef::`&(with,this_object(),@extra); // let it handle that... +  return predef::`&(with,this,@extra); // let it handle that...       TimeRange from,to;      // from the last beginning    if (a[BEGIN_BEGIN]>0) from=beginning(); else from=with->beginning();      // to the first end    if (a[END_END]<0) to=end(); else to=with->end();      // compute
pike.git/lib/modules/Calendar.pmod/TimeRanges.pmod:728:   //! method TimeRange `|(TimeRange with)   //! Gives the union on the called time period   //! and another time period.   //! <pre>   //! &gt;- the past the future -&lt;   //! |-------called-------|   //! |-------other--------|   //! &lt;----------union----------&gt;   //! </pre>    -  function ``| = `|; +  TimeRange ``| (TimeRange with, mixed... extra) {return `| (with, @extra);}    TimeRange `|(TimeRange with,mixed ...extra)    {    if (with->is_nulltimerange) -  return sizeof(extra)?`|(@extra):this_object(); +  return sizeof(extra)?`|(@extra):this;    array(int(-1..1)) a=_compare(with);    TimeRange from,to;       if (a[END_BEGIN]<0 || a[BEGIN_END]>0) -  from=SuperTimeRange( sort(({this_object(),with})) ); // no overlap +  from=SuperTimeRange( sort(({this,with})) ); // no overlap    else    {    if (with->is_supertimerange) // let it handle that... -  return predef::`|(with,this_object(),@extra); +  return predef::`|(with,this,@extra);       // from the first beginning -  if (a[BEGIN_BEGIN]<0) from=this_object(); else from=with; +  if (a[BEGIN_BEGIN]<0) from=this; else from=with;       // to the last end -  if (a[END_END]>0) to=this_object(); else to=with; +  if (a[END_END]>0) to=this; else to=with;    // compute    from=from->range(to);    }    if (sizeof(extra)) return predef::`|(from,@extra);    return from;    }      //! method TimeRange `^(TimeRange with)   //! Gives the exclusive-or on the called time period   //! and another time period, ie the union without   //! the cut. The result is zero if the   //! two periods were the same.   //! <pre>   //! &gt;- the past the future -&lt;   //! |-------called-------|   //! |-------other--------|   //! &lt;----| |----> - exclusive or   //! </pre>    -  function ``^ = `^; +  TimeRange ``^ (TimeRange with, mixed... extra) {return `^ (with, @extra);}    TimeRange `^(TimeRange with,mixed ... extra)    {    if (with->is_supertimerange) -  return `^(with,this_object(),@extra); // let it handle that... +  return `^(with,this,@extra); // let it handle that...    if (with->is_nulltimerange) -  return sizeof(extra)?`^(@extra):this_object(); +  return sizeof(extra)?`^(@extra):this;       TimeRange res;       array(int(-1..1)) a=_compare(with);    - // write(_describe_compare(a,this_object(),with)); + // write(_describe_compare(a,this,with));       TimeRange first,second;    if (a[END_BEGIN]<0 || a[BEGIN_END]>0) -  res=SuperTimeRange( sort(({this_object(),with})) ); // no overlap +  res=SuperTimeRange( sort(({this,with})) ); // no overlap    else if (a[BEGIN_END]==0 || a[END_BEGIN]==0) // bordering    if (a[BEGIN_BEGIN]<0)    res=range(with); // A precedes B    else -  res=with->range(this_object()); // B precedes A +  res=with->range(this); // B precedes A    else if (a[BEGIN_BEGIN]==0 && a[END_END]==0)    return sizeof(extra)?predef::`^(nulltimerange,@extra):nulltimerange;    else    {    // from the first beginning to the second beginning    if (a[BEGIN_BEGIN]<0)    first=distance(with);    else -  first=with->distance(this_object()); +  first=with->distance(this);      // and from the first end to the last end    if (a[END_END]<0)    second=end()->range(with);    else -  second=with->end()->range(this_object()); +  second=with->end()->range(this);    res=first|second;    }    // done    if (sizeof(extra)) return `^(res,@extra);    return res;    }      //! method TimeRange subtract(TimeRange what)   //! This subtracts a period of time from another;   //! <pre>
pike.git/lib/modules/Calendar.pmod/TimeRanges.pmod:829:   //! |-------called-------|   //! |---third---|   //! &lt;----&gt; &lt;---> &lt;- called->subtract(third)   //! </pre>       TimeRange subtract(TimeRange what,mixed ... extra)    {    array(int(-1..1)) a=_compare(what);       if (a[END_BEGIN]<=0 || a[BEGIN_END]>=0) -  return sizeof(extra)?subtract(@extra):this_object(); // no overlap +  return sizeof(extra)?subtract(@extra):this; // no overlap       if (what->is_supertimerange)    {    array res=map(what->parts+extra,subtract)-({nulltimerange});    switch (sizeof(res))    {    case 0: return nulltimerange;    case 1: return res[0];    default: return predef::`&(@res);    }    }       TimeRange res;    - // write(_describe_compare(a,this_object(),what)); + // write(_describe_compare(a,this,what));       if (a[BEGIN_BEGIN]>=0) // it preceeds us    if (a[END_END]<=0)    return nulltimerange; // full overlap    else // half overlap at start -  res=what->end()->range(this_object()); +  res=what->end()->range(this);    else if (a[END_END]<=0) // it succeeds us    res=distance(what);    else    {   // werror("%O..\n..%O\n%O..\n..%O\n",   // beginning(),what->beginning(),   // what->end(),end());   // it's inside us    res=predef::`|(distance(what), -  what->end()->range(this_object())); +  what->end()->range(this));    }    if (sizeof(extra)) return res->subtract(@extra);    return res;    }      //! method TimeRange set_ruleset(Ruleset r)   //! method TimeRange ruleset(Ruleset r)   //! Set or get the current ruleset.   //! note:   //! this may include timezone shanges,   //! and change the time of day.    -  TimeRange set_ruleset(Ruleset r); -  Ruleset ruleset() +  this_program set_ruleset(Calendar.Ruleset r); +  Calendar.Ruleset ruleset()    {    return rules;    }      //! method TimeRange set_timezone(Timezone tz)   //! method TimeRange set_timezone(string tz)   //! method TimeZone timezone()   //! Set or get the current timezone (including dst) rule.   //!   //! note:   //! The time-of-day may very well   //! change when you change timezone.   //!   //! To get the time of day for a specified timezone,   //! select the timezone before getting the time of day:   //!   //! <tt>Year(2003)-&gt;...-&gt;set_timezone(TimeZone.CET)-&gt;...-&gt;hour(14)-&gt;...</tt>   //!    -  TimeRange set_timezone(string|Ruleset.Timezone tz) +  this_program set_timezone(string|Calendar.Rule.Timezone tz)    {    return set_ruleset(rules->set_timezone(tz));    }    -  Ruleset.Timezone timezone() +  Calendar.Rule.Timezone timezone()    {    return rules->timezone;    }    - //! method TimeRange set_language(Language lang) + //! method TimeRange set_language(Rule.Language lang)   //! method TimeRange set_language(string lang)   //! method Language language()   //! Set or get the current language rule.    -  TimeRange set_language(string|Ruleset.Language lang) +  this_program set_language(string|Calendar.Rule.Language lang)    {    return set_ruleset(rules->set_language(lang));    }    -  Ruleset.Language language() +  Calendar.Rule.Language language()    {    return rules->language;    }      //! method Calendar calendar()   //! Simply gives back the calendar in use, for instance   //! Calendar.ISO or Calendar.Discordian.       object calendar()    {    return calendar_object;    } -  +  +  +  protected string _sprintf(int t,mapping m) +  { +  switch (t) +  { +  case 'O': +  return "TimeRange()"; +  case 't': +  return "Calendar."+calendar_name()+".TimeRange"; +  default: +  return 0;    } -  +  } + }      // ----------------------------------------------------------------      //!   //! module Calendar   //! class SuperTimeRange   //! This class handles the cases where you have a time   //! period with holes. These can be created by the   //! <tt>^</tt> or <tt>|</tt> operators on time ranges.   //! inherits TimeRange
pike.git/lib/modules/Calendar.pmod/TimeRanges.pmod:952:       constant is_supertimerange=1;       array parts;      //! method void create(array(TimeRange) parts)   //! A SuperTimeRange must have at least two parts,   //! two time ranges. Otherwise, it's either not   //! a time period at all or a normal time period.    -  void create(array(TimeRange) _parts) +  protected void create(array(TimeRange) _parts)    {    if (sizeof(_parts->is_supertimerange-({0})))    error("one part is super\n%O\n",_parts);    if (sizeof(_parts)<2)    error("SuperTimeRange: Too few time periods to constructor\n");    parts=_parts;    }       TimeRange beginning()    {
pike.git/lib/modules/Calendar.pmod/TimeRanges.pmod:1023:    default: return SuperTimeRange(r);    }    }       TimeRange `|(TimeRange with,mixed ...extra)    {    TimeRange res;    if (with->is_supertimerange)    res=mend_overlap(sort(with->parts+parts));    else if (with->is_nulltimerange) -  return this_object(); +  return this;    else    res=mend_overlap(sort( ({with})+parts ));    if (sizeof(extra))    return predef::`|(res,@extra);    return res;    }       TimeRange subtract(TimeRange with,mixed ...extra)    {    array r=({});
pike.git/lib/modules/Calendar.pmod/TimeRanges.pmod:1104:    if (a[3]>0) return 1;    if (a[3]<0) return 0;    if (!with->is_supertimerange) return 0; // always    if (sizeof(parts)<sizeof(with->parts)) return 1;    if (sizeof(parts)>sizeof(with->parts)) return 0;    for (int i=0; i<sizeof(parts); i++)    if (parts[i]>with->parts[i]) return 1;    return 0;    }    -  int __hash() +  protected int __hash()    {    return predef::`+(@map(parts,"__hash"));    }    -  string _sprintf(int t) +  protected string _sprintf(int t,mapping m)    {    switch (t)    {    case 'O':    return "SuperTimeRange("+    map(parts,"_sprintf",'O')*", "+")"; -  +  case 't': +  return "SuperTimeRange("+ +  map(parts,"_sprintf",'t')*", "+")";    } -  return 0; +  return ::_sprintf(t,m);    }    -  TimeRange set_timezone(string|Timezone tz) +  TimeRange set_timezone(string|Calendar.Rule.Timezone tz)    {   // fixme?    return `|(@map(parts,"set_timezone",tz));    }   }    -  + //! module Calendar   //! constant TimeRange nulltimerange   //! This represents the null time range,   //! which, to differ from the zero time range   //! (the zero-length time range), isn't placed   //! in time. This is the result of for instance   //! <ref>`&</ref> between two strict non-overlapping   //! timeranges - no time at all.   //!   //! It has a constant, <tt>is_nulltimerange</tt>, which   //! is non-zero. <tt>`!</tt> on this timerange is true.         program NullTimeRange=cNullTimeRange; - static class cNullTimeRange + protected class cNullTimeRange   {    inherit TimeRange;       constant is_nulltimerange=1;      // overload -  void create() +  protected void create()    {    }       TimeRange set_size(TimeRange|int(0..0x7fffffff) a,void|TimeRange b)    { -  return this_object(); +  return this;    }       TimeRange place(TimeRange what,void|int force)    { -  return this_object(); +  return this;    }       array(TimeRange) split(int n)    { -  return allocate(n,this_object()); +  return allocate(n,this);    }    -  TimeRange beginning() { return this_object(); } -  TimeRange end() { return this_object(); } +  TimeRange beginning() { return this; } +  TimeRange end() { return this; }       TimeRange distance(TimeRange to)    { -  if (to==this_object()) return this_object(); +  if (to==this) return this;    error("Can't distance/space/range with the null timerange\n");    }       array(int(-1..1)) _compare(TimeRange with)    { -  if (with==this_object()) return ({0,0,0,0}); +  if (with==this) return ({0,0,0,0});    return ({-1,-1,-1,-1});    }       int(0..1) `<(TimeRange with)    { -  return !(with==this_object()); +  return !(with==this);    }       int(0..1) `>(TimeRange with)    {    return 0;    }       int(0..1) `==(TimeRange with)    {    return objectp(with) && with->is_nulltimerange;    }       int(0..1) equals(TimeRange with)    {    return objectp(with) && with->is_nulltimerange;    }       TimeRange `&(TimeRange with, mixed ...extra)    { -  return predef::`&(with,this_object(),@extra); +  return predef::`&(with,this,@extra);    }       TimeRange `|(TimeRange with, mixed ...extra)    { -  return predef::`|(with,this_object(),@extra); +  return predef::`|(with,this,@extra);    }       TimeRange `^(TimeRange with, mixed ...extra)    { -  return predef::`^(with,this_object(),@extra); +  return predef::`^(with,this,@extra);    }       this_program subtract(TimeRange with, mixed ...extra)    { -  return this_object(); +  return this;    }       int(1..1) `!()    {    return 1;    }    -  string _sprintf(int t) +  protected string _sprintf(int t,mapping m)    {    switch (t)    {    case 'O': return "NullTimeRange"; -  default: return 0; +  case 't': return "Calendar."+calendar_name()+".NullTimeRange"; +  default: return ::_sprintf(t,m);    }    }   }      cNullTimeRange nulltimerange=NullTimeRange();      // helper functions    - static mapping(function:TimeRange) program2stuff=([]); + protected mapping(function:TimeRange) program2stuff=([]);    - static TimeRange promote_program(function p) + protected TimeRange promote_program(function p)   {    TimeRange x;    if ( (x=program2stuff[p]) ) return x;    x=[object(TimeRange)]p();    if (!x->is_timerange)    error("Not a timerange program: %O\n",p);    return program2stuff[p]=x;   }