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

version» Context lines:

pike.git/lib/modules/Calendar.pmod/Time.pmod:1:   //!   //! module Calendar   //! submodule Time   //!   //! Base for time of day in calendars, ie   //! calendars with hours, minutes, seconds   //!   //! This module can't be used by itself, but   //! is inherited by other modules (<ref>ISO</ref> by <ref>YMD</ref>,   //! for instance). + //! + //! inherits TimeRanges      #pike __REAL_VERSION__      // #pragma strict_types      //- these classes majorly works on seconds   //- an hour is 3600 seconds, a minute is 60 seconds    - import "."; - inherit TimeRanges:TimeRanges; + inherit Calendar.TimeRanges:TimeRanges;      #include "constants.h"      // from inherited module      function(mixed...:TimeRange) Day;    - // sanity check + Calendar.Rule.Timezone Timezone_UTC= +  Calendar.Rule.Timezone(0,"UTC"); // needed for dumping    - static private int __sanity_check=lambda() - { -  if (5000000000!=5*inano) -  error("Calendar.Time needs bignums (Gmp.mpz)\n"); -  return 1; - }(); -  - Ruleset.Timezone Timezone_UTC=Ruleset.Timezone(0,"UTC"); // needed for dumping -  +    string calendar_name() { return "Time"; }      //------------------------------------------------------------------------ - //! class TimeOfDay + //! class TimeofDay + //! Virtual class used by e.g. Hour.   //------------------------------------------------------------------------      class TimeofDay   {   //! inherits TimeRange    inherit TimeRange;       constant is_timeofday=1;       TimeRange base; // base day
pike.git/lib/modules/Calendar.pmod/Time.pmod:65:   //! a time of day can also be constructed with unixtime   //! as single argument consisting of the unix time   //! - as returned from <tt>time(2)</tt> - of the time unit start.   //!   //! It can also be constructed without argument, which   //! then means "now", as in "this minute".      //- for internal use:   //- method void create("timeofday",rules,unixtime,len)    -  void create(mixed ...args) +  protected void create(mixed ...args)    {    if (!sizeof(args))    {    rules=default_rules;    create_now();    return;    }    switch (args[0])    {    case "timeofday": -  rules=[object(Ruleset)]args[1]; +  rules=[object(Calendar.Ruleset)]args[1];    ux=[int]args[2];    len=[int]args[3];    ls=CALUNKNOWN;    return;       case "timeofday_sd": -  rules=[object(Ruleset)]args[1]; +  rules=[object(Calendar.Ruleset)]args[1];    ux=[int]args[2];    len=[int]args[3];    ls=[int]args[4];    utco=[int]args[5];    return;       default:    if (intp(args[0]) && sizeof(args)==1)    {    rules=default_rules;    create_unixtime_default([int]args[0]);    return;    }    }    rules=default_rules;    if (create_backtry(@args)) return;    ::create(@args);    }    -  static int(0..1) create_backtry(mixed ...args) +  protected int(0..1) create_backtry(mixed ...args)    {    if (sizeof(args)>1 && objectp(args[0]))    {    base=args[0];    rules=base->ruleset();    args=args[1..];    }    if (base)    {    switch (sizeof(args))
pike.git/lib/modules/Calendar.pmod/Time.pmod:141:    return 0;    }       void create_unixtime(int unixtime,int _len)    {    ux=unixtime;    len=_len;    ls=CALUNKNOWN;    }    -  static void create_now(); +  protected void create_now();       void create_julian_day(int|float jd)    {   // 1970-01-01 is julian day 2440588    jd-=2440588;    float fjd=(jd-(int)jd)-0.5; -  ux=((int)jd)*86400+(int)(fjd*86400); +     ls=CALUNKNOWN; -  +  create_unixtime_default(((int)jd)*86400+(int)(fjd*86400));    }      // make base   // needed in ymd   /*static*/ TimeRange make_base()    {    base=Day("unix_r",ux,rules);    if (len) base=base->range(Day("unix_r",ux+len,rules));   // werror("make base -> %O\n",base);    return base;    }      // make local second -  static void make_local() +  protected void make_local()    {    if (!base) make_base();       ls=ux-base->unix_time();    if (rules->timezone->is_dst_timezone)    {    if (utco==CALUNKNOWN)    [utco,tzn]=rules->timezone->tz_ux(ux);    if (utco!=base->utc_offset())    ls+=base->utc_offset()-utco;    }    }    -  +  TimeRange `*(int|float n) +  { +  if(intp(n)) +  return set_size(n,this); +  else +  return second()*(int)(how_many(Second)*n); +  } +  +  array(TimeRange) split(int|float n, void|function|TimeRange with) +  { +  if(!with) +  with=Second; +  if (functionp(with)) with=promote_program(with); +  float length=how_many(with)/(float)n; +  TimeRange start=beginning(); +  TimeRange end=end(); +  array result=({}); +  while(start+with*length < end) +  { +  result += ({ start->distance(start+with*length) }); +  start=start+with*length; +  } +  result += ({ start->distance(end) }); +  return result; +  } +    // default autopromote -  TimeRange autopromote() +  this_program autopromote()    { -  return this_object(); +  return this;    }       array(int(-1..1)) _compare(TimeRange with)    {   #define CMP(A,B) ( ((A)<(B))?-1:((A)>(B))?1:0 )    -  +  if (!objectp(with)) +  error("_compare: illegal argument 1, expected TimeRange: %O\n",with); +     if (with->is_timeofday_f)    { -  array(int(-1..1)) cmp=with->_compare(this_object()); +  array(int(-1..1)) cmp=with->_compare(this);       return ({-cmp[0],    -cmp[2],    -cmp[1],    -cmp[3]});    }    else if (with->is_timeofday)    return ({ CMP(ux,with->ux),CMP(ux,with->ux+with->len),    CMP(ux+len,with->ux),CMP(ux+len,with->ux+with->len) });    else if (with->is_supertimerange ||
pike.git/lib/modules/Calendar.pmod/Time.pmod:212:    return ::_compare(with);    else    {    int e2=with->end()->unix_time();    int b2=with->unix_time();       return ({ CMP(ux,b2),CMP(ux,e2),CMP(ux+len,b2),CMP(ux+len,e2) });    }    }    -  cSecond beginning() +  TimeRange beginning()    {    return Second("timeofday_sd",rules,ux,0,ls,utco)->autopromote();    }    -  cSecond end() +  TimeRange end()    {    return Second("timeofday",rules,ux+len,0)->autopromote();    }       TimeRange distance(TimeRange to)    {    if (to->is_ymd)    return distance(to->hour());       if (!to->is_timeofday)    error("distance: incompatible class %O\n",    object_program(to));       if (to->is_timeofday_f)    return    Fraction("timeofday_f",rules,ux,0,len,0)    ->distance(to);       int m;    if ( (m=to->unix_time()-unix_time())<0) -  error("Negative distance %O .. %O\n", this_object(),to); +  error("Negative distance %O .. %O\n", this,to);       return    Second("timeofday_sd",rules,ux,m,ls,utco)    ->autopromote();    }       TimeRange range(TimeRange to)    {    if (to->is_timeofday_f)    {
pike.git/lib/modules/Calendar.pmod/Time.pmod:262:    {    int m;    if ( (m=to->unix_time()+to->len-unix_time())<0 )    error("Negative range\n");    return Second("timeofday_sd",rules,ux,m,ls,utco)    ->autopromote();    }    return ::range(to);    }    -  static void convert_from(TimeRange other) +  protected void convert_from(TimeRange other)    {    ::convert_from(other);    if (other->is_timeofday)    len=other->len;    else if (other->number_of_seconds)    len=other->number_of_seconds();    else if (other->number_of_days)    len=86400*other->number_of_days(); // chance    else    len=0; // *shrug*
pike.git/lib/modules/Calendar.pmod/Time.pmod:285:    TimeRange _set_size(int n,TimeRange t)    {    if (!t->is_timeofday)    return distance(add(n,t));       return Second("timeofday_sd",rules,ux,n*(t->len),ls,utco)->autopromote();    }       TimeRange _move(int n,int m);    -  TimeRange _add(int n,TimeRange step) +  TimeRange _add(float|int n,TimeRange step)    {    if (step->is_timeofday_f)    return Fraction("timeofday_f",rules,ux,0,len,0)    ->add(n,step);    if (step->is_timeofday)    return _move(n,step->number_of_seconds());       if (!base) make_base(); -  return base->add(n,step)->place(this_object(),1); +  return base->add(n,step)->place(this,1);    }      //! method Hour hour()   //! method Hour hour(int n)   //! method array(Hour) hours()   //! method array(Hour) hours(int first,int last)   //! method int number_of_hours()   //! <ref>hour</ref>() gives back the timerange representing the   //! first or <i>n</i>th Hour of the called object.   //! Note that hours normally starts to count at zero,
pike.git/lib/modules/Calendar.pmod/Time.pmod:445:    {    int len=number_of_seconds();    if (!n || (n==-1 && !len))    return Second("timeofday",rules,ux,1);    if (n<0) n=len+n;    if (n<0 || n>=len)    error("second not in timerange (second 0..%d exist)\n",len);    return Second("timeofday",rules,ux+n,1)->autopromote();    }    -  static array(TimeRange) get_timeofday(string unit, +  protected array(TimeRange) get_timeofday(string unit,    int start,int step,program p,    int ... range)    {    int from=0,n=::`[]("number_of_"+unit)(),to=n-1;       if (sizeof(range))    if (sizeof(range)<2)    error("Illegal numbers of arguments to "+unit+"()\n");    else    {
pike.git/lib/modules/Calendar.pmod/Time.pmod:639:    {    if (ls==CALUNKNOWN) make_local();    return ls%60;    }       float fraction_no()    {    return 0.0;    }    - //! function mapping datetime() + //! method mapping datetime()   //! This gives back a mapping with the relevant   //! time information (representing the start of the period);   //! <pre>   //! ([ "year": int // year number (2000 AD=2000, 1 BC==0)   //! "month": int(1..) // month of year   //! "day": int(1..) // day of month   //! "yearday": int(1..) // day of year   //! "week": int(1..) // week of year   //! "week_day": int(1..) // day of week (depending on calendar)   //!
pike.git/lib/modules/Calendar.pmod/Time.pmod:691:   //! method string format_ymd_xshort();   //! method string format_iso_week();   //! method string format_iso_week_short();   //! method string format_week();   //! method string format_week_short();   //! method string format_month();   //! method string format_month_short();   //! method string format_iso_time();   //! method string format_time();   //! method string format_time_short(); + //! method string format_iso_short();   //! method string format_time_xshort();   //! method string format_mtime();   //! method string format_xtime();   //! method string format_tod();   //! method string format_xtod();   //! method string format_mod();   //! method string format_nice();   //! method string format_nicez();   //! Format the object into nice strings;   //! <pre>
pike.git/lib/modules/Calendar.pmod/Time.pmod:719:   //! week_short "2000w22" [2]   //! month "2000-06"   //! month_short "200006" [1]   //! iso_time "2000-06-02 (Jun) -W22-5 (Fri) 20:53:14 UTC+1" [2]   //! ext_time "Friday, 2 June 2000, 20:53:14" [2]   //! ctime "Fri Jun 4 20:53:14 2000\n" [2] [3]   //! http "Fri, 02 Jun 2000 19:53:14 GMT" [4]   //! time "2000-06-02 20:53:14"   //! time_short "20000602 20:53:14"   //! time_xshort "000602 20:53:14" + //! iso_short "20000602T20:53:14"   //! mtime "2000-06-02 20:53"   //! xtime "2000-06-02 20:53:14.000000"   //! todz "20:53:14 CET"   //! todz_iso "20:53:14 UTC+1"   //! tod "20:53:14"   //! tod_short "205314"   //! xtod "20:53:14.000000"   //! mod "20:53"   //! nice "2 Jun 20:53", "2 Jun 2000 20:53:14" [2][5]   //! nicez "2 Jun 20:53 CET" [2][5]   //! smtp "Fri, 2 Jun 2000 20:53:14 +0100" [6] -  + //! commonlog "02/Jun/2000:20:53:14 +0100" [2]   //! </pre>   //! <tt>[1]</tt> note conflict (think 1 February 2003)   //! <br><tt>[2]</tt> language dependent   //! <br><tt>[3]</tt> as from the libc function ctime()   //! <br><tt>[4]</tt> as specified by the HTTP standard;   //! this is always in GMT, ie, UTC. The timezone calculations   //! needed will be executed implicitly. It is not language   //! dependent.   //! <br><tt>[5]</tt> adaptive to type and with special cases   //! for yesterday, tomorrow and other years
pike.git/lib/modules/Calendar.pmod/Time.pmod:758:    string format_iso_week_short();    string format_week();    string format_week_short();    string format_month();    string format_month_short();       string format_nice();       string format_iso_time()    { -  return this_object()->format_iso_ymd()+" "+format_todz_iso(); +  return this->format_iso_ymd()+" "+format_todz_iso();    }       string format_ext_time()    { -  return this_object()->format_ext_ymd()+" "+format_tod(); +  return this->format_ext_ymd()+" "+format_tod();    }       string format_time()    { -  return this_object()->format_ymd()+" "+format_tod(); +  return this->format_ymd()+" "+format_tod();    }       string format_time_short()    { -  return this_object()->format_ymd_short()+" "+format_tod(); +  return this->format_ymd_short()+" "+format_tod();    }    -  +  string format_iso_short() +  { +  return this->format_ymd_short()+"T"+format_tod(); +  } +     string format_time_xshort()    { -  return this_object()->format_ymd_xshort()+" "+format_tod(); +  return this->format_ymd_xshort()+" "+format_tod();    }       string format_mtime()    { -  return this_object()->format_ymd()+" "+format_mod(); +  return this->format_ymd()+" "+format_mod();    }       string format_xtime()    { -  return this_object()->format_ymd()+" "+format_xtod(); +  return this->format_ymd()+" "+format_xtod();    }       string format_ctime()    {    if (!base) make_base();    return replace(base->format_ctime(),    "00:00:00",format_tod());    }       string format_http()    {    if (utc_offset())    return set_timezone(Timezone_UTC)->format_http();    if (!base) make_base();       return replace(base->format_http(),    "00:00:00",format_tod());    }    -  +  string format_ext_time_short() +  { +  if (!base) make_base(); +  return replace(base->format_ext_time_short(), +  "00:00:00 GMT",format_todz()); +  } +  +  string format_commonlog() +  { +  if (!base) make_base(); +  return replace(base->format_commonlog(), +  "00:00:00 ",format_tod()+" "); +  } +     string format_tod()    {    if (ls==CALUNKNOWN) make_local();    return sprintf("%02d:%02d:%02d", ls/3600, (ls/60)%60, ls%60);    }       string format_tod_short()    {    if (ls==CALUNKNOWN) make_local();    return sprintf("%02d%02d%02d", ls/3600, (ls/60)%60, ls%60);
pike.git/lib/modules/Calendar.pmod/Time.pmod:866:    string format_nice();    string format_nicez()    {    return format_nice()+" "+tzname();    }       string format_smtp()    {    if (ls==CALUNKNOWN) make_local();    int u=utc_offset(); -  return sprintf("%s, %s %s %s %d:%02d:%02d %+03d%02d", +  return sprintf("%s, %s %s %s %02d:%02d:%02d %+03d%02d",    base->week_day_shortname(),    base->month_day_name(),    base->month_shortname(),    base->year_name(),    ls/3600, (ls/60)%60, ls%60,    -u/3600,max(u,-u)/60%60);    }       string format_elapsed()    {    string res=""; -  object left=this_object(); +  object left=this;    int x; -  if ( (x=(this_object()/Day)) ) +  if ( (x=(this/Day)) )    {    res+=sprintf("%dd",x); -  left=this_object()->add(x,Day)->range(this_object()->end()); +  left=this->add(x,Day)->range(this->end());    }    return sprintf("%s%d:%02d:%02d",    res,left->len/3600,    (left->len/60)%60,    left->len%60);    }      // --------    -  TimeofDay set_ruleset(Ruleset r) +  this_program set_ruleset(Calendar.Ruleset r)    {    return    Second("timeofday",r,ux,len)    ->autopromote();    }       int utc_offset()    {    if (utco==CALUNKNOWN)    return [utco,tzn]=rules->timezone->tz_ux(ux),utco;
pike.git/lib/modules/Calendar.pmod/Time.pmod:932:    return    (u<0)    ?sprintf("UTC+%d:%02d",-u/3600,(-u/60)%60)    :sprintf("UTC-%d:%02d",u/3600,(u/60)%60);    return    (u<0)    ?sprintf("UTC+%d:%02d:%02d",-u/3600,(-u/60)%60,(-u)%60)    :sprintf("UTC-%d:%02d:%02d",u/3600,(u/60)%60,u%60);    }    +  string tzname_utc_offset() +  { +  int u=utc_offset(); +  return sprintf("%+03d%02d", -u/3600, abs(u)/60%60); +  } +  +  string tzname_location() +  { +  string location = rules->timezone->zoneid; +  if (location || tzn) return location || tzn; +  return [utco,tzn]=rules->timezone->tz_ux(ux), tzn; +  } +  + // ----------------------------------------------------------------- +  +  TimeRange place(TimeRange what,void|int force) +  { +  if (!base) make_base(); +  if (what->is_ymd) +  return base->place(what,force); +  +  error("place: Incompatible type %O\n",what); +  } +    // --------    -  + //! method void call_out(function fun,mixed ...args) + //! Creates a call_out to this point in time. +  void call_out(function fun,mixed ...args) +  { +  if (ux-time(1)>10000) +  predef::call_out(call_out,ux-time(1)-100,fun,@args); +  else if (ux-time(1)<0) +  predef::call_out(fun,0,@args); // already +  else +  predef::call_out(fun,-time(ux),@args); +  } +  + // -------- +    // #define TIME_OPERATOR_DEBUG   #ifdef TIME_OPERATOR_DEBUG   #define DEBUG_OVERLOAD_OPERATOR(OP,NAME,IND) \    TimeRange OP(mixed ...args) \    { \    _ind+=IND; \    TimeRange x=::OP(@args); \ -  _ind=_ind[..strlen(_ind)-strlen(IND)-1]; \ -  werror(_ind+" %O\n",this_object()); \ +  _ind=_ind[..<sizeof(IND)]; \ +  werror(_ind+" %O\n",this); \    foreach (args,TimeRange t) werror(_ind+NAME+" %O\n",t); \    werror(_ind+"= %O\n",x); \    return x; \    }    DEBUG_OVERLOAD_OPERATOR(`&,"&","| ");    DEBUG_OVERLOAD_OPERATOR(`^,"^","| ");    DEBUG_OVERLOAD_OPERATOR(`|,"|","| ");    DEBUG_OVERLOAD_OPERATOR(subtract,"-","| ");   #endif   }
pike.git/lib/modules/Calendar.pmod/Time.pmod:1024:    array(cMinute) minutes(int ...range) { return get_units("minutes",@range); }    cMinute minute(void|int n) { return get_unit("minutes",n); }    int number_of_minutes() { return num_units("minutes"); }       array(cSecond) seconds(int ...range) { return get_units("seconds",@range); }    cSecond second(void|int n) { return get_unit("seconds",n); }    int number_of_seconds() { return num_units("seconds"); }      // wrapper methods to calculate units in a supertimerange    -  static array(TimeRange) get_units(string unit,int ... range) +  protected array(TimeRange) get_units(string unit,int ... range)    {    int from=0,to=0x7fffffff,pos=0;    array res=({});    TimeRange last=0; -  string ums=unit[..strlen(unit)-2]; // no 's' +  string ums=unit[..<1]; // no 's'       if (sizeof(range)==2)    [from,to]=range;    else if (sizeof(range)==1)    error("Illegal numbers of arguments to "+unit+"()\n");       foreach (parts,TimeRange part)    {    if (pos>=from)    {
pike.git/lib/modules/Calendar.pmod/Time.pmod:1061:    if (l==last) n--;    if (n+pos>from)    res=part[unit](from-pos,to-pos);    pos+=n;    last=l;    }    }    return res;    }    -  static int num_units(string unit) +  protected int num_units(string unit)    {    int pos=0;    TimeRange last=0; -  string ums=unit[..strlen(unit)-2]; // no 's' +  string ums=unit[..<1]; // no 's'       foreach (parts,TimeRange part)    {    int n=part["number_of_"+unit]();    TimeRange l=part[ums]();    if (l==last) n--;    pos+=n;    last=l;    }    return pos;    }    -  static TimeRange get_unit(string unit,int n) +  protected TimeRange get_unit(string unit,int n)    {    array(TimeRange) res=get_units(unit,n,n);    if (sizeof(res)==1) return res[0];    error("not in range ("+unit+" 0..%d exist)\n",    num_units(unit)-1);    }      #define RBASE parts[0]       string format_ext_ymd();
pike.git/lib/modules/Calendar.pmod/Time.pmod:1102:    string format_ymd_xshort();    string format_iso_week();    string format_iso_week_short();    string format_week();    string format_week_short();    string format_month();    string format_month_short();       string format_iso_time() { return RBASE->format_iso_time(); }    string format_ext_time() { return RBASE->format_ext_time(); } +  string format_ext_time_short() { return RBASE->format_ext_time_short(); }    string format_time() { return RBASE->format_time(); }    string format_time_short() { return RBASE->format_time_short(); }    string format_time_xshort() { return RBASE->format_time_xshort(); }    string format_mtime() { return RBASE->format_mtime(); }    string format_xtime() { return RBASE->format_xtime(); }    string format_ctime() { return RBASE->format_ctime(); }    string format_http() { return RBASE->format_http(); }    string format_tod() { return RBASE->format_tod(); }    string format_todz() { return RBASE->format_todz(); }    string format_todz_iso() { return RBASE->format_todz_iso(); }
pike.git/lib/modules/Calendar.pmod/Time.pmod:1128:      #undef RBASE      // count parts elapsed    string format_elapsed()    {    TimeRange z=parts[0];    foreach (parts,TimeRange y) z+=y;    return parts[0]->distance(z)->format_elapsed();    } +  +  protected string _sprintf(int t,mapping m) +  { +  if (t=='t') +  return "Calendar."+calendar_name()+".TimeofDay"; +  return ::_sprintf(t,m);    } -  + }      class cNullTimeRange   {    inherit TimeRanges::cNullTimeRange;       array(cHour) hours(int ...range) { return ({}); }    cHour hour(void|int n) { error("no hours in nulltimerange\n"); }    int number_of_hours() { return 0; }       array(cMinute) minutes(int ...range) { return ({}); }
pike.git/lib/modules/Calendar.pmod/Time.pmod:1162:      function(mixed...:cHour) Hour=cHour; // inheritance purposes   class cHour   {    constant is_hour=1;      //! inherits TimeofDay       inherit TimeofDay;    +  protected int __hash() { return ux/(60*60); } +     void create_unixtime_default(int unixtime)    {    create_unixtime(unixtime,3600);    }    -  static void create_now() +  protected void create_now()    {    create_unixtime(time(),3600);    }    -  static void create_julian_day(int|float jd) +  protected void create_unixtime(int _ux,int _len)    { -  +  ::create_unixtime(_ux,_len); +  if (ls==CALUNKNOWN) make_local(); +  if (ls%3600) ux-=ls%3600,ls=CALUNKNOWN; +  } +  +  protected void create_julian_day(int|float jd) +  {    ::create_julian_day(jd);    len=3600;    }    -  static void convert_from(TimeRange other) +  protected void convert_from(TimeRange other)    {    ::convert_from(other);    len-=len%3600;    }       TimeofDay _move(int n,int m)    { -  if (m==0 || n==0) return this_object(); +  if (m==0 || n==0) return this;    if (m%3600)    return Second("timeofday",rules,ux,len)->_move(n,m);    return Hour("timeofday",rules,ux+n*m,len)->autopromote();    }       -  string _sprintf(int t) +  protected string _sprintf(int t,mapping m)    {    if (catch {    switch (t)    {    case 'O':    if (!base) make_base();    if (len!=3600)    return sprintf("Hour(%s)",    nice_print_period());    return sprintf("Hour(%s %s)",    base->nice_print(),    nice_print()); -  +  case 't': +  return "Calendar."+calendar_name()+".Hour";    default: -  return 0; +  return ::_sprintf(t,m);    }    })    return "error";    }       string nice_print()    {    if (ls==CALUNKNOWN) make_local();    return sprintf("%d:00 %s",ls/3600,tzname());    }       string format_nice()    {    if (ls==CALUNKNOWN) make_local();    if (!base) make_base();    return base->format_nice()+" "+sprintf("%d:00",ls/3600);    } -  +  + // ----------------------------------------------------------------- +  +  TimeRange place(TimeRange what,void|int force) +  { +  if (what->is_hour) +  return Hour("timeofday",rules,ux,what->len); +  if (what->is_minute) +  return minute()+(what->hour()->distance(what))->number_of_minutes(); +  if (what->is_fraction) +  { +  TimeRange t=what->hour()->distance(what); +  int s=t->len_s; +  int ns=t->len_ns; +  return +  Fraction("timeofday_f",rules,ux,0,what->len_s,what->len_s) +  ->_move(1,s,ns);    } -  +  if (what->is_second) +  return second()+(what->hour()->distance(what))->number_of_seconds();    -  +  ::place(what,force); +  } + } +    //------------------------------------------------------------------------   //! class Minute   //------------------------------------------------------------------------      function(mixed...:cMinute) Minute=cMinute; // inheritance purposes   class cMinute   {    constant is_minute=1;      //! inherits TimeofDay       inherit TimeofDay;    -  +  protected int __hash() { return ux/60; } +  +  protected void create_unixtime(int _ux,int _len) +  { +  ::create_unixtime(_ux,_len); +  if (ls==CALUNKNOWN) make_local(); +  ux-=ls%60; +  } +     void create_unixtime_default(int unixtime)    {    create_unixtime(unixtime,60);    }    -  static void create_now() +  protected void create_now()    {    create_unixtime(time()/60*60,60);    }       TimeofDay autopromote()    {    if (ls==CALUNKNOWN) make_local();    if (!(ls%3600) && !(len%3600))    return Hour("timeofday_sd",rules,ux,len,ls,utco)->autopromote();    return ::autopromote();    }    -  static void convert_from(TimeRange other) +  protected void convert_from(TimeRange other)    {    ::convert_from(other);    len-=len%60;    }       TimeofDay _move(int n,int m)    { -  if (m==0 || n==0) return this_object(); +  if (m==0 || n==0) return this;    if (m%60) return Second("timeofday",rules,ux,len)->_move(n,m);    return Minute("timeofday",rules,ux+n*m,len)->autopromote();    }    -  string _sprintf(int t) +  protected string _sprintf(int t,mapping m)    {    switch (t)    {    case 'O':    if (!base) make_base();    if (len!=60)    return sprintf("Minute(%s)",    nice_print_period());    return sprintf("Minute(%s %s)",    base->nice_print(),    nice_print()); -  +  case 't': +  return "Calendar."+calendar_name()+".Minute";    default: -  return 0; +  return ::_sprintf(t,m);    }    }       string nice_print()    {    if (ls==CALUNKNOWN) make_local();    return sprintf("%d:%02d %s",ls/3600,(ls/60)%60,tzname());    }       string format_nice()    {    if (ls==CALUNKNOWN) make_local();    if (!base) make_base();    return base->format_nice()+" "+sprintf("%d:%02d",ls/3600,(ls/60)%60);    } -  +  +  TimeRange place(TimeRange what,void|int force) +  { +  if (what->is_hour) +  return hour()->place(what); +  if (what->is_minute) +  return Minute("timeofday",rules,ux,what->len); +  if (what->is_fraction) +  { +  TimeRange t=what->minute()->distance(what); +  int s=t->len_s; +  int ns=t->len_ns; +  return +  Fraction("timeofday_f",rules,ux,0,what->len_s,what->len_s) +  ->_move(1,s,ns);    } -  +  if (what->is_second) +  return second()+(what->minute()->distance(what))->number_of_seconds();    -  +  ::place(what,force); +  } + } +    //------------------------------------------------------------------------   //! class Second   //------------------------------------------------------------------------      function(mixed...:cSecond) Second=cSecond; // inheritance purposes   class cSecond   {    constant is_second=1;      //! inherits TimeofDay       inherit TimeofDay;    -  +  protected int __hash() { return ux; } +     void create_unixtime_default(int unixtime)    {    create_unixtime(unixtime,1);    }    -  static void create_now() +  protected void create_now()    {    create_unixtime(time(),1);    }    -  static void create_julian_day(int|float jd) +  protected void create_julian_day(int|float jd)    {    ::create_julian_day(jd);    len=1;    }       TimeofDay autopromote()    {    if (ls==CALUNKNOWN) make_local();    if (!(ls%60) && !(len%60))    return Minute("timeofday",rules,ux,len)->autopromote();    return ::autopromote();    }       TimeofDay _move(int n,int m)    { -  if (m==0 || n==0) return this_object(); +  if (m==0 || n==0) return this;    return Second("timeofday",rules,ux+n*m,len)->autopromote();    }    -  string _sprintf(int t) +  protected string _sprintf(int t,mapping m)    {    switch (t)    {    case 'O':    if (len!=1)    return sprintf("Second(%s)",    nice_print_period());    if (!base) make_base();    return sprintf("Second(%s %s)",    base->nice_print(),    nice_print()); -  +  case 't': +  return "Calendar."+calendar_name()+".Second";    default: -  return 0; +  return ::_sprintf(t,m);    }    }       string nice_print()    {    if (ls==CALUNKNOWN) make_local(); -  return sprintf("%d:%02d:%02d %s",ls/3600,ls/60%60,ls%60,tzname()); +  return sprintf("%d:%02d:%02d %s",ls/3600,ls/60%60,ls%60,tzname()||"?");    }       string format_nice()    {    if (ls==CALUNKNOWN) make_local();    if (!base) make_base();    return base->format_nice()+" "+    sprintf("%d:%02d:%02d",ls/3600,ls/60%60,ls%60);    }      // backwards compatible with calendar I    string iso_name() -  { return this_object()->format_ymd()+" T"+format_tod(); } +  { return this->format_ymd()+"T"+format_tod(); }    string iso_short_name() -  { return this_object()->format_ymd_short()+" T"+(format_tod()-":"); } +  { return this->format_ymd_short()+"T"+(format_tod()-":"); } +  +  +  TimeRange place(TimeRange what,void|int force) +  { +  if (what->is_hour) +  return hour()->place(what); +  if (what->is_minute) +  return minute()->place(what); +  if (what->is_fraction) +  { +  TimeRange t=what->second()->distance(what); +  int s=t->len_s; +  int ns=t->len_ns; +  return +  Fraction("timeofday_f",rules,ux,0,what->len_s,what->len_s) +  ->_move(1,s,ns);    } -  +  if (what->is_second) +  return second()+(what->second()->distance(what))->number_of_seconds();    -  +  ::place(what,force); +  } + } +    //------------------------------------------------------------------------   //! class Fraction   //! A Fraction is a part of a second, and/or a time period   //! with higher resolution then a second.   //!   //! It contains everything that is possible to do with a   //! <ref>Second</ref>, and also some methods of grabbing   //! the time period with higher resolution.   //!   //! note:   //! Internally, the fraction time period is measured in   //! nanoseconds. A shorter or more precise time period then   //! in nanoseconds is not possible within the current Fraction class.   //! - //! inherits TimeofDay + //! inherits Second   //------------------------------------------------------------------------      function(mixed...:cFraction) Fraction=cFraction;   class cFraction   {    inherit cSecond;       constant is_timeofday_f=1;    constant is_fraction=1;       int ns; // nanoseconds add to s    int len_ns; // nanoseconds length    int len_s; // seconds length      //! method void create() - //! method void create("unixtime",int|float unixtime) - //! method void create("unixtime",int|float unixtime,int|float len) - //! It is possible to create a Fraction in two ways, + //! method void create("unix",int|float unixtime) + //! method void create("unix",int|float unixtime,int|float len) + //! method void create(int y,int m,int d,int h,int m,int s,int ns) + //! It is possible to create a Fraction in three ways,   //! either "now" with no arguments or - //! from a unix time (as from <tt>time(2)</tt>). + //! from a unix time (as from <tt>time(2)</tt>), + //! or the convenience way from ymd-hms integers.   //!   //! If created from unix time, both the start of the period   //! and the size of the period can be given in floats,   //! both representing seconds. Note that the default   //! float precision in pike is rather low (same as 'float' in C,   //! the 32 bit floating point precision, normally about 7 digits),   //! so beware that the resolution might bite you. (Internally   //! in a Fraction, the representation is an integer.)   //!   //! If created without explicit length, the fraction will always be   //! of zero length.    -  void create(mixed ...args) +  protected void create(mixed ...args)    {    if (!sizeof(args))    {    rules=default_rules;    create_now();    return;    }    else if (args[0]=="timeofday_f")    { -  rules=[object(Ruleset)]args[1]; +  rules=[object(Calendar.Ruleset)]args[1];    ux=[int]args[2];    ns=[int]args[3];    len_s=[int]args[4];    len_ns=[int]args[5];    ls=CALUNKNOWN;       if (ns<0) -  error("Can't create negative ns: %O\n",this_object()); +  error("Can't create negative ns: %O\n",this);       if (!rules) error("no rules\n");       if (len_ns>=inano) len_s+=(len_ns/inano),len_ns%=inano;    if (ns>=inano) ux+=(ns/inano),ns%=inano;    len=len_s+(ns+len_ns+inano-1)/inano;       if (ns<0) -  error("Can't create negative ns: %O\n",this_object()); +  error("Can't create negative ns: %O\n",this);       return;    }    else if (intp(args[0]) && sizeof(args)==1)    {    rules=default_rules;    create_unixtime(args[0]);    return;    }    else switch (args[0])    { -  +  case "timeofday": +  rules=[object(Calendar.Ruleset)]args[1]; +  ux=[int]args[2]; +  len=[int]args[3]; +  ls=CALUNKNOWN; +  ns=[int]args[4]; +  return;    case "unix":    rules=default_rules;    create_unixtime(@args[1..]);    return;    case "julian":    rules=default_rules;    create_julian_day(args[1]);    return;    case "unix_r":    rules=args[-1]; -  create_unixtime(@args[..sizeof(args)-2]); +  create_unixtime(@args[..<1]);    return;    case "julian_r":    rules=args[2];    create_julian_day(args[1]);    return;    }    rules=default_rules;    if (create_backtry(@args)) return;    error("Fraction: illegal argument(s) %O,%O,%O,...\n",    @args,0,0,0);
pike.git/lib/modules/Calendar.pmod/Time.pmod:1527:    ux=base->second(args[0],args[1],(int)args[2])->unix_time();    ns=(int)(inano*(args[3]-(int)args[3]));    return 1;    }    break;    }    }    return ::create_backtry(@args);    }    -  static void create_now() +  protected void create_now()    {    ux=time();    ns=(int)(inano*time(ux));    if (ns>=inano) ux+=(ns/inano),ns%=inano;    len=len_s=len_ns=0;    ls=CALUNKNOWN;    }       int unix_time() { return ux; }    float f_unix_time() { return ux+ns*(1.0/inano); }    -  static void create_unixtime(int|float unixtime, +  protected void create_unixtime(int|float unixtime,    void|int|float _len)    {    ux=(int)unixtime;    ns=(int)(inano*(unixtime-(int)unixtime));    len_s=(int)_len;    len_ns=(int)(inano*(_len-(int)_len));    ls=CALUNKNOWN;    }    -  static void create_unixtime_default(int|float unixtime) +  protected void create_unixtime_default(int|float unixtime)    {    create_unixtime(unixtime);    }       float julian_day()    {    return 2440588+(ux+ns*(1.0/inano))*(1/86400.0)+0.5;    }    -  static void create_julian_day(int|float jd) +  protected void create_julian_day(int|float jd)    {   // 1970-01-01 is julian day 2440588    jd-=2440588;    float fjd=((jd-(int)jd)+0.5)*86400;    ux=((int)jd)*86400+(int)(fjd);    ns=(int)(inano*(fjd-(int)fjd));       ls=CALUNKNOWN;    }    -  string _sprintf(int t) +  protected string _sprintf(int t,mapping m)    {    switch (t)    {    case 'O':    if (!base) make_base();    if (len_ns || len_s)    return sprintf("Fraction(%s)",    nice_print_period());    return sprintf("Fraction(%s %s)",    base->nice_print(),    nice_print()); -  +  case 't': +  return "Calendar."+calendar_name()+".Fraction";    default: -  return 0; +  return ::_sprintf(t,m);    }    }    -  int __hash() { return ux; } +  protected int __hash() { return ux; }       string nice_print()    {    if (ls==CALUNKNOWN) make_local();    return sprintf("%d:%02d:%02d.%06d %s",    ls/3600,ls/60%60,ls%60,ns/1000,tzname());    }       string format_nice()    {
pike.git/lib/modules/Calendar.pmod/Time.pmod:1610:    return base->format_nice()+" "+    sprintf("%d:%02d:%02d.%06d",    ls/3600,ls/60%60,ls%60,ns/1000);    }       TimeofDay autopromote()    {    if (!ns && !len_ns)    return Second("timeofday",rules,ux,len_s)->autopromote();    -  return this_object(); +  return this;    }    -  +  this_program set_ruleset(Calendar.Ruleset r) +  { +  return +  Fraction("timeofday",r,ux,len,ns) +  ->autopromote(); +  } +     TimeofDay _move(int n,int z_s,void|int z_ns)    {    if ((z_s==0 && z_ns==0) || n==0) return autopromote();    int nns=ns+n*z_ns;    int nux=ux+n*z_s;    if (nns<0 || nns>=inano) nux+=nns/inano,nns%=inano;    return Fraction("timeofday_f",rules,nux,nns,len_s,len_ns)    ->autopromote();    }       TimeRange _add(int n,TimeRange step)    {    if (step->is_timeofday_f)    return _move(n,step->len_s,step->len_ns);    return ::_add(n,step);    }    -  static void convert_from(TimeRange other) +  protected void convert_from(TimeRange other)    {    ::convert_from(other);    if (other->is_timeofday_f)    {    ns=other->ns;    len_s=other->len_s;    len_ns=other->len_ns;    }    }    -  static TimeRange _set_size(int n,TimeRange t) +  protected TimeRange _set_size(int n,TimeRange t)    {    if (t->is_timeofday_f)    return Fraction("timeofday_f",rules,ux,ns,    n*t->len_s,n*t->len_ns)    ->autopromote();       if (t->is_timeofday)    return Fraction("timeofday_f",rules,ux,ns,n*t->len,0)    ->autopromote();   
pike.git/lib/modules/Calendar.pmod/Time.pmod:1671:       if (to->is_timeofday)    s2=to->ux;    else    s2=to->unix_time();      // ns is 0 in an object that doesn't have ns       if (s2<s1 ||    (s2==s1 && to->ns<ns)) -  error("Negative distance %O .. %O\n", this_object(),to); +  error("Negative distance %O .. %O\n", this,to);       return    Fraction("timeofday_f",rules,ux,ns,s2-s1-1,to->ns-ns+inano)    ->autopromote();    }       TimeRange range(TimeRange to)    {    return distance(to->end());    }
pike.git/lib/modules/Calendar.pmod/Time.pmod:1707:    else if (with->is_timeofday)    return ({ CMP2(ux,ns,with->ux,0),    CMP2(ux,ns,with->ux+with->len,0),    CMP2(ux+len_s,ns+len_ns,with->ux,0),    CMP2(ux+len_s,ns+len_ns,with->ux+with->len, 0) });    return ::_compare(with);    }       TimeofDay beginning()    { -  if (len_s==0.0 && len_ns==0.0) return this_object(); +  if (len_s==0.0 && len_ns==0.0) return this;    return Fraction("timeofday_f",rules,ux,ns,0,0)    ->autopromote();    }       TimeofDay end()    { -  if (len_s==0 && len_ns==0) return this_object(); +  if (len_s==0 && len_ns==0) return this;    object q=Fraction("timeofday_f",rules,ux+len_s,ns+len_ns,0,0)    ->autopromote();    return q;    }       TimeRange set_size_seconds(int seconds)    {    if (seconds<0) error("Negative size\n");    return Fraction("timeofday_f",rules,ux,ns,seconds,0)    ->autopromote();
pike.git/lib/modules/Calendar.pmod/Time.pmod:1770:    from=(float)range[0],to=(float)range[1];    else if (sizeof(range)==0)    from=0.0,to=n;    else    error("Illegal arguments\n");    if (from<0.0) from=0.0;    if (to>n) to=n;    if (to<from)    return ({});    -  if (from==0.0 && to==n) return ({this_object()}); +  if (from==0.0 && to==n) return ({this});       to-=from;    return ({Fraction("timeofday_f",rules,    ux+(int)from,ns+(int)(inano*(from-(int)from)),    (int)to,(int)(inano*(to-(int)to)))});    }       mapping datetime()    {    return ::datetime()|(["fraction":ns*(1.0/inano)]);
pike.git/lib/modules/Calendar.pmod/Time.pmod:1796:    return sprintf("%02d:%02d:%02d.%06d",    ls/3600,    (ls/60)%60,    ls%60,    ns/1000);    }       string format_elapsed()    {    int x; -  if ( (x=(this_object()/Day)) ) +  if ( (x=(this/Day)) )    { -  object left=this_object()->add(x,Day)->range(this_object()->end()); +  object left=this->add(x,Day)->range(this->end());    return sprintf("%dd%d:%02d:%02d.%03d",    x,left->len_s/3600,    (left->len_s/60)%60,    left->len_s%60,    left->len_ns/1000000);    }    if (len_s>=3600)    return sprintf("%d:%02d:%02d.%03d",    len_s/3600,(len_s/60)%60,    len_s%60,len_ns/1000000);    if (len_s>=60)    return sprintf("%d:%02d.%03d",    len_s/60,len_s%60,len_ns/1000000);    if (len_s || len_ns>inano/1000)    return sprintf("%d.%06d",    len_s,len_ns/1000);    return sprintf("0.%09d",len_ns);    } -  +  +  float fraction_no() +  { +  return ns / 1e9;    }    -  +  void call_out(function fun,mixed ...args) +  { +  if (ux-time(1)>10000) +  predef::call_out(call_out,ux-time(1)-100,fun,@args); +  else if (ux-time(1)<0) +  predef::call_out(fun,0,@args); // already +  else +  predef::call_out(fun,-time(ux)+ns*1e-9,@args); +  } + } +    //------------------------------------------------------------------------   // global convinience functions   //------------------------------------------------------------------------      //! method TimeofDay now()   //! Give the zero-length time period of the   //! current time.      TimeofDay now()   {
pike.git/lib/modules/Calendar.pmod/Time.pmod:1847:   //! as the called calendar but with another set of rules.   //!   //! Example:   //! <pre>   //! &gt; Calendar.now();   //! Result: Fraction(Fri 2 Jun 2000 18:03:22.010300 CET)   //! &gt; Calendar.set_timezone(Calendar.Timezone.UTC)->now();   //! Result: Fraction(Fri 2 Jun 2000 16:03:02.323912 UTC)   //! </pre>    - this_program set_timezone(string|Ruleset.Timezone tz) + this_program set_timezone(string|Calendar.Rule.Timezone tz)   {    return set_ruleset(default_rules->set_timezone(tz));   }    - Ruleset.Timezone timezone() + Calendar.Rule.Timezone timezone()   {    return default_rules->timezone;   }    - this_program set_language(string|Ruleset.Language lang) + this_program set_language(string|Calendar.Rule.Language lang)   {    return set_ruleset(default_rules->set_language(lang));   }    - Ruleset.Language language() + Calendar.Rule.Language language()   {    return default_rules->language;   }      //! method Calendar set_ruleset(Ruleset r)   //! method Ruleset ruleset()   //! Set or read the ruleset for the calendar.   //! <ref>set_ruleset</ref> returns a new calendar object,   //! but with the new ruleset.    - this_program set_ruleset(Ruleset r) + this_program set_ruleset(Calendar.Ruleset r)   { - // "this_program" here ceased to work -  object c=object_program(this_object())(); +  this_program c=this_program();    c->default_rules=r;    return c;   }    - Ruleset ruleset() + Calendar.Ruleset ruleset()   {    return default_rules;   }