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

version» Context lines:

pike.git/lib/modules/Calendar.pmod/Event.pmod:1:   #pike __REAL_VERSION__      static constant M_YD=({0,0,31,59,90,120,151,181,212,243,273,304,334});   static constant M_ED=({({0,31,59,90,120,151,181,212,243,273,304,334,365}),    ({0,31,60,91,121,152,182,213,244,274,305,335,366}),    ({0,31,60,90,120,151,181,212,243,273,304,334,365}) });   static constant M_NAME="---JanFebMarAprMayJunJulAugSepOctNovDec"/3;   static constant WD_NAME="---MonTueWedThuFriSatSun"/3;    - static function(mixed...:.TimeRanges.TimeRange) std_day=Calendar.Day; - static function(mixed...:.TimeRanges.TimeRange) std_second=Calendar.Second; + static function(mixed...:Calendar.TimeRanges.TimeRange) std_day= +  Calendar.Day; + static function(mixed...:Calendar.TimeRanges.TimeRange) std_second= +  Calendar.Second;      // ----------------------------------------------------------------   // base classes   // ----------------------------------------------------------------         //! Event is an abstract class, defining what methods an Event   //! need to have.   class Event   {
pike.git/lib/modules/Calendar.pmod/Event.pmod:25:    //! This constant may be used to identify an event object.    constant is_event=1;       //! This calculates the next or previous occurance of the event,    //! from the given timerange's start, including any event occuring    //! at the start if that flag is set.    //!    //! It returns zero if there is no next event.    //!    //! These methods are virtual in the base class. -  .TimeRanges.TimeRange next(void|.TimeRanges.TimeRange from, +  Calendar.TimeRanges.TimeRange next(void|Calendar.TimeRanges.TimeRange from,    void|int(0..1) including); -  .TimeRanges.TimeRange previous(void|.TimeRanges.TimeRange from, +  Calendar.TimeRanges.TimeRange previous(void|Calendar.TimeRanges.TimeRange from,    void|int(0..1) including);       //! This calculates the eventual events that is contained or    //! overlapped by the given timerange. @[scan] uses @[next], if not    //! overloaded.    //!    //! @example    //! Calendar.Event.Easter()->scan(Calendar.Year(2000))    //! => ({ Day(Sun 23 Apr 2000) })    //!    //! @note    //! @[scan] can return an array of overlapping timeranges.    //!    //! This method must use @tt{in->calendar_object->@}@i{type@}    //! to create the returned timeranges, and must keep the ruleset. -  array(.TimeRanges.TimeRange) scan(.TimeRanges.TimeRange in) +  array(Calendar.TimeRanges.TimeRange) scan(Calendar.TimeRanges.TimeRange in)    {    array res=({}); -  .TimeRanges.TimeRange t=next(in,1); +  Calendar.TimeRanges.TimeRange t=next(in,1);    for (;;)    {    if (!t || !t->overlaps(in)) return res;    res+=({t});    t=next(t);    }    }       //! Returns a mapping with time ranges mapped to events. -  mapping(.TimeRanges.TimeRange:Event) scan_events(.TimeRanges.TimeRange in) +  mapping(Calendar.TimeRanges.TimeRange:Event) +  scan_events(Calendar.TimeRanges.TimeRange in)    {    array r=scan(in);    return mkmapping(r,allocate(sizeof(r),this));    }       //! Joins several events into one @[SuperEvent].    SuperEvent `|(Event ... with)    {    with-=({0});    with|=({this});
pike.git/lib/modules/Calendar.pmod/Event.pmod:106:       //! This constant may be used to identify a NullEvent.    constant is_nullevent=1;       void create(string _id,string s,mixed ...args)    {    id=_id;    name=s;    }    -  .TimeRanges.TimeRange next(void|.TimeRanges.TimeRange from, +  Calendar.TimeRanges.TimeRange next(void|Calendar.TimeRanges.TimeRange from,    void|int(0..1) including)    {    return 0;    }    -  .TimeRanges.TimeRange previous(void|.TimeRanges.TimeRange from, +  Calendar.TimeRanges.TimeRange previous(void|Calendar.TimeRanges.TimeRange from,    void|int(0..1) including)    {    return 0;    }   }      //! @[Day_Event] is an abstract class, extending @[Event] for events   //! that are single days, using julian day numbers for the calculations.   class Day_Event   {
pike.git/lib/modules/Calendar.pmod/Event.pmod:134:       //! This constant may be used to identify @[Day_Event] objects.    constant is_day_event=1;       //! Returned from @[scan_jd] if the even searched for did not    //! exist.    constant NODAY=-1;       int nd=1;    -  //! @decl int scan_jd(.Calendar realm, int jd,@ +  //! @decl int scan_jd(Calendar.Calendar realm, int jd,@    //! int(-1..-1)|int(1..1) direction)    //! These methods has to be defined, and is what    //! really does some work. It should return the next or previos    //! julian day (>@i{jd@}) when the event occurs,    //! or the constant @[NODAY] if it doesn't.    //!    //! @param direction    //! @int    //! @value 1    //! Forward (next),    //! @value -1    //! Backward (previous).    //! @endint    -  int scan_jd(.Calendar realm,int jd,int(1..1)|int(-1..-1) direction); +  int scan_jd(Calendar.Calendar realm,int jd,int(1..1)|int(-1..-1) direction);       //! Uses the virtual method @[scan_jd].    //! @seealso    //! @[Event.next] -  .TimeRanges.TimeRange next(void|.TimeRanges.TimeRange from, +  Calendar.TimeRanges.TimeRange next(void|Calendar.TimeRanges.TimeRange from,    void|int(0..1) including)    {    if (!from) from=std_day();    int jd;    if (including) jd=(int)(from->julian_day());    else jd=(int)(from->end()->julian_day());    jd=scan_jd(from->calendar(),jd-nd+1,1);    return (from->calendar()->Day)("julian_r",jd,from->ruleset())*nd;    }       //! Uses the virtual method @[scan_jd].    //! @seealso    //! @[Event.previous] -  .TimeRanges.TimeRange previous(void|.TimeRanges.TimeRange from, +  Calendar.TimeRanges.TimeRange previous(void|Calendar.TimeRanges.TimeRange from,    void|int(0..1) including)    {    if (!from) from=std_day();    int jd;    if (including) jd=(int)(from->end()->julian_day());    else jd=(floatp(from->julian_day())    ?(int)floor(from->julian_day())    :(from->julian_day()-1));    jd=scan_jd(from->calendar(),jd+nd-1,-1);    if (jd==NODAY) return 0;
pike.git/lib/modules/Calendar.pmod/Event.pmod:201:    constant is_nameday=1;       int jd;       void create(string _name,int _jd)    {    name=_name;    jd=_jd;    }    -  int scan_jd(.Calendar realm,int sjd,int(1..1)|int(-1..-1) direction) +  int scan_jd(Calendar.Calendar realm,int sjd,int(1..1)|int(-1..-1) direction)    {    if (direction==1) return sjd<=jd?jd:NODAY;    else return sjd>=jd?jd:NODAY;    }       string _sprintf(int t)    {    return t=='O'?sprintf("Nameday(%s:%O)",id,name):0;    }   }
pike.git/lib/modules/Calendar.pmod/Event.pmod:244:    name=_name;    namelist=_names;    first_year=start||-1;    last_year=stop||-1;    leapdayshift=_leapdayshift||2000;    lookup=_lookup;    }       //! Gives back an array of names that occur during    //! the time period, in no particular order. -  array(string) names(.TimeRanges.TimeRange t) +  array(string) names(Calendar.TimeRanges.TimeRange t)    {    // optimize this?    return predef::`|(({}),@values(namedays(t)));    }       //! Gives back an table of days with names that occur during    //! the time period. Note that days without names will not    //! appear in the returned mapping. -  mapping(.TimeRanges.TimeRange:array(string)) -  namedays(.TimeRanges.TimeRange t) +  mapping(Calendar.TimeRanges.TimeRange:array(string)) +  namedays(Calendar.TimeRanges.TimeRange t)    {    int jd=t->julian_day();    mapping res=([]); -  function(mixed...:.TimeRanges.TimeRange) day=t->calendar()->Day; -  .Ruleset rules=t->ruleset(); +  function(mixed...:Calendar.TimeRanges.TimeRange) day=t->calendar()->Day; +  Calendar.Ruleset rules=t->ruleset();    [int y,int yjd,int leap]=gregorian_yjd(jd);    if (first_year!=-1 && y<first_year)    [y,yjd,leap]=gregorian_year(first_year),jd=yjd;    if (last_year!=-1 && y>last_year) return res;    int ld;    if (y<leapdayshift) ld=55-1; // 24 feb    else ld=60-1; // 29 feb       for (;;)    { -  .TimeRanges.TimeRange td=day("julian_r",jd,rules); +  Calendar.TimeRanges.TimeRange td=day("julian_r",jd,rules);    if (!td->overlaps(t)) return res;       if (jd>=yjd+365+leap) // next year    {    [y,yjd,leap]=gregorian_yjd(jd);    if (last_year!=-1 && y>last_year) return res;    if (y<leapdayshift) ld=55-1; // 24 feb    else ld=60-1; // 29 feb    }   
pike.git/lib/modules/Calendar.pmod/Event.pmod:297:    else n=namelist[-1];    }    else    n=namelist[d];       if (n) res[td]=n;    jd++;    }    }    -  mapping(.TimeRanges.TimeRange:Event) scan_events(.TimeRanges.TimeRange in) +  mapping(Calendar.TimeRanges.TimeRange:Event) +  scan_events(Calendar.TimeRanges.TimeRange in)    {    mapping res=([]); -  foreach ((array)namedays(in),[.TimeRanges.TimeRange t,array(string) s]) +  foreach ((array)namedays(in), +  [Calendar.TimeRanges.TimeRange t,array(string) s])    res[t]=predef::`|(@map(s,Nameday,t->julian_day()));    return res;    }    -  array(.TimeRanges.TimeRange) scan(.TimeRanges.TimeRange in) +  array(Calendar.TimeRanges.TimeRange) scan(Calendar.TimeRanges.TimeRange in)    {    return indices(namedays(in));    }    -  static .TimeRanges.TimeRange _find(.TimeRanges.TimeRange t, +  static Calendar.TimeRanges.TimeRange _find(Calendar.TimeRanges.TimeRange t,    int including, int direction)    {    int jd=(int)t->julian_day();       jd+=direction*!including;       [int y,int yjd,int leap]=gregorian_yjd(jd);    int ld;    if (y<leapdayshift) ld=55-1; // 24 feb    else ld=60-1; // 29 feb
pike.git/lib/modules/Calendar.pmod/Event.pmod:355:    }    else    n=namelist[d];       if (n) return t->calendar()->Day("julian_r",jd,t->ruleset());       jd+=direction;    }    }    -  .TimeRanges.TimeRange next(.TimeRanges.TimeRange from, +  Calendar.TimeRanges.TimeRange next(Calendar.TimeRanges.TimeRange from,    void|int(0..1) including)    {    return _find(from,including,1);    }    -  .TimeRanges.TimeRange previous(.TimeRanges.TimeRange from, +  Calendar.TimeRanges.TimeRange previous(Calendar.TimeRanges.TimeRange from,    void|int(0..1) including)    {    return _find(from,including,-1);    }       string _sprintf(int t)    {    return t=='O'?sprintf("Namedays(%s:%O)",id,name):0;    }   
pike.git/lib/modules/Calendar.pmod/Event.pmod:422:    string _sprintf(int t)    {    return t=='O'?sprintf("SuperNamedays(%s [%d])",id,sizeof(namedayss)):0;    }       string describe()    {    return "Namedays";    }    -  array(.TimeRanges.TimeRange) scan(.TimeRanges.TimeRange in) +  array(Calendar.TimeRanges.TimeRange) scan(Calendar.TimeRanges.TimeRange in)    {    return indices(namedays(in));    }    -  mapping(.TimeRanges.TimeRange:Event) scan_events(.TimeRanges.TimeRange in) +  mapping(Calendar.TimeRanges.TimeRange:Event) +  scan_events(Calendar.TimeRanges.TimeRange in)    {    return predef::`|(@map(namedayss,"scan_events",in));    }    -  .TimeRanges.TimeRange next(.TimeRanges.TimeRange from, +  Calendar.TimeRanges.TimeRange next(Calendar.TimeRanges.TimeRange from,    void|int(0..1) including)    { -  array(.TimeRanges.TimeRange) a=map(namedayss,"next", +  array(Calendar.TimeRanges.TimeRange) a=map(namedayss,"next",    from,including)-({0});    switch (sizeof(a))    {    case 0: return UNDEFINED;    case 1: return a[0];    default: return min(@a);    }    }    -  .TimeRanges.TimeRange previous(.TimeRanges.TimeRange from, +  Calendar.TimeRanges.TimeRange previous(Calendar.TimeRanges.TimeRange from,    void|int(0..1) including)    { -  array(.TimeRanges.TimeRange) a=map(namedayss,"previous", +  array(Calendar.TimeRanges.TimeRange) a=map(namedayss,"previous",    from,including)-({0});    switch (sizeof(a))    {    case 0: return UNDEFINED;    case 1: return a[0];    default: return max(@a);    }    }    -  mapping(.TimeRanges.TimeRange:array(string)) -  namedays(.TimeRanges.TimeRange t) +  mapping(Calendar.TimeRanges.TimeRange:array(string)) +  namedays(Calendar.TimeRanges.TimeRange t)    {    return predef::`|(@map(namedayss,"namedays",t));    }    -  array(string) names(.TimeRanges.TimeRange t) +  array(string) names(Calendar.TimeRanges.TimeRange t)    {    return predef::`|(@map(namedayss,"names",t));    }       SuperEvent|SuperNamedays|Namedays    `|(SuperEvent|Namedays|SuperNamedays e,    mixed ...extra)    {    if (e->is_namedays_wrapper)    return `|(this,@e->namedayss,@extra);
pike.git/lib/modules/Calendar.pmod/Event.pmod:569:    {    id=_id;    name=_name;    md=_md;    mn=_mn;       yd=M_YD[mn]+md;    if (sizeof(_n)) nd=_n[0];    }    -  int scan_jd(.Calendar realm,int jd,int(-1..1) direction) +  int scan_jd(Calendar.Calendar realm,int jd,int(-1..1) direction)    {    [int y,int yjd,int leap]=gregorian_yjd(jd);    int njd;       for (;;)    {    if (leap && yd>59)    njd=yjd+yd;    else    njd=yjd+yd-1; // yd start with 1
pike.git/lib/modules/Calendar.pmod/Event.pmod:611:   //! used for the Gregorian fixed events in the events list.   //! @seealso   //! @[Gregorian_Fixed]   class Julian_Fixed   {    inherit Gregorian_Fixed;       //! This constant may be used to identify @[Julian_Fixed] objects.    constant is_julian_fixed=1;    -  int scan_jd(.Calendar realm,int jd,int(-1..1) direction) +  int scan_jd(Calendar.Calendar realm,int jd,int(-1..1) direction)    {    [int y,int yjd,int leap]=julian_yjd(jd);    int njd;       for (;;)    {    if (leap && yd>59)    njd=yjd+yd;    else    njd=yjd+yd-1; // yd start with 1
pike.git/lib/modules/Calendar.pmod/Event.pmod:664:    //! (1=January, 12=December).    void create(int _md,int _mn)    {    md=_md;    mn=_mn;    name=M_NAME[mn]+" "+md;       yd=M_YD[mn]+md;    }    -  int scan_jd(.Calendar realm,int jd,int(-1..1) direction) +  int scan_jd(Calendar.Calendar realm,int jd,int(-1..1) direction)    {    [int y,int yjd,int leap]=gregorian_yjd(jd);    for (;;)    {    int njd;       if (leap && yd>60)    njd=yjd+yd;    else    njd=yjd+yd-1; // yd start with 1
pike.git/lib/modules/Calendar.pmod/Event.pmod:721:    void create(int _md,int _mn,int wd)    {    md=_md;    mn=_mn;    name=M_NAME[mn]+" "+md+" "+WD_NAME[wd];       yd=M_YD[mn]+md;    jd_wd=(wd+6)%7;    }    -  int scan_jd(.Calendar realm,int jd,int(-1..1) direction) +  int scan_jd(Calendar.Calendar realm,int jd,int(-1..1) direction)    {    if (md<1) return 0;    [int y,int yjd,int leap]=gregorian_yjd(jd);    for (;;)    {    int njd;       if (leap && yd>60)    njd=yjd+yd;    else
pike.git/lib/modules/Calendar.pmod/Event.pmod:774:    //! The week day numbers used are the same as the day of week in    //! the @[ISO] calendar - the @[Gregorian] calendar has 1=Sunday,    //! 7=Saturday.    void create(int _md,int wd)    {    md=_md;    name=md+","+WD_NAME[wd];    jd_wd=(wd+6)%7;    }    -  int scan_jd(.Calendar realm,int jd,int(-1..1) direction) +  int scan_jd(Calendar.Calendar realm,int jd,int(-1..1) direction)    {    if (md>31 || md<1) return 0;    [int y,int yjd,int leap]=gregorian_yjd(jd);    for (;;)    {    array z,w;       if (!leap)    z=({0,31,59,90,120,151,181,212,243,273,304,334});    else
pike.git/lib/modules/Calendar.pmod/Event.pmod:835:    //! The week day numbers used are the same as the day of week in    //! the @[ISO] calendar - the @[Gregorian] calendar has 1=Sunday,    //! 7=Saturday.    void create(int wd,void|string _id)    {    jd_wd=(wd+6)%7; // convert to julian day numbering    name=WD_NAME[wd];    if (!id) id=name; else id=_id;    }    -  int scan_jd(.Calendar realm,int jd,int(-1..1) direction) +  int scan_jd(Calendar.Calendar realm,int jd,int(-1..1) direction)    {    if (direction==-1) return jd-(jd-jd_wd)%7;    return jd+(7-(jd-jd_wd))%7;    }   }         //! This class represents an easter.   class Easter   {
pike.git/lib/modules/Calendar.pmod/Event.pmod:911:    int z=(y<shift)?old_style(y):new_style(y);    return `+(yjd,z,58,leap);    }       static array(int) my_year(int y)    {    if (y<shift) return julian_year(y);    return gregorian_year(y);    }    -  int scan_jd(.Calendar realm,int jd,int(-1..1) direction) +  int scan_jd(Calendar.Calendar realm,int jd,int(-1..1) direction)    {    int y,yjd,leap,ejd;      // werror("scan %O %O\n",jd,direction);       [y,yjd,leap]=gregorian_yjd(jd);    if (y<shift)    [y,yjd,leap]=julian_yjd(jd);       for (;;)
pike.git/lib/modules/Calendar.pmod/Event.pmod:958:    int offset;       //! @decl void create(string id, string name, int offset)    void create(string _id,string _name,void|int _offset)    {    id=_id;    name=_name;    offset=_offset;    }    -  int scan_jd(.Calendar realm,int jd,int(-1..1) direction) +  int scan_jd(Calendar.Calendar realm,int jd,int(-1..1) direction)    {    return offset+::scan_jd(realm,jd-direction*offset,direction);    }       string describe()    {    return sprintf("%seaster %+2d, %s",    shift>2000?"orthodox ":"",    offset,WD_NAME[(offset-1)%7+1]);    }
pike.git/lib/modules/Calendar.pmod/Event.pmod:1023:    if (n<0)    offset=(n+1)*7-!inclusive;    else if (n>0)    offset=n*7-!!inclusive;    else    offset=3;       wd=_wd;    }    -  int scan_jd(.Calendar realm,int jd,int(-1..1) direction) +  int scan_jd(Calendar.Calendar realm,int jd,int(-1..1) direction)    {    [int y,int yjd,int leap]=gregorian_yjd(jd-offset);    for (;;)    {    int njd;       int d=yd+offset;    if (leap && d>59)    njd=(yjd+((d)-1)+leap-( (yjd+leap+((d)+(8-wd)-1)) % 7));    else
pike.git/lib/modules/Calendar.pmod/Event.pmod:1129:    array res=({});    multiset m;    foreach (events,Event e)    if ((m=flags[e]) && m[flag]) res+=({e});    return SuperEvent(res,flags&res,id+"!"+flag);    }       SuperEvent holidays() { return filter_flag("h"); }    SuperEvent flagdays() { return filter_flag("f"); }    -  mapping(.TimeRanges.TimeRange:Event) scan_events(.TimeRanges.TimeRange in) +  mapping(Calendar.TimeRanges.TimeRange:Event) +  scan_events(Calendar.TimeRanges.TimeRange in)    {    mapping res=([]);    foreach (events,Event e)    {    mapping er=e->scan_events(in); -  foreach ((array)er,[.TimeRanges.TimeRange t,Event e]) +  foreach ((array)er,[Calendar.TimeRanges.TimeRange t,Event e])    if (res[t]) res[t]|=e; // join    else res[t]=e;    }    return res;    }    -  array(.TimeRanges.TimeRange) scan(.TimeRanges.TimeRange in) +  array(Calendar.TimeRanges.TimeRange) scan(Calendar.TimeRanges.TimeRange in)    {    return indices(scan_events(in));    }    -  .TimeRanges.TimeRange next(.TimeRanges.TimeRange from, +  Calendar.TimeRanges.TimeRange next(Calendar.TimeRanges.TimeRange from,    void|int(0..1) including)    { -  .TimeRanges.TimeRange best=0; +  Calendar.TimeRanges.TimeRange best=0;    foreach (events,Event e)    { -  .TimeRanges.TimeRange y=e->next(from,including); +  Calendar.TimeRanges.TimeRange y=e->next(from,including);    if (!best || y->preceeds(best)) best=y;    else if (y->starts_with(best)) best|=y;    }    return best;    }    -  .TimeRanges.TimeRange previous(.TimeRanges.TimeRange from, +  Calendar.TimeRanges.TimeRange previous(Calendar.TimeRanges.TimeRange from,    void|int(0..1) including)    { -  .TimeRanges.TimeRange best=0; +  Calendar.TimeRanges.TimeRange best=0;    foreach (events,Event e)    { -  .TimeRanges.TimeRange y=e->previous(from,including); +  Calendar.TimeRanges.TimeRange y=e->previous(from,including);    if (!best || best->preceeds(y)) best=y;    else if (y->ends_with(best)) best|=y;    }    return best;    }       Event `|(Event|SuperEvent ... with)    {    with-=({0});    return SuperEvent(events|with,flags,"?");
pike.git/lib/modules/Calendar.pmod/Event.pmod:1237:    }   }      //! Event containing information about when a timezone is changed.   class TZShift_Event   {    inherit Event;       constant is_tzshift_event=1;    -  .Rule.Timezone timezone; +  Calendar.Rule.Timezone timezone;    -  void create(void|.Rule.Timezone _tz) +  void create(void|Calendar.Rule.Timezone _tz)    {    timezone=_tz;    }    -  .TimeRanges.TimeRange next(void|.TimeRanges.TimeRange from, +  Calendar.TimeRanges.TimeRange next(void|Calendar.TimeRanges.TimeRange from,    void|int(0..1) including)    {    if (!from) from=std_second();    return scan_shift(timezone||from->timezone(),    from,1,including);    } -  .TimeRanges.TimeRange previous(void|.TimeRanges.TimeRange from, +  Calendar.TimeRanges.TimeRange previous(void|Calendar.TimeRanges.TimeRange from,    void|int(0..1) including)    {    if (!from) from=std_second();    return scan_shift(timezone||from->timezone(),    from,-1,including);    }       //! -  static .TimeRanges.TimeRange scan_shift(.Rule.Timezone tz, -  .TimeRanges.TimeRange from, +  static Calendar.TimeRanges.TimeRange +  scan_shift(Calendar.Rule.Timezone tz, +  Calendar.TimeRanges.TimeRange from,    int direction,int including)    {    if (tz->whatrule)    return scan_history(tz,from,direction,including);    return scan_rule(tz,from,direction,including);    }       //! -  static .TimeRanges.TimeRange scan_history(.Rule.Timezone tz, -  .TimeRanges.TimeRange from, +  static Calendar.TimeRanges.TimeRange +  scan_history(Calendar.Rule.Timezone tz, +  Calendar.TimeRanges.TimeRange from,    int direction,int(0..1) including)    {    int ux;       if ((direction==1) ^ (!!including))    ux=(from=from->end())->unix_time();    else    ux=from->unix_time();       int nextshift=-1;    if (direction==1)    {    foreach (tz->shifts,int z)    if (z>=ux) { nextshift=z; break; }    }    else    foreach (reverse(tz->shifts),int z)    if (z<=ux) { nextshift=z; break; }    -  .TimeRanges.TimeRange btr=0; +  Calendar.TimeRanges.TimeRange btr=0;    if (nextshift!=-1)    btr=from->calendar()->Second("unix_r",nextshift,from->ruleset());    -  .TimeRanges.TimeRange atr=from; +  Calendar.TimeRanges.TimeRange atr=from;    for (;;)    { -  .Rule.Timezone atz=tz->whatrule(ux); +  Calendar.Rule.Timezone atz=tz->whatrule(ux);    atr=scan_rule(atz,atr,direction,including);    if (!atr) break;    if (direction==1)    { if (atr>=from) break; }    else    if (atr<=from) break;    }       if (!btr)    return atr;    if (!atr)    return btr;    if ( (direction==1)^(btr>atr) )    return btr;    else    return atr;    }       //! -  static .TimeRanges.TimeRange scan_rule(.Rule.Timezone tz, -  .TimeRanges.TimeRange from, +  static Calendar.TimeRanges.TimeRange +  scan_rule(Calendar.Rule.Timezone tz, +  Calendar.TimeRanges.TimeRange from,    int direction,int including)    {    if (!tz->jd_year_periods)    return 0; // non-shifting timezone       int jd;    if ((direction==1) ^ (!!including))    jd=(int)(from=from->end())->julian_day();    else    jd=(int)from->julian_day();
pike.git/lib/modules/Calendar.pmod/Event.pmod:1346:    {    // sanity check, are we leaving all shifts behind?    if (direction==-1 && y<tz->firstyear) return 0;    if (direction==1 && y>tz->lastyear) return 0;    }    if (direction==1)    {    foreach (per[1..],array shift)    if (shift[0]>=jd)    { -  .TimeRanges.TimeRange atr=from->calendar() +  Calendar.TimeRanges.TimeRange atr=from->calendar()    ->Second("unix_r",(shift[0]-2440588)*86400+shift[1],    from->ruleset());    if (atr>=from) return atr;    }    }    else    {    foreach (reverse(per[1..]),array shift)    if (shift[0]<=jd)    { -  .TimeRanges.TimeRange atr=from->calendar() +  Calendar.TimeRanges.TimeRange atr=from->calendar()    ->Second("unix_r",(shift[0]-2440588)*86400+shift[1],    from->ruleset());    if (atr<=from) return atr;    }    }    [y,yjd,leap_year]=gregorian_year(y+direction);    }       return 0;    }   }