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

version» Context lines:

pike.git/lib/modules/Calendar.pmod/YMD.pike:1:   //!   //! module Calendar   //! submodule YMD   //!   //! base for all Roman-kind of Calendars,   //! ie, one with years, months, weeks and days   //! + //! inherits Time      #pike __REAL_VERSION__      // #pragma strict_types      inherit Calendar.Time:Time;      #include "constants.h"      // ----------------
pike.git/lib/modules/Calendar.pmod/YMD.pike:37:   protected string f_week_day_shortname_from_number;   protected string f_week_day_name_from_number;   protected string f_year_name_from_number;   protected string f_year_number_from_name;         protected int(0..1) year_leap_year(int y);      protected int compat_week_day(int n);    + // Polynomial terms for calculating the difference between TDT and UTC. + // + // The polynomials have been taken from NASA: + // @url{http://eclipse.gsfc.nasa.gov/SEhelp/deltatpoly2004.html@} + // + // Each entry is an @expr{array(float)@}: + // @array + // @elem float 0 + // End year for the range. + // @elem float 1 + // Year offset. + // @elem float 2 + // Year divisor. + // @elem float 3.. + // Polynomial factors with the highest exponent first. + // @endarray + protected constant deltat_polynomials = ({ +  ({ -500.0, -1820.0, 100.0, +  -20.0, 0.0, 32.0, }), +  ({ 500.0, 0.0, 100.0, +  0.0090316521, 0.022174192, -0.1798452, +  -5.952053, 33.78311, -1014.41, 10583.6, }), +  ({ 1600.0, -1000.0, 100.0, +  0.0083572073, -0.005050998, -0.8503463, +  0.319781, 71.23472, -556.01, 1574.2, }), +  ({ 1700.0, -1600.0, 1.0, +  0.000140272128, -0.01532, -0.9808, 120.0, }), +  ({ 1800.0, -1700.0, 1.0, +  0.000000851788756, 0.00013336, -0.0059285, 0.1603, 8.83, }), +  ({ 1860.0, -1800.0, 1.0, +  0.000000000875, -0.0000001699, 0.0000121272, -0.00037436, +  0.0041116, 0.0068612, -0.332447, 13.72, }), +  ({ 1900.0, -1860.0, 1.0, +  0.000004288643, -0.0004473624, 0.01680668, -0.251754, 0.5737, 7.62, }), +  ({ 1920.0, -1900.0, 1.0, +  -0.000197, 0.0061966, -0.0598939, 1.494119, -2.79, }), +  ({ 1941.0, -1920.0, 1.0, +  0.0020936, -0.076100, 0.84493, 21.20, }), +  ({ 1961.0, -1950.0, 1.0, +  0.0003926188, 0.0042918455, 0.407, 29.07, }), +  ({ 1986.0, -1975.0, 1.0, +  0.001392758, 0.0038461538, 1.067, 45.45, }), +  ({ 2005.0, -2000.0, 1.0, +  0.00002373599, 0.000651814, 0.0017275, -0.060374, 0.3345, 63.86, }), +  ({ 2050.0, -2000.0, 1.0, +  0.005589, 0.32217, 62.92 }), +  ({ 2150.0, -1820.0, 100.0, +  32.0-185.724, 56.28, -20.0, }), +  ({ Math.inf, -1820.0, 100.0, +  32.0, 0.0, -20.0, }), + }); +  + //! method float deltat(int unadjusted_utc) + //! Terrestrial Dynamical Time difference from standard time. + //! + //! returns + //! An approximation of the difference between TDT and UTC + //! in fractional seconds at the specified time. + //! + //! The zero point is 1901-06-25T14:23:01 UTC + //! (unix time -2162281019), ie the accumulated number + //! of leap seconds since then is returned. + //! + //! note + //! The function is based on polynomials provided by NASA, + //! and the result may differ from actual for dates after 2004. + float deltat(int unadjusted_utc) + { +  // Approximation of the year. This ought to be good enough for +  // most purposes given the uncertainty in the table values. +  // 31556952 == 365.2425 * 24 * 60 * 60. +  float y = 1970.0 + unadjusted_utc/31556952.0; +  +  array(float) polynomial; +  int l, c, h = sizeof(deltat_polynomials); +  do { +  c = (l + h)/2; +  polynomial = deltat_polynomials[c]; +  if (y < polynomial[0]) h = c; +  else l = c + 1; +  } while (l < h); +  float u = (y + polynomial[1])/polynomial[2]; +  +  float deltat = 0.0; +  foreach(polynomial; int i; float factor) { +  if (i < 3) continue; +  deltat = deltat * u + factor; +  } +  return deltat; + } +    //------------------------------------------------------------------------   //! class YMD   //! Base (virtual) time period of the Roman-kind of calendar.   //! inherits TimeRange   //------------------------------------------------------------------------      class YMD   {    inherit TimeRange;   
pike.git/lib/modules/Calendar.pmod/YMD.pike:144:   //! method string week_name()   //! method string year_name()   //! method string tzname()   //! method string tzname_iso()       int julian_day()    {    return jd;    }    - //! function method int unix_time() + //! method int unix_time()   //! Returns the unix time integer corresponding to the start   //! of the time range object. (An unix time integer is UTC.)       int unix_time()    {   // 1970-01-01 is julian day 2440588    int ux=(jd-2440588)*86400;    if (utco==CALUNKNOWN)    [utco,tzn]=rules->timezone->tz_jd(jd);    return ux+utco;
pike.git/lib/modules/Calendar.pmod/YMD.pike:269:    return rules->language[f_week_day_shortname_from_number](wd);    }       int leap_year() { return year_leap_year(year_no()); }       int hour_no() { return 0; }    int minute_no() { return 0; }    int second_no() { return 0; }    float fraction_no() { return 0.0; }    - //! function method 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(0..) // day of year   //! "week": int(1..) // week of year   //! "week_day": int(0..) // day of week   //! "timezone": int // offset to utc, including dst
pike.git/lib/modules/Calendar.pmod/YMD.pike:406:   //! todz "00:00:00 CET"   //! todz_iso "00:00:00 UTC+1"   //! xtod "00:00:00.000000"   //! mod "00:00"   //! </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;   //! not language dependent. + //! + //! The iso variants aim to be compliant with ISO-8601.       string format_iso_ymd()    {    if (m==CALUNKNOWN) make_month();    if (w==CALUNKNOWN) make_week();    return sprintf("%04d-%02d-%02d (%s) -W%02d-%d (%s)",    y,m,md,    month_shortname(),    w,wd, // fixme - what weekday?    week_day_shortname());
pike.git/lib/modules/Calendar.pmod/YMD.pike:1432:    }       cYear set_ruleset(Calendar.Ruleset r)    {    return Year("ymd_y",r,y,yjd,n);    }   }         // ---------------------------------------------------------------- - // Month + //! class Month + //! inherits YMD   // ----------------------------------------------------------------      function(mixed...:cMonth) Month=cMonth;   class cMonth   {    inherit YMD;       constant is_month=1;       int nd; // number of days
pike.git/lib/modules/Calendar.pmod/YMD.pike:1723:   //! calendar, which modifies this rule for the Gregorian calendar;   //! the week number and year is the same as for the ISO calendar,   //! except for the sundays.   //!   //! When adding, moving and subtracting months   //! to a week, it falls back to using days.   //!   //! When adding, moving or subtracting years,   //! if tries to place the moved week in the   //! resulting year. + //! + //! inherits YMD   // ----------------------------------------------------------------      function(mixed...:cWeek) Week=cWeek;   class cWeek   {    inherit YMD;       // Note: wy, w and wd are never CALUNKNOWN in this class.       constant is_week=1;
pike.git/lib/modules/Calendar.pmod/YMD.pike:2061:    {    return Week("ymd_yjwm",r,y,yjd,jd,wy,w,n,md,m,mnd);    }      // --- needs to be defined       protected int weeks_to_week(int y,int m);   }      // ---------------------------------------------------------------- - // Day + //! class Day + //! inherits YMD   // ----------------------------------------------------------------      class cDay   {    inherit YMD;       constant is_day=1;    int nw;      //!
pike.git/lib/modules/Calendar.pmod/YMD.pike:2511:   //! inherits YMD   //------------------------------------------------------------------------      class cHour   {    inherit Time::cHour;    inherit YMD_Time;    OVERLOAD_TIMEOFDAY;   }    + //------------------------------------------------------------------------ + //! class Minute + //! inherits Time.Minute + //! inherits YMD + //------------------------------------------------------------------------ +    class cMinute   {    inherit Time::cMinute;    inherit YMD_Time;    OVERLOAD_TIMEOFDAY;   }    -  + //------------------------------------------------------------------------ + //! class Second + //! inherits Time.Second + //! inherits YMD + //------------------------------------------------------------------------ +    class cSecond   {    inherit Time::cSecond;    inherit YMD_Time;    OVERLOAD_TIMEOFDAY;   }    -  + //------------------------------------------------------------------------ + //! class Fraction + //! inherits Time.Fraction + //! inherits YMD + //------------------------------------------------------------------------ +    class cFraction   {    inherit Time::cFraction;    inherit YMD_Time;    OVERLOAD_TIMEOFDAY;   }    -  + //------------------------------------------------------------------------ + //! class SuperTimeRange + //! inherits Time.SuperTimeRange + //------------------------------------------------------------------------ +    class cSuperTimeRange   {    inherit Time::cSuperTimeRange;       array(cYear) years(int ...range) { return get_units("years",@range); }    cYear year(void|int n) { return get_unit("years",n); }    int number_of_years() { return num_units("years"); }       array(cMonth) months(int ...range) { return get_units("months",@range); }    cMonth month(void|int n) { return get_unit("months",n); }
pike.git/lib/modules/Calendar.pmod/YMD.pike:2584:    string format_iso_week_short() { return RBASE->format_iso_week_short(); }    string format_week() { return RBASE->format_week(); }    string format_week_short() { return RBASE->format_week_short(); }    string format_month() { return RBASE->format_month(); }    string format_month_short() { return RBASE->format_month_short(); }      #undef RBASE   }      //------------------------------------------------------------------------ - //! global convinience functions + // Pop out doc-extractor context to the top-level scope. + //! module Calendar + //! submodule YMD + // global convenience functions   //------------------------------------------------------------------------      //! method TimeRange parse(string fmt,string arg)   //! parse a date, create relevant object   //! fmt is in the format "abc%xdef..."   //! where abc and def is matched, and %x is   //! one of those time units:   //! <pre>   //! %Y absolute year   //! %y dwim year (70-99 is 1970-1999, 0-69 is 2000-2069)
pike.git/lib/modules/Calendar.pmod/YMD.pike:2846:    {    m->month=low=m->year->month(m->M);    }    if (m->W)    m->week=low=m->year->week("w"+m->W);       if (!zero_type(m->D))    m->day=low=(m->month||(context?context->month():cal->Month()))    ->day((int)m->D);    else if (!zero_type(m->a)) -  m->day=low=m->year->day(m->a); +  m->day=low=(m->month || m->year)->day(m->a);    else if (!zero_type(m->e))    m->day=low=(m->week||(context?context->week():cal->Week()))    ->day(m->e);    else    low=m->day=context?context->day():cal->Day();       if (m->day && zero_type(m->Y) && zero_type(m->y) && m->e)    if (m->month)    {    // scan for closest year that matches
pike.git/lib/modules/Calendar.pmod/YMD.pike:2939:    if (sub_second)    low = low->fraction(sub_second);    return low;      #ifndef NOCATCH    })   #endif    return 0;   }    - //! function Day dwim_day(string date) - //! function Day dwim_day(string date,TimeRange context) + //! method Day dwim_day(string date) + //! method Day dwim_day(string date,TimeRange context)   //! Tries a number of different formats on the given date (in order):   //! <pre>   //! <ref>parse</ref> format as in   //! "%y-%M-%D (%M) -W%W-%e (%e)" "2000-03-20 (Mar) -W12-1 (Mon)"   //! "%y-%M-%D" "2000-03-20", "00-03-20"   //! "%M%/%D/%y" "3/20/2000"   //! "%D%*[ /]%M%*[ /-,]%y" "20/3/2000" "20 mar 2000" "20/3 -00"   //! "%e%*[ ]%D%*[ /]%M%*[ /-,]%y" "Mon 20 Mar 2000" "Mon 20/3 2000"   //! "-%y%*[ /]%D%*[ /]%M" "-00 20/3" "-00 20 mar"   //! "-%y%*[ /]%M%*[ /]%D" "-00 3/20" "-00 march 20"
pike.git/lib/modules/Calendar.pmod/YMD.pike:3170:    (t=parse(rfc850_date, what, cx)) ||    (t=parse(asctime_date+" %z", what+" GMT", cx)) )    return t;       return 0;   }      //-- auxillary functions------------------------------------------------      //! - //! function datetime(int|void unix_time) + //! function mapping(string:int) datetime(int|void unix_time)   //! Replacement for localtime; gives back a mapping:   //! <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)   //! "unix": int // unix time   //! "julian": float // julian day   //! "hour": int(0..) // hour of day, including dst   //! "minute": int(0..59) // minute of hour   //! "second": int(0..59) // second of minute   //! "fraction": float // fraction of second   //! "timezone": int // offset to utc, including dst   //! ]);   //! </pre>   //! This is the same as calling <ref>Second</ref>()-><ref to=Second.datetime>datetime</ref>().   //! - //! function datetime_name(int|void unix_time) - //! function datetime_short_name(int|void unix_time) + //! function string datetime_name(int|void unix_time) + //! function string datetime_short_name(int|void unix_time)   //! Compat functions; same as <ref>format_iso</ref>   //! and <ref>format_iso_short</ref>.   //!   //! function string format_iso(void|int unix_time)   //! function string format_iso_short(void|int unix_time)   //! function string format_iso_tod(void|int unix_time)   //! function string format_day_iso(void|int unix_time)   //! function string format_day_iso_short(void|int unix_time)   //! Format the object into nice strings;   //! <pre>