dc21d42001-05-05Mirar (Pontus Hagland) //! //! module Calendar //! submodule YMD //!
78fd532000-07-12Mirar (Pontus Hagland) //! base for all Roman-kind of Calendars, //! ie, one with years, months, weeks and days //!
091c412012-05-04Henrik Grubbström (Grubba) //! inherits Time
78fd532000-07-12Mirar (Pontus Hagland) 
a580e12000-09-27Fredrik Hübinette (Hubbe) #pike __REAL_VERSION__
a20af62000-09-26Fredrik Hübinette (Hubbe) 
78fd532000-07-12Mirar (Pontus Hagland) // #pragma strict_types
9f0b6c2008-02-07Martin Stjernholm inherit Calendar.Time:Time;
78fd532000-07-12Mirar (Pontus Hagland) 
210cfe2001-01-11Mirar (Pontus Hagland) #include "constants.h"
78fd532000-07-12Mirar (Pontus Hagland) // ---------------- // virtual methods to tell how this calendar works // ----------------
9eaf1d2008-06-28Martin Nilsson protected array(int) year_from_julian_day(int jd); protected int julian_day_from_year(int year); protected int year_remaining_days(int y,int yday);
78fd532000-07-12Mirar (Pontus Hagland) 
9eaf1d2008-06-28Martin Nilsson protected array(int) year_month_from_month(int y,int m); // [y,m,ndays,myd] protected array(int) month_from_yday(int y,int yday); // [m,day-of-month,ndays,myd]
78fd532000-07-12Mirar (Pontus Hagland) 
9eaf1d2008-06-28Martin Nilsson protected array(int) week_from_week(int y,int w); // [wy,w,wd,ndays,wjd] protected array(int) week_from_julian_day(int jd); // [wy,w,wd,ndays,wjd]
78fd532000-07-12Mirar (Pontus Hagland) 
9eaf1d2008-06-28Martin Nilsson protected string f_month_name_from_number; protected string f_month_shortname_from_number; protected string f_month_number_from_name; protected string f_month_day_name_from_number; protected string f_week_name_from_number; protected string f_week_day_number_from_name; 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;
78fd532000-07-12Mirar (Pontus Hagland) 
9eaf1d2008-06-28Martin Nilsson protected int(0..1) year_leap_year(int y);
78fd532000-07-12Mirar (Pontus Hagland) 
9eaf1d2008-06-28Martin Nilsson protected int compat_week_day(int n);
78fd532000-07-12Mirar (Pontus Hagland) 
4b1e032012-09-22Henrik Grubbström (Grubba) // 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; }
78fd532000-07-12Mirar (Pontus Hagland) //------------------------------------------------------------------------
dc21d42001-05-05Mirar (Pontus Hagland) //! class YMD
78fd532000-07-12Mirar (Pontus Hagland) //! Base (virtual) time period of the Roman-kind of calendar.
dc21d42001-05-05Mirar (Pontus Hagland) //! inherits TimeRange
55f4ec2001-04-27Henrik Grubbström (Grubba) //------------------------------------------------------------------------
dc21d42001-05-05Mirar (Pontus Hagland)  class YMD
78fd532000-07-12Mirar (Pontus Hagland) { inherit TimeRange; // --- generic for all YMD:
3fc92e2008-05-23Martin Stjernholm  // The correct year to use in context with yjd, yd, m and md is y. // The correct year to use in context with w is wy. // The correct year to use without context is year_no() (= either y or wy).
78fd532000-07-12Mirar (Pontus Hagland)  int y; // year int yjd; // julian day of the first day of the year int n; // number of this in the period int jd; // julian day of first day int yd; // day of year (1..) int m; // [*] month of year (1..12?), like int md; // [*] day of month (1..) int wy; // [*] week year int w; // [*] week of week year (1..) int wd; // [*] day of week (1..7?)
9ec4ca2008-01-23Martin Stjernholm  int mnd=CALUNKNOWN; // [*] days in current month
78fd532000-07-12Mirar (Pontus Hagland)  int utco=CALUNKNOWN; // [*] distance to UTC string tzn=0; // timezone name
3fc92e2008-05-23Martin Stjernholm  // [*]: might be uninitialized (CALUNKNOWN)
78fd532000-07-12Mirar (Pontus Hagland) 
9f0b6c2008-02-07Martin Stjernholm  Calendar.Ruleset rules;
78fd532000-07-12Mirar (Pontus Hagland)  constant is_ymd=1; // ---------------------------------------- // basic Y-M-D stuff // ---------------------------------------- void create_now() { rules=default_rules; create_unixtime_default(time()); } void create_unixtime_default(int unixtime) { // 1970-01-01 is julian day 2440588 create_julian_day( 2440588+unixtime/86400 ); // we can't reuse this; it might not be start of day [int mutco,string mtzn]=rules->timezone->tz_ux(unixtime); int uxo=unixtime%86400-mutco; if (uxo<0) create_julian_day( 2440588+unixtime/86400-1 ); else if (uxo>=86400) create_julian_day( 2440588+unixtime/86400+1 ); else if (uxo==0) utco=mutco,tzn=mtzn; // reuse, it *is* start of day } void make_month() // set m and md from y and yd { int myd; [m,md,mnd,myd]=month_from_yday(y,yd); }
9ec4ca2008-01-23Martin Stjernholm  void make_week() // set wy, w and wd from jd
78fd532000-07-12Mirar (Pontus Hagland)  { int wnd,wjd; [wy,w,wd,wnd,wjd]=week_from_julian_day(jd); } int __hash() { return jd; } // --- query
dc21d42001-05-05Mirar (Pontus Hagland) //! method float fraction_no() //! method int hour_no() //! method int julian_day() //! method int leap_year() //! method int minute_no() //! method int month_day() //! method int month_no() //! method int second_no() //! method int utc_offset() //! method int week_day() //! method int week_no() //! method int year_day() //! method int year_no() //! method string month_name() //! method string month_shortname() //! method string month_day_name() //! method string week_day_name() //! method string week_day_shortname() //! method string week_name() //! method string year_name() //! method string tzname() //! method string tzname_iso()
78fd532000-07-12Mirar (Pontus Hagland)  int julian_day() { return jd; }
3f28812012-05-06Henrik Grubbström (Grubba) //! method int unix_time()
f725052002-11-01Johan Sundström //! Returns the unix time integer corresponding to the start //! of the time range object. (An unix time integer is UTC.)
78fd532000-07-12Mirar (Pontus Hagland)  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; } int utc_offset() { if (utco==CALUNKNOWN) [utco,tzn]=rules->timezone->tz_jd(jd); return utco; } string tzname() { if (!tzn) [utco,tzn]=rules->timezone->tz_jd(jd); return tzn; } string tzname_iso() { int u=utc_offset(); if (!(u%3600)) return sprintf("UTC%+d",-u/3600); if (!(u%60)) 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); } int year_no() { return y>0?y:-1+y; } int month_no() { if (m==CALUNKNOWN) make_month(); return m; } int week_no() { if (w==CALUNKNOWN) make_week(); return w; } int month_day() { if (md==CALUNKNOWN) make_month(); return md; } int week_day() { if (wd==CALUNKNOWN) make_week(); return wd; } int year_day() { return yd; } string year_name() {
3fc92e2008-05-23Martin Stjernholm  return rules->language[f_year_name_from_number](year_no());
78fd532000-07-12Mirar (Pontus Hagland)  } string week_name() { if (w==CALUNKNOWN) make_week(); return rules->language[f_week_name_from_number](w); } string month_name() { if (m==CALUNKNOWN) make_month(); return rules->language[f_month_name_from_number](m); } string month_shortname() { if (m==CALUNKNOWN) make_month(); return rules->language[f_month_shortname_from_number](m); } string month_day_name() { if (mnd==CALUNKNOWN) make_month(); return rules->language[f_month_day_name_from_number](md,mnd); } string week_day_name() { if (wd==CALUNKNOWN) make_week(); return rules->language[f_week_day_name_from_number](wd); } string week_day_shortname() { if (wd==CALUNKNOWN) make_week(); return rules->language[f_week_day_shortname_from_number](wd); }
3fc92e2008-05-23Martin Stjernholm  int leap_year() { return year_leap_year(year_no()); }
78fd532000-07-12Mirar (Pontus Hagland)  int hour_no() { return 0; } int minute_no() { return 0; } int second_no() { return 0; } float fraction_no() { return 0.0; }
3f28812012-05-06Henrik Grubbström (Grubba) //! method mapping datetime()
dc21d42001-05-05Mirar (Pontus Hagland) //! 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 //! //! "unix": int // unix time //! "julian": int // julian day //! // for compatibility: //! "hour": 0 // hour of day, including dst //! "minute": 0 // minute of hour //! "second": 0 // second of minute //! "fraction": 0.0 // fraction of second //! ]); //! </pre> //! //! note: //! Day of week is compatible with old versions, //! ie, 0 is sunday, 6 is saturday, so it shouldn't be //! used to calculate the day of the week with the given //! week number. Year day is also backwards compatible, //! ie, one (1) less then from the year_day() function.
3fc92e2008-05-23Martin Stjernholm //! //! note: //! If this function is called in a Week object that begins with //! the first week of a year, it returns the previous year if that //! is where the week starts. To keep the representation //! unambiguous, the returned week number is then one more than //! the number of weeks in that year. //! //! E.g. Week(2008,1)->datetime() will return year 2007 and week //! 53 since the first week of 2008 starts in 2007.
dc21d42001-05-05Mirar (Pontus Hagland) 
78fd532000-07-12Mirar (Pontus Hagland)  mapping datetime(void|int skip_stuff) { if (m==CALUNKNOWN) make_month(); if (w==CALUNKNOWN) make_week();
3fc92e2008-05-23Martin Stjernholm  int week; if (y == wy) week = w; else // w is the first week of the year and it begins in the // previous year, so we know y == wy - 1 and w == 1. week = week_from_week (y, 0)[1] + 1;
78fd532000-07-12Mirar (Pontus Hagland)  if (skip_stuff) // called from timeofday return ([ "year": y, "month": m, "day": md, "yearday": yd-1,
3fc92e2008-05-23Martin Stjernholm  "week": week,
78fd532000-07-12Mirar (Pontus Hagland)  "week_day": compat_week_day(wd) ]); else { return ([ "year": y, "month": m, "day": md, "yearday": yd-1,
3fc92e2008-05-23Martin Stjernholm  "week": week,
78fd532000-07-12Mirar (Pontus Hagland)  "week_day": compat_week_day(wd), "timezone": utc_offset(), "julian": jd, "unix": unix_time(), // for compatibility: "hour": 0, "minute": 0, "second": 0, "fraction": 0.0 ]); } } // --- string format ----
dc21d42001-05-05Mirar (Pontus Hagland) //! method string format_iso_ymd(); //! method string format_ymd(); //! method string format_ymd_short(); //! 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_time_xshort(); //! method string format_mtime(); //! method string format_xtime(); //! method string format_tod(); //! method string format_todz(); //! method string format_xtod(); //! method string format_mod(); //! Format the object into nice strings; //! <pre> //! iso_ymd "2000-06-02 (Jun) -W22-5 (Fri)" [2] //! ext_ymd "Friday, 2 June 2000" [2] //! ymd "2000-06-02" //! ymd_short "20000602" //! ymd_xshort "000602" [1] //! iso_week "2000-W22" //! iso_week_short "2000W22" //! week "2000-w22" [2] //! week_short "2000w22" [2] //! month "2000-06" //! month_short "200006" [1] //! iso_time "2000-06-02 (Jun) -W22-5 (Fri) 00:00:00 UTC+1" [2] //! ext_time "Friday, 2 June 2000, 00:00:00" [2] //! ctime "Fri Jun 2 00:00:00 2000\n" [2] [3] //! http "Fri, 02 Jun 2000 00:00:00 GMT" [4] //! time "2000-06-02 00:00:00" //! time_short "20000602 00:00:00" //! time_xshort "000602 00:00:00"
9f3c3f2001-07-18Mirar (Pontus Hagland) //! iso_short "2000-06-02T00:00:00"
dc21d42001-05-05Mirar (Pontus Hagland) //! mtime "2000-06-02 00:00" //! xtime "2000-06-02 00:00:00.000000" //! tod "00:00:00" //! tod_short "000000" //! 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.
4b1e032012-09-22Henrik Grubbström (Grubba) //! //! The iso variants aim to be compliant with ISO-8601.
78fd532000-07-12Mirar (Pontus Hagland)  string format_iso_ymd() { if (m==CALUNKNOWN) make_month(); if (w==CALUNKNOWN) make_week(); return sprintf("%04d-%02d-%02d (%s) -W%02d-%d (%s)",
3fc92e2008-05-23Martin Stjernholm  y,m,md,
78fd532000-07-12Mirar (Pontus Hagland)  month_shortname(), w,wd, // fixme - what weekday? week_day_shortname()); } string format_ext_ymd() { if (m==CALUNKNOWN) make_month(); return sprintf("%s, %s %s %s", week_day_name(), month_day_name(),month_name(),year_name()); } string format_ctime() { return sprintf("%s %s %2d 00:00:00 %s\n", week_day_shortname(), month_shortname(), md, year_name()); } string format_http() { if (wd==CALUNKNOWN) make_week();
16901a2007-05-06Martin Bähr  if (md==CALUNKNOWN) make_month(); return sprintf("%s, %02d %s %04d 00:00:00 GMT", ("SunMonTueWedThuFriSat"/3)[compat_week_day(wd)], md, ("zzzJanFebMarAprMayJunJulAugSepOctNovDec"/3)[m],
3fc92e2008-05-23Martin Stjernholm  y);
16901a2007-05-06Martin Bähr  } string format_ext_time_short() { if (wd==CALUNKNOWN) make_week();
78fd532000-07-12Mirar (Pontus Hagland)  if (md==CALUNKNOWN) make_month(); return
a813bd2007-05-06Martin Bähr  sprintf("%s, %d %s %d 00:00:00 GMT",
dca9502007-05-05Martin Bähr  week_day_shortname(),
3fc92e2008-05-23Martin Stjernholm  month_day(),month_shortname(),y);
78fd532000-07-12Mirar (Pontus Hagland)  } string format_ymd() { if (m==CALUNKNOWN) make_month();
3fc92e2008-05-23Martin Stjernholm  return sprintf("%04d-%02d-%02d",y,m,md);
78fd532000-07-12Mirar (Pontus Hagland)  } string format_ymd_short() { if (m==CALUNKNOWN) make_month();
3fc92e2008-05-23Martin Stjernholm  return sprintf("%04d%02d%02d",y,m,md);
78fd532000-07-12Mirar (Pontus Hagland)  } string format_ymd_xshort() { if (m==CALUNKNOWN) make_month();
3fc92e2008-05-23Martin Stjernholm  return sprintf("%02d%02d%02d",y%100,m,md);
78fd532000-07-12Mirar (Pontus Hagland)  } string format_iso_week() { if (w==CALUNKNOWN) make_week();
9ec4ca2008-01-23Martin Stjernholm  return sprintf("%04d-W%02d",wy,w);
78fd532000-07-12Mirar (Pontus Hagland)  } string format_iso_week_short() { if (w==CALUNKNOWN) make_week();
9ec4ca2008-01-23Martin Stjernholm  return sprintf("%04d%02d",wy,w);
78fd532000-07-12Mirar (Pontus Hagland)  } string format_week() {
3fc92e2008-05-23Martin Stjernholm  if (w==CALUNKNOWN) make_week(); return sprintf("%04d-%s",wy,week_name());
78fd532000-07-12Mirar (Pontus Hagland)  } string format_week_short() {
3fc92e2008-05-23Martin Stjernholm  if (w==CALUNKNOWN) make_week(); return sprintf("%04d%s",wy,week_name());
78fd532000-07-12Mirar (Pontus Hagland)  } string format_month() { if (m==CALUNKNOWN) make_month(); return sprintf("%04d-%02d",y,m); } string format_month_short() { if (m==CALUNKNOWN) make_month(); return sprintf("%04d%02d",y,m); } string format_iso_time() { return format_iso_ymd()+" 00:00:00"; } string format_ext_time() { return format_ext_ymd()+" 00:00:00"; } string format_time() { return format_ymd()+" 00:00:00"; } string format_time_short() { return format_ymd_short()+" 00:00:00"; }
9f3c3f2001-07-18Mirar (Pontus Hagland)  string format_iso_short() { return format_ymd_short()+"T00:00:00"; }
78fd532000-07-12Mirar (Pontus Hagland)  string format_time_xshort() { return format_ymd_xshort()+" 00:00:00"; } string format_mtime() {
f480a02001-12-04Martin Nilsson  return format_ymd()+" 00:00";
78fd532000-07-12Mirar (Pontus Hagland)  } string format_xtime() {
f480a02001-12-04Martin Nilsson  return format_ymd()+" 00:00:00.000000";
78fd532000-07-12Mirar (Pontus Hagland)  } string format_tod() { return "00:00:00"; } string format_tod_short() { return "000000"; } string format_todz() { return "00:00:00 "+tzname(); } string format_todz_iso() { return "00:00:00 "+tzname_iso(); } string format_mod() { return "00:00"; } string format_xtod() { return "00:00:00.000000"; }
2c364e2000-11-13Mirar (Pontus Hagland)  string format_nice(); string format_nicez() { return format_nice()+" "+tzname(); }
3e5dc62003-06-19Johan Sundström  string tzname_utc_offset() { int u=utc_offset(); return sprintf("%+03d%02d", -u/3600, abs(u)/60%60); }
2c364e2000-11-13Mirar (Pontus Hagland)  string format_smtp() { if (m==CALUNKNOWN) make_month();
3e5dc62003-06-19Johan Sundström  return sprintf("%s, %s %s %s 00:00:00 %s",
376f902000-12-12Mirar (Pontus Hagland)  week_day_shortname(),
2c364e2000-11-13Mirar (Pontus Hagland)  month_day_name(),month_shortname(),year_name(),
3e5dc62003-06-19Johan Sundström  tzname_utc_offset()); } string format_commonlog() { if (m==CALUNKNOWN) make_month(); return sprintf("%02d/%s/%d:%s %s", month_day(), month_shortname(), year_no(), format_tod(), tzname_utc_offset());
2c364e2000-11-13Mirar (Pontus Hagland)  }
78fd532000-07-12Mirar (Pontus Hagland)  string format_elapsed() { return sprintf("%dd",number_of_days()); } // --- size and move ---
9eaf1d2008-06-28Martin Nilsson  protected TimeRange _set_size(int n,TimeRange t)
78fd532000-07-12Mirar (Pontus Hagland)  { if (t->is_timeofday) return second()->set_size(n,t); if (yd==1 && t->is_year) return Year("ymd_y",rules,y,yjd,t->n*n) ->autopromote(); // months are even on years if (t->is_year || t->is_month) { if (md==CALUNKNOWN) make_month(); if (md==1) return Month("ymd_yjmw",rules,y,yjd,jd,m,
9ec4ca2008-01-23Martin Stjernholm  t->number_of_months()*n,wd,w,wy)
78fd532000-07-12Mirar (Pontus Hagland)  ->autopromote(); } // weeks are not if (t->is_week) { if (wd==CALUNKNOWN) make_week();
3fc92e2008-05-23Martin Stjernholm  if (wd==1) return Week("ymd_yjwm",rules,y,yjd,jd,wy,w,t->n*n,md,m,mnd);
78fd532000-07-12Mirar (Pontus Hagland)  } // fallback on days if (t->is_ymd) return Day("ymd_ydmw",rules,y,yjd,jd,yd,
9ec4ca2008-01-23Martin Stjernholm  n*t->number_of_days(),m,md,wy,w,wd,mnd);
78fd532000-07-12Mirar (Pontus Hagland)  error("set_size: incompatible class %O\n", object_program(t)); }
9eaf1d2008-06-28Martin Nilsson  protected TimeRange _add(int _n,TimeRange step)
78fd532000-07-12Mirar (Pontus Hagland)  { if (step->is_ymd)
07fc8c2006-01-11Martin Bähr  return _move(_n,step);
78fd532000-07-12Mirar (Pontus Hagland)  if (step->is_timeofday)
07fc8c2006-01-11Martin Bähr  if (n) return second()->range(second(-1))->add(_n,step); else return second()->beginning()->add(_n,step);
78fd532000-07-12Mirar (Pontus Hagland)  error("add: incompatible class %O\n", object_program(step)); } array(int(-1..1)) _compare(TimeRange with) {
325f582000-08-06Mirar (Pontus Hagland)  if (objectp(with)) if (with->is_timeofday) { // wrap
563bd72004-01-11Martin Nilsson  array(int(-1..1)) cmp=with->_compare(this);
78fd532000-07-12Mirar (Pontus Hagland) 
325f582000-08-06Mirar (Pontus Hagland)  return ({-cmp[0], -cmp[2], -cmp[1], -cmp[3]}); } else if (with->is_ymd || with->julian_day) {
78fd532000-07-12Mirar (Pontus Hagland) #define CMP(A,B) ( ((A)<(B))?-1:((A)>(B))?1:0 )
325f582000-08-06Mirar (Pontus Hagland)  int b1=julian_day(); int e1=b1+number_of_days();
78fd532000-07-12Mirar (Pontus Hagland) 
325f582000-08-06Mirar (Pontus Hagland)  int b2=with->julian_day(); int e2=b2+with->number_of_days();
78fd532000-07-12Mirar (Pontus Hagland) 
325f582000-08-06Mirar (Pontus Hagland)  return ({ CMP(b1,b2),CMP(b1,e2),CMP(e1,b2),CMP(e1,e2) }); }
78fd532000-07-12Mirar (Pontus Hagland)  return ::_compare(with); } // --- to other YMD // years int number_of_years() { int m=number_of_days(); if (m<=1 || m+yd-1<year()->number_of_days()) return 1; return 1+y-year_from_julian_day(jd+m-1)[0]; }
3fc92e2008-05-23Martin Stjernholm  array(cYear) years(void|int from, void|int to)
78fd532000-07-12Mirar (Pontus Hagland)  {
3fc92e2008-05-23Martin Stjernholm  int n=number_of_years();
78fd532000-07-12Mirar (Pontus Hagland) 
3fc92e2008-05-23Martin Stjernholm  if (zero_type (from)) { from = 1; to = n; } else if (zero_type (to)) error("Illegal numbers of arguments to years()\n");
78fd532000-07-12Mirar (Pontus Hagland)  else {
3fc92e2008-05-23Martin Stjernholm  if (from>n) return ({}); else if (from<1) from=1; if (to>n) to=n; else if (to<from) return ({});
78fd532000-07-12Mirar (Pontus Hagland)  }
0564742006-01-17Martin Bähr  return map(enumerate(1+to-from,1,y+from-1),
78fd532000-07-12Mirar (Pontus Hagland)  lambda(int x) { return Year("ymd_yn",rules,x,1); }); }
3fc92e2008-05-23Martin Stjernholm  cYear year(void|int m) { if (zero_type (m)) m=1; if (!n&&m==-1)
78fd532000-07-12Mirar (Pontus Hagland)  return Year("ymd_y",rules,y,yjd,1);
3fc92e2008-05-23Martin Stjernholm  if (m<0) m += 1 + number_of_years();
78fd532000-07-12Mirar (Pontus Hagland)  array(TimeRange) res=years(m,m); if (sizeof(res)==1) return res[0];
3fc92e2008-05-23Martin Stjernholm  error("Not in range (Year 1..%d exist)\n", number_of_years());
78fd532000-07-12Mirar (Pontus Hagland)  } // days int number_of_days();
3fc92e2008-05-23Martin Stjernholm  array(cDay) days(void|int from, void|int to)
78fd532000-07-12Mirar (Pontus Hagland)  {
3fc92e2008-05-23Martin Stjernholm  int n=number_of_days();
78fd532000-07-12Mirar (Pontus Hagland) 
3fc92e2008-05-23Martin Stjernholm  if (zero_type (from)) { from = 1; to = n; } else if (zero_type (to)) error("Illegal number of arguments to days()\n");
78fd532000-07-12Mirar (Pontus Hagland)  else { if (from>n) return ({}); else if (from<1) from=1; if (to>n) to=n; else if (to<from) return ({}); } int zy=y; int zyd=yd+from-1; int zjd=jd+from-1; int zyjd=yjd; array(cDay) res=({}); to-=from-1; for (;;) { int rd=year_remaining_days(zy,zyd)+1; if (rd>0) { if (rd>to) rd=to; res+=map(enumerate(rd,1,zyd), lambda(int x) { return Day("ymd_yd",rules,zy,zyjd,zyjd+x-1,x,1); }); if (rd==to) break; zjd+=rd; to-=rd; } [zy,zyjd]=year_from_julian_day(zjd); zyd=zjd-zyjd+1; } return res; }
3fc92e2008-05-23Martin Stjernholm  cDay day(void|int m, mixed... ignored)
b71b812002-05-27Johan Sundström  {
3fc92e2008-05-23Martin Stjernholm  if (zero_type (m)) m=1;
78fd532000-07-12Mirar (Pontus Hagland) 
4bbad12006-01-10Martin Bähr  if (!n)
78fd532000-07-12Mirar (Pontus Hagland)  return Day("ymd_yd",rules,y,yjd,jd,yd,1); if (m<0) m+=1+number_of_days(); array(TimeRange) res=days(m,m); if (sizeof(res)==1) return res[0];
880dc52003-12-31Martin Nilsson  if(number_of_days()) error("Not in range (Day 1..%d exist).\n", number_of_days()); else error("No days in object.\n");
78fd532000-07-12Mirar (Pontus Hagland)  } // --- months int number_of_months(); array(cMonth) months(int ...range) { int from=1,n=number_of_months(),to=n; if (sizeof(range)) if (sizeof(range)<2) error("Illegal numbers of arguments to months()\n"); else { [from,to]=range; if (from>n) return ({}); else if (from<1) from=1; if (to>n) to=n; else if (to<from) return ({}); } if (md==CALUNKNOWN) make_month(); return map(enumerate(1+to-from,1,from+m-1), lambda(int x) { return Month("ymd_ym",rules,y,x,1); }); } cMonth month(int ... mp) { if (md==CALUNKNOWN) make_month(); if (!sizeof(mp)) return Month("ymd_ym",rules,y,m,1); int num=mp[0]; if (num==-1 && !n) return Month("ymd_ym",rules,y,m,1); if (num<0) num+=1+number_of_months(); array(TimeRange) res=months(num,num); if (sizeof(res)==1) return res[0]; error("not in range; Month 1..%d exist in %O\n",
563bd72004-01-11Martin Nilsson  number_of_months(),this);
78fd532000-07-12Mirar (Pontus Hagland)  } //---- week int number_of_weeks(); array(cWeek) weeks(int ...range) { int from=1,n=number_of_weeks(),to=n; if (sizeof(range)) if (sizeof(range)<2) error("Illegal numbers of arguments to weeks()\n"); else { [from,to]=range; if (from>n) return ({}); else if (from<1) from=1; if (to>n) to=n; else if (to<from) return ({}); } if (wd==CALUNKNOWN) make_week(); return map(enumerate(1+to-from,1,from+w-1), lambda(int x) { return Week("ymd_yw",rules,wy,x,1); }); } cWeek week(int ... mp) { if (wd==CALUNKNOWN) make_week(); if (!sizeof(mp)) return Week("ymd_yw",rules,wy,w,1); int num=mp[0]; if (num==-1 && !n) return Week("ymd_yw",rules,wy,w,1); if (num<0) num+=1+number_of_weeks(); array(TimeRange) res=weeks(num,num); if (sizeof(res)==1) return res[0]; error("not in range (Week 1..%d exist)\n", number_of_weeks()); } // --- functions to conform to Time.*
9eaf1d2008-06-28Martin Nilsson  protected TimeRange get_unit(string unit,int m)
78fd532000-07-12Mirar (Pontus Hagland)  { if (!n) return day()[unit](); if (m<0) m+=::`[]("number_of_"+unit+"s")(); array(TimeRange) res=::`[](unit+"s")(m,m); if (sizeof(res)==1) return res[0]; error("not in range ("+unit+" 0..%d exist)\n", ::`[]("number_of_"+unit+"s")()-1); }
9eaf1d2008-06-28Martin Nilsson  protected array(TimeRange) get_timeofday(string unit,
78fd532000-07-12Mirar (Pontus Hagland)  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 { [from,to]=range; if (from>=n) return ({}); else if (from<0) from=0; if (to>=n) to=n-1; else if (to<from) return ({}); } from*=step; to*=step; to-=from-step; from+=unix_time(); array z= map(enumerate(to/step,step,from), lambda(int x) { return p("timeofday",rules,x,step); }); // return z; if (sizeof(z)>1 && ((p==cHour && z[0]->utc_offset()%3600 != z[-1]->utc_offset()%3600) || (p==cMinute && z[0]->utc_offset()%60 != z[-1]->utc_offset()%60))) { // we're in a zone shifting, and we shift a non-hour (or non-minute) cSecond sec=Second(); int i,uo=z[0]->utc_offset(); for (i=1; i<sizeof(z); i++) if (z[i]->utc_offset()!=uo) { int uq=(z[i]->utc_offset()-uo); if (uq<0) { if (uq<=-step) uq=-(-uq%step); z= z[..i-1]+ ({z[i]->set_size(step+uq,sec)})+ map(z[i+1..],"add",uq,sec); } else { if (uq>=step) uq%=step; z= z[..i-1]+ ({z[i]->set_size(uq,sec)})+
8a531a2006-11-04Martin Nilsson  map(z[i..<1],"add",uq,sec);
78fd532000-07-12Mirar (Pontus Hagland)  i++; } uo=z[i]->utc_offset(); } } return z; }
dc21d42001-05-05Mirar (Pontus Hagland) //! method Second second() //! method Second second(int n) //! method Minute minute(int hour,int minute,int second) //! method array(Second) seconds() //! method array(Second) seconds(int first,int last) //! method int number_of_seconds() //! method Minute minute() //! method Minute minute(int n) //! method Minute minute(int hour,int minute) //! method array(Minute) minutes() //! method array(Minute) minutes(int first,int last) //! method int number_of_minutes() //! 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()
78fd532000-07-12Mirar (Pontus Hagland)  int number_of_hours() { return (number_of_seconds()+3599)/3600; } cHour hour(void|int n) { return get_unit("hour",n); } array(cHour) hours(int ...range) { return get_timeofday("hours",0,3600,Hour,@range); } int number_of_minutes() { return (number_of_seconds()+59)/60; }
eb4d9c2000-08-04Mirar (Pontus Hagland)  cMinute minute(void|int n,int ... time) { if (sizeof(time))
e7dce62001-01-11Mirar (Pontus Hagland)  return minute(n*60+time[0]);
eb4d9c2000-08-04Mirar (Pontus Hagland)  return get_unit("minute",n); }
78fd532000-07-12Mirar (Pontus Hagland)  array(cMinute) minutes(int ...range) { return get_timeofday("minutes",0,60,Minute,@range); } int number_of_seconds() { return end()->unix_time()-unix_time(); } cSecond second(void|int n,int ...time) { if (sizeof(time)==2)
f50dbf2000-10-18Mirar (Pontus Hagland)  {
210cfe2001-01-11Mirar (Pontus Hagland)  return second(n*3600+time[0]*60+time[1]); // return hour(n)->minute(time[0])->second(time[1]);
f50dbf2000-10-18Mirar (Pontus Hagland)  }
78fd532000-07-12Mirar (Pontus Hagland)  return get_unit("second",n); } array(cSecond) seconds(int ...range) { return get_timeofday("seconds",0,1,Second,@range); } float number_of_fractions() { return (float)number_of_seconds(); } cSecond fraction(void|float|int n) { return fractions()[0]; } array(cSecond) fractions(int|float ...range) { float from,to,n=number_of_fractions(); if (sizeof(range)==2) 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; return ({Fraction("timeofday_f",rules,unix_time(),0, (int)to,(int)(inano*(to-(int)to))) ->autopromote()}); }
adbafd2006-01-11Martin Bähr  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(); else if (functionp(with)) with=promote_program(with); int length=(int)(how_many(with)/n);
0a64802006-01-23Martin Bähr  int remains; if(length && intp(n)) remains=(int)(how_many(with)%n); if(!length) length=1;
adbafd2006-01-11Martin Bähr  TimeRange start=beginning(); TimeRange end=end(); array result=({});
0a64802006-01-23Martin Bähr  TimeRange next; while((next=start+with*(length+!!remains)) < end)
adbafd2006-01-11Martin Bähr  {
0a64802006-01-23Martin Bähr  result += ({ start->distance(next) }); start=next; if(remains) remains--;
adbafd2006-01-11Martin Bähr  } result += ({ start->distance(end) }); return result; }
78fd532000-07-12Mirar (Pontus Hagland) // ---------------------------------------- // virtual functions needed // ---------------------------------------- string nice_print();
d7db5d2013-05-31Martin Nilsson  protected string _sprintf(int t,mapping m)
61ec5e2001-06-09Mirar (Pontus Hagland)  { switch (t) { case 't': return "Calendar."+calendar_name()+".YMD"; default: return ::_sprintf(t,m); } }
78fd532000-07-12Mirar (Pontus Hagland)  void create_julian_day(int|float jd);
9eaf1d2008-06-28Martin Nilsson  protected TimeRange _move(int n,YMD step);
78fd532000-07-12Mirar (Pontus Hagland)  TimeRange place(TimeRange what,void|int force); // not needed YMD autopromote() { return this; } } //------------------------------------------------------------------------ //! class Year
55f4ec2001-04-27Henrik Grubbström (Grubba) //! This is the time period of a year.
dc21d42001-05-05Mirar (Pontus Hagland) //! inherits TimeRange //! inherits YMD
55f4ec2001-04-27Henrik Grubbström (Grubba) //------------------------------------------------------------------------
dc21d42001-05-05Mirar (Pontus Hagland)  function(mixed...:cYear) Year=cYear; class cYear
78fd532000-07-12Mirar (Pontus Hagland) { inherit YMD; constant is_year=1; // ---
dc21d42001-05-05Mirar (Pontus Hagland) //! //! method void create("unix",int unix_time) //! method void create("julian",int|float julian_day) //! method void create(int year) //! method void create(string year)
6519f22008-01-27Henrik Grubbström (Grubba) //! method void create(TimeRange range)
77f1082006-01-17Martin Bähr //! It's possible to create the standard year
dc21d42001-05-05Mirar (Pontus Hagland) //! by using three different methods; either the normal //! way - from standard unix time or the julian day, //! and also, for more practical use, from the year number. //!
d7db5d2013-05-31Martin Nilsson  protected void create(mixed ...args)
78fd532000-07-12Mirar (Pontus Hagland)  { if (!sizeof(args)) { create_now(); return; } else switch (args[0]) { case "ymd_y": rules=args[1]; y=args[2]; jd=yjd=args[3]; n=args[4];
9ec4ca2008-01-23Martin Stjernholm  m=md=wy=w=wd=CALUNKNOWN;
78fd532000-07-12Mirar (Pontus Hagland)  yd=1; return; case "ymd_yn": rules=args[1]; y=args[2]; jd=yjd=julian_day_from_year(y); n=args[3];
9ec4ca2008-01-23Martin Stjernholm  m=md=wy=w=wd=CALUNKNOWN;
78fd532000-07-12Mirar (Pontus Hagland)  yd=1; return;
557b582008-01-25Martin Stjernholm  case "unix": case "unix_r": case "julian": case "julian_r": // Handled by ::create. break;
78fd532000-07-12Mirar (Pontus Hagland)  default: if (intp(args[0]) && sizeof(args)==1) { rules=default_rules; y=args[0]; jd=yjd=julian_day_from_year(y); n=1;
9ec4ca2008-01-23Martin Stjernholm  m=md=wy=w=wd=CALUNKNOWN;
78fd532000-07-12Mirar (Pontus Hagland)  yd=1; return; } else if (stringp(args[0])) { y=default_rules->language[f_year_number_from_name](args[0]); rules=default_rules; jd=yjd=julian_day_from_year(y); n=1;
9ec4ca2008-01-23Martin Stjernholm  m=md=wy=w=wd=CALUNKNOWN;
78fd532000-07-12Mirar (Pontus Hagland)  yd=1; return; } break; } rules=default_rules; ::create(@args); } void create_julian_day(int|float _jd) { if (floatp(_jd)) create_unixtime_default((int)((jd-2440588)*86400)); else { [y,yjd]=year_from_julian_day(_jd); jd=yjd; n=1; md=yd=m=1;
9ec4ca2008-01-23Martin Stjernholm  wy=w=wd=CALUNKNOWN; // unknown
78fd532000-07-12Mirar (Pontus Hagland)  } } TimeRange beginning() { return Year("ymd_y",rules,y,yjd,0); } TimeRange end() { return Year("ymd_yn",rules,y+n,0); } // ----------------
d7db5d2013-05-31Martin Nilsson  protected string _sprintf(int t,mapping m)
78fd532000-07-12Mirar (Pontus Hagland)  { switch (t) { case 'O': if (n!=1) return sprintf("Year(%s)",nice_print_period()); return sprintf("Year(%s)",nice_print());
61ec5e2001-06-09Mirar (Pontus Hagland)  case 't': return "Calendar."+calendar_name()+".Year";
78fd532000-07-12Mirar (Pontus Hagland)  default:
e0d1952001-06-17Mirar (Pontus Hagland)  return ::_sprintf(t,m);
78fd532000-07-12Mirar (Pontus Hagland)  } } string nice_print_period() { if (!n) return nice_print()+" sharp"; return sprintf("%s..%s",nice_print(),year(-1)->nice_print()); } string nice_print() { return year_name(); }
2c364e2000-11-13Mirar (Pontus Hagland)  string format_nice() { return year_name(); }
78fd532000-07-12Mirar (Pontus Hagland) // --- Year _move TimeRange _move(int m,YMD step) { if (!step->n || !m) return this; if (step->is_year) return Year("ymd_yn",rules,y+m*step->n,n) ->autopromote(); if (step->is_month)
563bd72004-01-11Martin Nilsson  return month()->add(m,step)->set_size(this);
78fd532000-07-12Mirar (Pontus Hagland)  // if (step->is_week)
563bd72004-01-11Martin Nilsson // return week()->add(m,step)->set_size(this);
78fd532000-07-12Mirar (Pontus Hagland)  if (step->is_ymd) return Day("ymd_jd",rules, yjd+m*step->number_of_days(),number_of_days()) ->autopromote(); error("_move: Incompatible type %O\n",step); }
9eaf1d2008-06-28Martin Nilsson  protected void convert_from(TimeRange other)
78fd532000-07-12Mirar (Pontus Hagland)  {
3fc92e2008-05-23Martin Stjernholm #if 0 // The following is disabled since it leads to inconsistent // behavior with other time ranges when they are converted to // partly overlapping time ranges. If the user wants to convert // a week to the year it "unambiguously" belongs to, (s)he can // do Calendar.ISO.Year(week->year_no()). if (other->is_week) { // Weeks aren't even on years but they still unambiguously // belong to years. We therefore convert using the week year // instead of the default method that uses the julian day. create ("ymd_yn", other->rules, other->wy, other->n > 1 ? other->week(-1)->wy - other->wy + 1 : other->n); return; } #endif ::convert_from(other);
78fd532000-07-12Mirar (Pontus Hagland)  if (other->number_of_years) n=other->number_of_years(); else n=0; } TimeRange place(TimeRange what,void|int force) { if (what->is_day) { int yd=what->yd; return Day("ymd_yd",rules,y,yjd,yjd+yd-1,yd,what->n); } if (what->is_week) { cWeek week=Week("ymd_yw",rules,y,what->w,what->n);
3fc92e2008-05-23Martin Stjernholm  if (!force && week->wy!=y) return 0; // not this year
78fd532000-07-12Mirar (Pontus Hagland)  return week; }
c4a0d92001-06-09Mirar (Pontus Hagland)  if (what->is_year) return Year("ymd_yn",rules,y,what->number_of_years()); if (what->is_month) return month(what->month_name()); if (what->is_timeofday) return place(what->day(),force)->place(what,force);
78fd532000-07-12Mirar (Pontus Hagland)  error("place: Incompatible type %O\n",what); } TimeRange distance(TimeRange to) { if (to->is_timeofday) { return hour()->distance(to); } if (to->is_ymd) { if (to->is_year) { int y1=y; int y2=to->y; if (y2<y1) error("distance: negative distance\n"); return Year("ymd_yn",rules,y,y2-y1) ->autopromote(); } if (to->is_month) return month()->distance(to); return day()->distance(to); } error("distance: Incompatible type %O\n",to); } // --- int number_of_years() { return n; } int number_of_weeks();
dc21d42001-05-05Mirar (Pontus Hagland) //! method Month month() //! method Month month(int n) //! method Month month(string name) //! The Year type overloads the month() method, //! so it is possible to get a specified month //! by string: //! //! <tt>year-&gt;month("April")</tt> //! //! The integer and no argument behavior is inherited //! from <ref to=YMD.month>YMD</ref>().
78fd532000-07-12Mirar (Pontus Hagland)  cMonth month(int|string ... mp) { if (sizeof(mp) && stringp(mp[0])) { int num=((int)mp[0]) || rules->language[f_month_number_from_name](mp[0]); if (!num)
563bd72004-01-11Martin Nilsson  error("no such month %O in %O\n",mp[0],this);
78fd532000-07-12Mirar (Pontus Hagland)  return ::month(num); } else return ::month(@mp); }
dc21d42001-05-05Mirar (Pontus Hagland) //! method Week week() //! method Week week(int n) //! method Week week(string name) //! The Year type overloads the week() method, //! so it is possible to get a specified week //! by name: //! //! <tt>year-&gt;week("17")</tt> //! <tt>year-&gt;week("w17")</tt> //! //! The integer and no argument behavior is inherited //! from <ref to=YMD.week>YMD</ref>(). //! //! This is useful, since the first week of a year //! not always (about half the years, in the ISO calendar) //! is numbered '1'. //!
78fd532000-07-12Mirar (Pontus Hagland)  cWeek week(int|string ... mp) { if (sizeof(mp) && stringp(mp[0])) { int num; sscanf(mp[0],"%d",num); sscanf(mp[0],"w%d",num); cWeek w=::week(num); if (w->week_no()==num) return w; return ::week(num-(w->week_no()-num)); } else return ::week(@mp); }
9f0b6c2008-02-07Martin Stjernholm  cYear set_ruleset(Calendar.Ruleset r)
78fd532000-07-12Mirar (Pontus Hagland)  { return Year("ymd_y",r,y,yjd,n); } } // ----------------------------------------------------------------
091c412012-05-04Henrik Grubbström (Grubba) //! class Month //! inherits YMD
78fd532000-07-12Mirar (Pontus Hagland) // ---------------------------------------------------------------- function(mixed...:cMonth) Month=cMonth; class cMonth { inherit YMD; constant is_month=1; int nd; // number of days int nw; // number of weeks
d7db5d2013-05-31Martin Nilsson  protected void create(mixed ...args)
78fd532000-07-12Mirar (Pontus Hagland)  { if (!sizeof(args)) { rules=default_rules; create_unixtime_default(time()); return; } else switch (args[0]) { case "ymd_ym": rules=args[1]; y=args[2]; m=args[3]; n=args[4]; md=1;
9ec4ca2008-01-23Martin Stjernholm  wy=w=wd=CALUNKNOWN;
78fd532000-07-12Mirar (Pontus Hagland)  [y,m,nd,yd]=year_month_from_month(y,m); yjd=julian_day_from_year(y); jd=yjd+yd-1; if (n!=1) nd=CALUNKNOWN; nw=CALUNKNOWN; return; case "ymd_yjmw": rules=args[1]; y=args[2]; yjd=args[3]; jd=args[4]; yd=1+jd-yjd; m=args[5]; n=args[6]; wd=args[7]; w=args[8];
9ec4ca2008-01-23Martin Stjernholm  wy=args[9];
78fd532000-07-12Mirar (Pontus Hagland)  md=1; nw=nd=CALUNKNOWN; return; case "ymd_jd": rules=args[1]; create_julian_day(args[2]); n=args[3]; return;
557b582008-01-25Martin Stjernholm  case "unix": case "unix_r": case "julian": case "julian_r": // Handled by ::create. break;
78fd532000-07-12Mirar (Pontus Hagland)  default: if (intp(args[0]) && sizeof(args)==2) { create("ymd_ym",default_rules,args[0],args[1],1); if (y!=args[0]) error("month %d doesn't exist in %d\n",args[1],args[0]); return; } break; } rules=default_rules; ::create(@args); } void create_julian_day(int|float _jd) { if (floatp(_jd)) create_unixtime_default((int)((jd-2440588)*86400)); else { int zmd; [y,yjd]=year_from_julian_day(jd=_jd); [m,zmd,nd,yd]=month_from_yday(y,1+jd-yjd); jd=yd+yjd-1; n=1; md=1;
9ec4ca2008-01-23Martin Stjernholm  nw=wd=w=wy=CALUNKNOWN; // unknown
78fd532000-07-12Mirar (Pontus Hagland)  } }
d7db5d2013-05-31Martin Nilsson  protected string _sprintf(int t,mapping m)
78fd532000-07-12Mirar (Pontus Hagland)  { // return sprintf("month y=%d yjd=%d m=%d jd=%d yd=%d n=%d nd=%d", // y,yjd,m,jd,yd,n,number_of_days()); switch (t) { case 'O': if (n!=1) return sprintf("Month(%s)",nice_print_period()); return sprintf("Month(%s)",nice_print());
61ec5e2001-06-09Mirar (Pontus Hagland)  case 't': return "Calendar."+calendar_name()+".Month";
78fd532000-07-12Mirar (Pontus Hagland)  default:
61ec5e2001-06-09Mirar (Pontus Hagland)  return ::_sprintf(t,m);
78fd532000-07-12Mirar (Pontus Hagland)  } } string nice_print() {
2c364e2000-11-13Mirar (Pontus Hagland)  return sprintf("%s %s", month_name(), year_name()); } string format_nice() { return sprintf("%s %s", month_name(), year_name());
78fd532000-07-12Mirar (Pontus Hagland)  }
2c364e2000-11-13Mirar (Pontus Hagland) 
78fd532000-07-12Mirar (Pontus Hagland)  string nice_print_period() {
77f1082006-01-17Martin Bähr  if (!n) return day()->nice_print()+" "+minute()->nice_print()+" sharp";
78fd532000-07-12Mirar (Pontus Hagland)  cMonth mo=month(-1); if (mo->y==y) return sprintf("%s..%s %s", month_shortname(), mo->month_shortname(), year_name());
3fc92e2008-05-23Martin Stjernholm  return nice_print()+" .. "+mo->nice_print();
78fd532000-07-12Mirar (Pontus Hagland)  }
3fc92e2008-05-23Martin Stjernholm  TimeRange beginning()
78fd532000-07-12Mirar (Pontus Hagland)  {
9ec4ca2008-01-23Martin Stjernholm  return Month("ymd_yjmw",rules,y,yjd,jd,m,0,wd,w,wy)
78fd532000-07-12Mirar (Pontus Hagland)  ->autopromote(); }
3fc92e2008-05-23Martin Stjernholm  TimeRange end()
78fd532000-07-12Mirar (Pontus Hagland)  { return Month("ymd_ym",rules,y,m+n,0) ->autopromote(); } // --- month position and distance TimeRange distance(TimeRange to) { if (to->is_timeofday) return hour()->distance(to); if (to->is_ymd) { if (to->is_month || to->is_year) { int n1=months_to_month(to->y,to->is_year?1:to->m); if (n1<0) error("distance: negative distance (%d months)\n",n1);
9ec4ca2008-01-23Martin Stjernholm  return Month("ymd_yjmw",rules,y,yjd,jd,m,n1,wd,w,wy)
78fd532000-07-12Mirar (Pontus Hagland)  ->autopromote(); } int d1=jd; int d2=to->jd; if (d2<d1) error("distance: negative distance (%d days)\n",d2-d1);
9ec4ca2008-01-23Martin Stjernholm  return Day("ymd_ydmw",rules,y,yjd,jd,yd,d2-d1,m,1,wy,w,wd,mnd)
78fd532000-07-12Mirar (Pontus Hagland)  ->autopromote(); } error("distance: Incompatible type %O\n",to); }
9eaf1d2008-06-28Martin Nilsson  protected void convert_from(TimeRange other)
78fd532000-07-12Mirar (Pontus Hagland)  { ::convert_from(other); if (other->number_of_months) n=other->number_of_months(); else n=0; } TimeRange _move(int x,YMD step) { if (step->is_year) return Month("ymd_ym",rules,y+x*step->n,m,n) ->autopromote(); if (step->is_month) return Month("ymd_ym",rules,y,m+x*step->n,n) ->autopromote(); return Day("ymd_jd",rules,jd+x*step->number_of_days(),number_of_days()) ->autopromote(); } TimeRange place_day(int day,int day_n,void|int force) { if (day>number_of_days()) return 0; // doesn't exist return Day("ymd_jd",rules,jd+day-1,day_n)->autopromote(); } TimeRange place(TimeRange what,void|int force) { if (what->is_year) return year()->place(what,force); // just fallback if (what->is_day) return place_day(what->month_day(),what->n,force);
c4a0d92001-06-09Mirar (Pontus Hagland)  if (what->is_month) return Month("ymd_ym",rules,y,m,what->number_of_months()) ->autopromote(); if (what->is_week) return place(what->day(),force)->week(); if (what->is_timeofday) return place(what->day(),force)->place(what,force);
78fd532000-07-12Mirar (Pontus Hagland)  error("place: Incompatible type %O\n",what); } // --- Month to other units int number_of_years() { if (n<=1) return 1; [int y2,int m2,int nd2,int yd2]=year_month_from_month(y,m+n); return 1+y2-y; } int number_of_days() { if (nd!=CALUNKNOWN) return nd; [int y2,int m2,int nd2,int yd2]=year_month_from_month(y,m+n); return nd=julian_day_from_year(y2)+yd2-jd-1; } int number_of_weeks() { if (nw!=CALUNKNOWN) return nw; [int y2,int m2,int nd2,int yd2]=year_month_from_month(y,m+n); return nw= Week("julian_r",jd,rules) ->range(Week("julian_r",julian_day_from_year(y2)+yd2-2,rules)) ->number_of_weeks(); } int number_of_months() { return n; }
9f0b6c2008-02-07Martin Stjernholm  cMonth set_ruleset(Calendar.Ruleset r)
78fd532000-07-12Mirar (Pontus Hagland)  {
9ec4ca2008-01-23Martin Stjernholm  return Month("ymd_yjmw",r,y,yjd,jd,m,n,wd,w,wy);
78fd532000-07-12Mirar (Pontus Hagland)  } // --- needs to be defined
9eaf1d2008-06-28Martin Nilsson  protected int months_to_month(int y,int m);
78fd532000-07-12Mirar (Pontus Hagland) } // ---------------------------------------------------------------- //! class Week //! The Calendar week represents a standard time period of //! a week. In the Gregorian calendar, the standard week //! starts on a sunday and ends on a saturday; in the ISO //! calendar, it starts on a monday and ends on a sunday. //! //! The week are might not be aligned to the year, and thus //! the week may cross year borders and the year of //! the week might not be the same as the year of all the //! days in the week. The basic rule is that the week year //! is the year that has the most days in the week, but //! since week number only is specified in the ISO calendar //! - and derivates - the week number of most calendars //! is the week number of most of the days in the ISO //! 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.
091c412012-05-04Henrik Grubbström (Grubba) //! //! inherits YMD
78fd532000-07-12Mirar (Pontus Hagland) // ----------------------------------------------------------------
dc21d42001-05-05Mirar (Pontus Hagland)  function(mixed...:cWeek) Week=cWeek; class cWeek
78fd532000-07-12Mirar (Pontus Hagland) { inherit YMD;
3fc92e2008-05-23Martin Stjernholm  // Note: wy, w and wd are never CALUNKNOWN in this class.
78fd532000-07-12Mirar (Pontus Hagland)  constant is_week=1;
dc21d42001-05-05Mirar (Pontus Hagland) //! //! method void create("unix",int unix_time) //! method void create("julian",int|float julian_day) //! method void create(int year,int week) //! It's possible to create the standard week //! by using three different methods; either the normal //! way - from standard unix time or the julian day, //! and also, for more practical use, from year and week //! number. //!
d7db5d2013-05-31Martin Nilsson  protected void create(mixed ...args)
78fd532000-07-12Mirar (Pontus Hagland)  { if (!sizeof(args)) { rules=default_rules; create_unixtime_default(time()); return; } else switch (args[0]) { case "ymd_yw": rules=args[1];
3fc92e2008-05-23Martin Stjernholm  wy=args[2];
78fd532000-07-12Mirar (Pontus Hagland)  w=args[3]; n=args[4]; m=md=CALUNKNOWN;
3fc92e2008-05-23Martin Stjernholm  [wy,w,wd,int nd,jd]=week_from_week(wy,w); int wyjd=julian_day_from_year(wy); if (wyjd > jd) y = wy - 1, yjd = julian_day_from_year (y); else y = wy, yjd = wyjd;
78fd532000-07-12Mirar (Pontus Hagland)  yd=1+jd-yjd; if (n!=1) nd=CALUNKNOWN; return; case "ymd_yjwm": rules=args[1]; y=args[2]; yjd=args[3]; jd=args[4]; yd=1+jd-yjd;
3fc92e2008-05-23Martin Stjernholm  wy=args[5]; w=args[6]; n=args[7]; md=args[8]; m=args[9]; mnd=args[10];
78fd532000-07-12Mirar (Pontus Hagland)  wd=1; nd=CALUNKNOWN; return; case "ymd_jd": rules=args[1]; create_julian_day(args[2]); n=args[3]; return;
557b582008-01-25Martin Stjernholm  case "unix": case "unix_r": case "julian": case "julian_r": // Handled by ::create. break;
78fd532000-07-12Mirar (Pontus Hagland)  default: if (intp(args[0]) && sizeof(args)==2) { create("ymd_yw",default_rules,args[0],args[1],1);
3fc92e2008-05-23Martin Stjernholm  if (wy!=args[0]) // FIXME: Allow weeks 0 and 53/54 if they contain // at least one day in this year.
9ec4ca2008-01-23Martin Stjernholm  error("Week %d doesn't exist in %d\n",args[1],args[0]);
78fd532000-07-12Mirar (Pontus Hagland)  return; } break; } rules=default_rules; ::create(@args); } void create_julian_day(int|float _jd) { if (floatp(_jd)) create_unixtime_default((int)((jd-2440588)*86400)); else { int zwd;
3fc92e2008-05-23Martin Stjernholm  [wy,w,zwd,int nd,jd]=week_from_julian_day(_jd); [y,yjd]=year_from_julian_day(_jd);
78fd532000-07-12Mirar (Pontus Hagland)  yd=1+jd-yjd; n=1; wd=1; md=m=CALUNKNOWN; // unknown } }
d7db5d2013-05-31Martin Nilsson  protected string _sprintf(int t,mapping m)
78fd532000-07-12Mirar (Pontus Hagland)  { // return sprintf("week y=%d yjd=%d w=%d jd=%d yd=%d n=%d nd=%d", // y,yjd,w,jd,yd,n,number_of_days()); switch (t) { case 'O': if (n!=1) return sprintf("Week(%s)",nice_print_period()); return sprintf("Week(%s)",nice_print());
61ec5e2001-06-09Mirar (Pontus Hagland)  case 't': return "Calendar."+calendar_name()+".Week";
78fd532000-07-12Mirar (Pontus Hagland)  default:
61ec5e2001-06-09Mirar (Pontus Hagland)  return ::_sprintf(t,m);
78fd532000-07-12Mirar (Pontus Hagland)  } }
3fc92e2008-05-23Martin Stjernholm  int year_no() { return wy>0?wy:-1+wy; } int year_day() //! Can be less than 1 for the first week of the year if it begins //! in the previous year. { return y != wy ? 1 + jd - julian_day_from_year (wy) : yd; }
78fd532000-07-12Mirar (Pontus Hagland)  string nice_print() { return sprintf("%s %s", week_name(), year_name()); }
2c364e2000-11-13Mirar (Pontus Hagland)  string format_nice() { return sprintf("%s %s", week_name(), year_name()); }
78fd532000-07-12Mirar (Pontus Hagland)  string nice_print_period() {
77f1082006-01-17Martin Bähr  if (!n) return day()->nice_print()+" "+minute()->nice_print()+" sharp";
78fd532000-07-12Mirar (Pontus Hagland)  cWeek wo=week(-1);
3fc92e2008-05-23Martin Stjernholm  if (wo->wy==wy)
78fd532000-07-12Mirar (Pontus Hagland)  return sprintf("%s..%s %s", week_name(), wo->week_name(), year_name());
3fc92e2008-05-23Martin Stjernholm  return nice_print()+" .. "+wo->nice_print();
78fd532000-07-12Mirar (Pontus Hagland)  }
3fc92e2008-05-23Martin Stjernholm  TimeRange beginning()
78fd532000-07-12Mirar (Pontus Hagland)  {
3fc92e2008-05-23Martin Stjernholm  return Week("ymd_yjwm",rules,y,yjd,jd,wy,w,0,md,m,mnd)
78fd532000-07-12Mirar (Pontus Hagland)  ->autopromote(); }
3fc92e2008-05-23Martin Stjernholm  TimeRange end()
78fd532000-07-12Mirar (Pontus Hagland)  {
3fc92e2008-05-23Martin Stjernholm  return Week("ymd_yw",rules,wy,w+n,0)
78fd532000-07-12Mirar (Pontus Hagland)  ->autopromote(); } // --- week position and distance TimeRange distance(TimeRange to) { if (to->is_timeofday) return hour()->distance(to); if (to->is_week) {
3fc92e2008-05-23Martin Stjernholm  int n1=weeks_to_week(to->wy,to->w);
78fd532000-07-12Mirar (Pontus Hagland)  if (n1<0) error("distance: negative distance (%d weeks)\n",n1);
3fc92e2008-05-23Martin Stjernholm  return Week("ymd_yjwm",rules,y,yjd,jd,wy,w,n1,md,m,mnd)
78fd532000-07-12Mirar (Pontus Hagland)  ->autopromote(); } if (to->julian_day) { int d1=jd; int d2=to->julian_day(); if (d2<d1) error("distance: negative distance (%d days)\n",d2-d1);
9ec4ca2008-01-23Martin Stjernholm  return Day("ymd_ydmw",rules,y,yjd,jd,yd,d2-d1,m,md,wy,w,1,mnd)
78fd532000-07-12Mirar (Pontus Hagland)  ->autopromote(); } error("distance: Incompatible type %O\n",to); }
9eaf1d2008-06-28Martin Nilsson  protected void convert_from(TimeRange other)
78fd532000-07-12Mirar (Pontus Hagland)  { ::convert_from(other); if (other->number_of_weeks) n=other->number_of_weeks(); else n=0; } TimeRange _move(int x,YMD step) { if (step->is_week)
3fc92e2008-05-23Martin Stjernholm  return Week("ymd_yw",rules,wy,w+x*step->n,n)
78fd532000-07-12Mirar (Pontus Hagland)  ->autopromote();
3fc92e2008-05-23Martin Stjernholm  if (step->is_year) { TimeRange stepped = year()->add(x,step); if (TimeRange placed = stepped->place(this,0)) return placed; // If we couldn't place our week in the target year it means // we're in week 53 and the target year got only 52 weeks. We // return the closest week of the target year, i.e. week 52. return Week ("ymd_yw", rules, stepped->y, 52, n); }
78fd532000-07-12Mirar (Pontus Hagland)  if (step->number_of_days) return Day("ymd_jd",rules, jd+x*step->number_of_days(),number_of_days()) ->autopromote(); error("add: Incompatible type %O\n",step); } TimeRange place_day(int day,int day_n,int force) { if (day>number_of_days()) if (!force) return 0; else return Day("ymd_jd",rules,jd+day-1,max(0,day_n-1))->autopromote(); return Day("ymd_jd",rules,jd+day-1,day_n)->autopromote(); } TimeRange place(TimeRange what,void|int force) {
adb9c52000-10-18Mirar (Pontus Hagland)  if (what->is_supertimerange) return what->mend_overlap(map(what->parts,place,force)); // return `|(@map(what->parts,place,force));
78fd532000-07-12Mirar (Pontus Hagland)  if (what->is_year) return year()->place(what,force); // just fallback
c4a0d92001-06-09Mirar (Pontus Hagland)  if (what->is_month) return month()->place(what,force); // just fallback
78fd532000-07-12Mirar (Pontus Hagland) 
c4a0d92001-06-09Mirar (Pontus Hagland)  if (what->is_week)
3fc92e2008-05-23Martin Stjernholm  return Week("ymd_yw",rules,wy,w,what->number_of_weeks());
c4a0d92001-06-09Mirar (Pontus Hagland) 
78fd532000-07-12Mirar (Pontus Hagland)  if (what->is_day) return place_day(what->week_day(),what->n,force);
adb9c52000-10-18Mirar (Pontus Hagland)  if (what->is_timeofday) return place(what->day(),force)->place(what,force);
78fd532000-07-12Mirar (Pontus Hagland)  error("place: Incompatible type %O\n",what); } // --- Week to other units int number_of_years() {
3fc92e2008-05-23Martin Stjernholm  if (n<=1 && y == wy) return 1;
78fd532000-07-12Mirar (Pontus Hagland) 
3fc92e2008-05-23Martin Stjernholm  [int y2,int w2,int wd2,int nd2,int jd2]=week_from_week(wy,w+n);
78fd532000-07-12Mirar (Pontus Hagland)  return 1+y2-y; } int number_of_months() { if (!n) return 1; // cheat return Day("ymd_jd",rules,jd,number_of_days()) ->number_of_months(); } int number_of_weeks() { return n; } int number_of_days();
dc21d42001-05-05Mirar (Pontus Hagland) //! method Day day() //! method Day day(int n) //! method Day day(string name) //! The Week type overloads the day() method, //! so it is possible to get a specified weekday //! by string: //! //! <tt>week-&gt;day("sunday")</tt> //! //! The integer and no argument behavior is inherited //! from <ref to=YMD.day>YMD</ref>(). //! //! note: //! the weekday-from-string routine is language dependent.
78fd532000-07-12Mirar (Pontus Hagland)  cDay day(int|string ... mp) { if (sizeof(mp) && stringp(mp[0])) { int num=((int)mp[0]) || rules->language[f_week_day_number_from_name](mp[0]); if (!num)
563bd72004-01-11Martin Nilsson  error("no such day %O in %O\n",mp[0],this);
78fd532000-07-12Mirar (Pontus Hagland)  return ::day(num); } else return ::day(@mp); }
9f0b6c2008-02-07Martin Stjernholm  cWeek set_ruleset(Calendar.Ruleset r)
78fd532000-07-12Mirar (Pontus Hagland)  {
3fc92e2008-05-23Martin Stjernholm  return Week("ymd_yjwm",r,y,yjd,jd,wy,w,n,md,m,mnd);
78fd532000-07-12Mirar (Pontus Hagland)  } // --- needs to be defined
9eaf1d2008-06-28Martin Nilsson  protected int weeks_to_week(int y,int m);
78fd532000-07-12Mirar (Pontus Hagland) } // ----------------------------------------------------------------
091c412012-05-04Henrik Grubbström (Grubba) //! class Day //! inherits YMD
78fd532000-07-12Mirar (Pontus Hagland) // ---------------------------------------------------------------- class cDay { inherit YMD; constant is_day=1; int nw;
dc21d42001-05-05Mirar (Pontus Hagland) //! //! method void create("unix",int unix_time) //! method void create("julian",int|float julian_day) //! method void create(int year,int month,int day) //! method void create(int year,int year_day) //! method void create(int julian_day) //! It's possible to create the day //! by using five different methods; either the normal //! way - from standard unix time or the julian day, //! and also, for more practical use, from year, month and day, //! from year and day of year, and from julian day //! without extra fuzz.
d7db5d2013-05-31Martin Nilsson  protected void create(mixed ...args)
78fd532000-07-12Mirar (Pontus Hagland)  { if (!sizeof(args)) { rules=default_rules; create_unixtime_default(time()); return; } else switch (args[0]) { case "ymd_ydmw": rules=args[1]; y=args[2]; yjd=args[3]; jd=args[4]; yd=args[5]; n=args[6]; m=args[7]; md=args[8];
9ec4ca2008-01-23Martin Stjernholm  wy=args[9]; w=args[10]; wd=args[11]; mnd=args[12];
78fd532000-07-12Mirar (Pontus Hagland)  nw=CALUNKNOWN; return; case "ymd_yd": rules=args[1]; y=args[2]; yjd=args[3]; jd=args[4]; yd=args[5]; n=args[6];
9ec4ca2008-01-23Martin Stjernholm  wy=wd=nw=md=m=w=CALUNKNOWN;
78fd532000-07-12Mirar (Pontus Hagland)  return; case "ymd_jd": rules=args[1]; create_julian_day(args[2]); n=args[3];
9ec4ca2008-01-23Martin Stjernholm  wy=wd=nw=md=m=w=CALUNKNOWN;
78fd532000-07-12Mirar (Pontus Hagland)  return; case "unix_r": case "julian_r": case "unix": case "julian":
557b582008-01-25Martin Stjernholm  // Handled by ::create.
78fd532000-07-12Mirar (Pontus Hagland)  break; default: rules=default_rules;
9ec4ca2008-01-23Martin Stjernholm  wy=wd=nw=md=m=w=CALUNKNOWN;
78fd532000-07-12Mirar (Pontus Hagland)  n=1; switch (sizeof(args)) { case 1: if (intp(args[0])) { create_julian_day(args[0]); return; } break; case 2: if (stringp(args[0])) y=default_rules->language[f_year_number_from_name] (args[0]); else if (intp(args[0])) y=args[0]; else break; if (!intp(args[1])) break; yd=args[1]; yjd=julian_day_from_year(y); jd=yjd+yd-1; return; case 3: if (stringp(args[0])) y=default_rules->language[f_year_number_from_name] (args[0]); else if (intp(args[0])) y=args[0]; else break; if (!intp(args[1]) || !intp(args[2])) break; md=args[2]; [y,m,int nmd,int myd]= year_month_from_month(y,args[1]); if (m!=args[1] || y!=args[0]) error("No such month (%d-%02d)\n",args[0],args[1]); yjd=julian_day_from_year(y); md=args[2]; jd=yjd+myd+md-2; yd=jd-yjd+1; if (md>nmd || md<1) error("No such day of month (%d-%02d-%02d)\n", @args); return; } } rules=default_rules; ::create(@args); } void create_julian_day(int|float _jd) { n=1;
9ec4ca2008-01-23Martin Stjernholm  nw=md=m=wd=w=wy=CALUNKNOWN; // unknown
78fd532000-07-12Mirar (Pontus Hagland)  if (floatp(_jd)) { create_unixtime_default((int)((jd-2440588)*86400)); } else { [y,yjd]=year_from_julian_day(jd=_jd); yd=1+jd-yjd; } }
d7db5d2013-05-31Martin Nilsson  protected string _sprintf(int t,mapping m)
78fd532000-07-12Mirar (Pontus Hagland)  { switch (t) { case 'O':
60a8fa2004-12-15Martin Nilsson  catch { if (n!=1)
78fd532000-07-12Mirar (Pontus Hagland)  return sprintf("Day(%s)",nice_print_period());
60a8fa2004-12-15Martin Nilsson  return sprintf("Day(%s)",nice_print()); }; return sprintf("Day(%d)", unix_time());
61ec5e2001-06-09Mirar (Pontus Hagland)  case 't': return "Calendar."+calendar_name()+".Day";
78fd532000-07-12Mirar (Pontus Hagland)  default:
61ec5e2001-06-09Mirar (Pontus Hagland)  return ::_sprintf(t,m);
78fd532000-07-12Mirar (Pontus Hagland)  } } string nice_print() { if (m==CALUNKNOWN) make_month(); if (wd==CALUNKNOWN) make_week();
60a8fa2004-12-15Martin Nilsson  return
78fd532000-07-12Mirar (Pontus Hagland)  sprintf("%s %s %s %s", week_day_shortname(), month_day_name(),month_shortname(), year_name()); }
2c364e2000-11-13Mirar (Pontus Hagland)  string format_nice() { if (m==CALUNKNOWN) make_month(); if (calendar()->Year()!=year()) return sprintf("%s %s %s", month_day_name(),month_shortname(), year_name()); else return sprintf("%s %s", month_day_name(),month_shortname()); }
78fd532000-07-12Mirar (Pontus Hagland)  string nice_print_period() { // return nice_print()+" n="+n+"";
77f1082006-01-17Martin Bähr  if (!n) return nice_print()+" "+minute()->nice_print()+" sharp";
78fd532000-07-12Mirar (Pontus Hagland)  return nice_print()+" .. "+day(-1)->nice_print(); }
3fc92e2008-05-23Martin Stjernholm  TimeRange beginning()
78fd532000-07-12Mirar (Pontus Hagland)  {
9ec4ca2008-01-23Martin Stjernholm  return Day("ymd_ydmw",rules,y,yjd,jd,yd,0,m,md,wy,w,wd,mnd);
78fd532000-07-12Mirar (Pontus Hagland)  }
3fc92e2008-05-23Martin Stjernholm  TimeRange end()
78fd532000-07-12Mirar (Pontus Hagland)  { return Day("ymd_jd",rules,jd+n,0) ->autopromote(); }
9eaf1d2008-06-28Martin Nilsson  protected void convert_from(TimeRange other)
78fd532000-07-12Mirar (Pontus Hagland)  { ::convert_from(other); if (other->number_of_days) n=other->number_of_days(); else n=0; } // --- Day _move
9eaf1d2008-06-28Martin Nilsson  protected TimeRange _move(int x,YMD step)
78fd532000-07-12Mirar (Pontus Hagland)  {
7a51702008-02-05Martin Stjernholm  if (step->is_year) { TimeRange stepped = year()->add(x,step); if (TimeRange placed = stepped->place(this,0)) return placed; // If we couldn't place our day in the target year it means // we're on a leap day and the target year doesn't have any. // We return the closest day in the same month. TimeRange placed = stepped->place (month()); if (md == CALUNKNOWN) make_month(); return placed->day (md < placed->number_of_days() ? md : -1); }
78fd532000-07-12Mirar (Pontus Hagland) 
7a51702008-02-05Martin Stjernholm  if (step->is_month) { TimeRange stepped = month()->add(x,step); if (TimeRange placed = stepped->place(this,0)) return placed; // The target month is shorter and our date doesn't exist in // it. We return the closest (i.e. last) day of the target // month. return stepped->day (-1); }
78fd532000-07-12Mirar (Pontus Hagland)  if (step->is_week)
563bd72004-01-11Martin Nilsson  return week()->add(x,step)->place(this,1);
78fd532000-07-12Mirar (Pontus Hagland)  if (step->is_day) return Day("ymd_jd",rules,jd+x*step->n,n) ->autopromote(); error("_move: Incompatible type %O\n",step); }
c4a0d92001-06-09Mirar (Pontus Hagland)  TimeRange place(TimeRange what,int|void force)
78fd532000-07-12Mirar (Pontus Hagland)  { if (what->is_timeofday) { int lux= what->ux- Day("unix_r",what->unix_time(),what->ruleset()) ->unix_time();
9371cd2001-07-18Mirar (Pontus Hagland)  TimeRange res;
b8c6a72001-07-18Mirar (Pontus Hagland) 
78fd532000-07-12Mirar (Pontus Hagland)  if (what->is_timeofday_f)
9371cd2001-07-18Mirar (Pontus Hagland)  res=
78fd532000-07-12Mirar (Pontus Hagland)  Fraction("timeofday_f",rules,
9371cd2001-07-18Mirar (Pontus Hagland)  lux+unix_time(),what->ns,what->s_len,what->ns_len); else res=Second("timeofday",rules,unix_time()+lux,what->len);
78fd532000-07-12Mirar (Pontus Hagland) 
9371cd2001-07-18Mirar (Pontus Hagland)  if (what->rules->timezone->is_dst_timezone || rules->timezone->is_dst_timezone) { int u0=what->utc_offset()-what->day()->utc_offset(); int u1=res->utc_offset()-utc_offset(); // werror("%O %O\n",u0,u1); if (u1-u0) res=res->add(u1-u0,Second); else res=res->autopromote();
9f3c3f2001-07-18Mirar (Pontus Hagland)  if (!force) { if (res->hour_no()!=what->hour_no()) error("place: no such time of "
ce6f672008-09-01Henrik Grubbström (Grubba)  "day (DST shift): %O\n", what);
9f3c3f2001-07-18Mirar (Pontus Hagland)  }
9371cd2001-07-18Mirar (Pontus Hagland)  } else res=res->autopromote(); return res;
78fd532000-07-12Mirar (Pontus Hagland)  }
c4a0d92001-06-09Mirar (Pontus Hagland)  if (what->is_year) return year()->place(what,force); // just fallback if (what->is_month) return month()->place(what,force); // just fallback if (what->is_week) return week()->place(what,force); // just fallback if (what->is_day) return Day("ymd_jd",rules,jd,what->number_of_days()) ->autopromote();
78fd532000-07-12Mirar (Pontus Hagland)  error("place: Incompatible type %O\n",what); } TimeRange distance(TimeRange to) { if (to->is_timeofday) return hour()->distance(to); if (to->is_ymd) { int d1=jd; int d2=to->jd; if (d2<d1) error("distance: negative distance (%d days)\n",d2-d1);
9ec4ca2008-01-23Martin Stjernholm  return Day("ymd_ydmw",rules,y,yjd,jd,yd,d2-d1,m,md,wy,w,wd,mnd)
78fd532000-07-12Mirar (Pontus Hagland)  ->autopromote(); } error("distance: Incompatible type %O\n",to); } // --- Day to other YMD int number_of_days() { return n; } int number_of_years() { if (n<=1) return 1; return 1+year_from_julian_day(jd+n-1)[0]-y; } int number_of_weeks() { if (nw!=CALUNKNOWN) return nw; if (n<=1) return nw=1; return nw= Week("julian_r",jd,rules) ->range(Week("julian_r",jd+n-1,rules)) ->number_of_weeks(); }
9f0b6c2008-02-07Martin Stjernholm  cDay set_ruleset(Calendar.Ruleset r)
78fd532000-07-12Mirar (Pontus Hagland)  {
9ec4ca2008-01-23Martin Stjernholm  return Day("ymd_ydmw",r,y,yjd,jd,yd,n,m,md,wy,w,wd,mnd);
78fd532000-07-12Mirar (Pontus Hagland)  } // backwards compatible with calendar I string iso_name() { return format_ymd(); } string iso_short_name() { return format_ymd_short(); } }
6f29262002-06-11Martin Stjernholm function(mixed...:cDay) Day=cDay;
78fd532000-07-12Mirar (Pontus Hagland) //------------------------------------------------------------------------ //- class YMD_Time //------------------------------------------------------------------------ class YMD_Time { #define MKRBASE \ do \ { \ int n; \ if (!rbase) \ rbase=Day("unix_r",this->ux,this->rules)->range(Day("unix_r",this->ux+this->len,this->rules)); \ } while (0) #define RBASE (this->base || this->make_base()) cDay day(int ...n) { return RBASE->day(@n); } cDay number_of_days() { return RBASE->number_of_days(); } array(cDay) days(int ...r) { return RBASE->days(@r); } cMonth month(int ...n) { return RBASE->month(@n); } cMonth number_of_months() { return RBASE->number_of_months(); } array(cMonth) months(int ...r) { return RBASE->months(@r); } cWeek week(int ...n) { return RBASE->week(@n); } cWeek number_of_weeks() { return RBASE->number_of_weeks(); } array(cWeek) weeks(int ...r) { return RBASE->weeks(@r); } cYear year(int ...n) { return RBASE->year(@n); } cYear number_of_years() { return RBASE->number_of_years(); } array(cYear) years(int ...r) { return RBASE->years(@r); } int year_no() { return RBASE->year_no(); } int month_no() { return RBASE->month_no(); } int week_no() { return RBASE->week_no(); } int month_name() { return RBASE->month_name(); }
7e39942009-03-21Henrik Grubbström (Grubba)  string month_shortname() { return RBASE->month_shortname(); }
78fd532000-07-12Mirar (Pontus Hagland)  int month_day() { return RBASE->month_day(); }
7e39942009-03-21Henrik Grubbström (Grubba)  string month_day_name() { return RBASE->month_day_name(); }
78fd532000-07-12Mirar (Pontus Hagland)  int week_day() { return RBASE->week_day(); } int year_day() { return RBASE->year_day(); }
85f0412000-09-17Mirar (Pontus Hagland)  int year_name() { return RBASE->year_name(); }
78fd532000-07-12Mirar (Pontus Hagland)  string week_name() { return RBASE->week_name(); } string week_day_name() { return RBASE->week_day_name(); } string week_day_shortname() { return RBASE->week_day_shortname(); } int leap_year() { return RBASE->leap_year(); } string format_iso_ymd() { return RBASE->format_iso_ymd(); } string format_ext_ymd() { return RBASE->format_ext_ymd(); } string format_ymd() { return RBASE->format_ymd(); } string format_ymd_short() { return RBASE->format_ymd_short(); } string format_ymd_xshort() { return RBASE->format_ymd_xshort(); } string format_iso_week() { return RBASE->format_iso_week(); } 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 } #define OVERLOAD_TIMEOFDAY \ \
beb21d2008-06-28Martin Nilsson  protected int(0..1) create_backtry(mixed ... args) \
78fd532000-07-12Mirar (Pontus Hagland)  { \ if (sizeof(args)>=5 && \ (intp(args[0])||stringp(args[0])) && \ intp(args[1]) && \ intp(args[2])) \ { \ base=Day(@args[..2]); \ return ::create_backtry(@args[3..]); \ } \ return ::create_backtry(@args); \ } //------------------------------------------------------------------------ //! class Hour
dc21d42001-05-05Mirar (Pontus Hagland) //! inherits Time.Hour //! inherits YMD
55f4ec2001-04-27Henrik Grubbström (Grubba) //------------------------------------------------------------------------
dc21d42001-05-05Mirar (Pontus Hagland)  class cHour
78fd532000-07-12Mirar (Pontus Hagland) { inherit Time::cHour; inherit YMD_Time; OVERLOAD_TIMEOFDAY; }
091c412012-05-04Henrik Grubbström (Grubba) //------------------------------------------------------------------------ //! class Minute //! inherits Time.Minute //! inherits YMD //------------------------------------------------------------------------
78fd532000-07-12Mirar (Pontus Hagland) class cMinute { inherit Time::cMinute; inherit YMD_Time; OVERLOAD_TIMEOFDAY; }
091c412012-05-04Henrik Grubbström (Grubba) //------------------------------------------------------------------------ //! class Second //! inherits Time.Second //! inherits YMD //------------------------------------------------------------------------
78fd532000-07-12Mirar (Pontus Hagland) class cSecond { inherit Time::cSecond; inherit YMD_Time; OVERLOAD_TIMEOFDAY; }
091c412012-05-04Henrik Grubbström (Grubba) //------------------------------------------------------------------------ //! class Fraction //! inherits Time.Fraction //! inherits YMD //------------------------------------------------------------------------
78fd532000-07-12Mirar (Pontus Hagland) class cFraction { inherit Time::cFraction; inherit YMD_Time; OVERLOAD_TIMEOFDAY; }
091c412012-05-04Henrik Grubbström (Grubba) //------------------------------------------------------------------------ //! class SuperTimeRange //! inherits Time.SuperTimeRange //------------------------------------------------------------------------
78fd532000-07-12Mirar (Pontus Hagland) 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); } int number_of_months() { return num_units("months"); } array(cWeek) weeks(int ...range) { return get_units("weeks",@range); } cWeek week(void|int n) { return get_unit("weeks",n); } int number_of_weeks() { return num_units("weeks"); } array(cDay) days(int ...range) { return get_units("days",@range); } cDay day(void|int n) { return get_unit("days",n); } int number_of_days() { return num_units("days"); } #define RBASE parts[0] int year_no() { return RBASE->year_no(); } int month_no() { return RBASE->month_no(); } int week_no() { return RBASE->week_no(); } int month_name() { return RBASE->month_name(); }
7e39942009-03-21Henrik Grubbström (Grubba)  string month_shortname() { return RBASE->month_shortname(); }
78fd532000-07-12Mirar (Pontus Hagland)  int month_day() { return RBASE->month_day(); }
7e39942009-03-21Henrik Grubbström (Grubba)  string month_day_name() { return RBASE->month_day_name(); }
78fd532000-07-12Mirar (Pontus Hagland)  int week_day() { return RBASE->week_day(); } int year_day() { return RBASE->year_day(); } string week_name() { return RBASE->week_name(); } string week_day_name() { return RBASE->week_day_name(); } string week_day_shortname() { return RBASE->week_day_shortname(); } int leap_year() { return RBASE->leap_year(); } string format_iso_ymd() { return RBASE->format_iso_ymd(); } string format_ext_ymd() { return RBASE->format_ext_ymd(); } string format_ymd() { return RBASE->format_ymd(); } string format_ymd_short() { return RBASE->format_ymd_short(); } string format_ymd_xshort() { return RBASE->format_ymd_xshort(); } string format_iso_week() { return RBASE->format_iso_week(); } 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 } //------------------------------------------------------------------------
e6d5642012-05-06Henrik Grubbström (Grubba) // Pop out doc-extractor context to the top-level scope. //! module Calendar //! submodule YMD // global convenience functions
78fd532000-07-12Mirar (Pontus Hagland) //------------------------------------------------------------------------
dc21d42001-05-05Mirar (Pontus Hagland) //! method TimeRange parse(string fmt,string arg)
78fd532000-07-12Mirar (Pontus Hagland) //! 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:
dc21d42001-05-05Mirar (Pontus Hagland) //! <pre>
78fd532000-07-12Mirar (Pontus Hagland) //! %Y absolute year //! %y dwim year (70-99 is 1970-1999, 0-69 is 2000-2069) //! %M month (number, name or short name) (needs %y) //! %W week (needs %y) //! %D date (needs %y, %m) //! %d short date (20000304, 000304) //! %a day (needs %y) //! %e weekday (needs %y, %w) //! %h hour (needs %d, %D or %W) //! %m minute (needs %h) //! %s second (needs %m)
eb22d82003-10-01Dan Nelson //! %S seconds since the Epoch (only combines with %f) //! %f fraction of a second (needs %s or %S)
78fd532000-07-12Mirar (Pontus Hagland) //! %t short time (205314, 2053)
ff685a2000-08-04Mirar (Pontus Hagland) //! %z zone
dd23d02000-08-04Mirar (Pontus Hagland) //! %p "am" or "pm"
0f0ec42000-10-26Mirar (Pontus Hagland) //! %n empty string (to be put at the end of formats)
dc21d42001-05-05Mirar (Pontus Hagland) //! </pre>
78fd532000-07-12Mirar (Pontus Hagland) //!
dc21d42001-05-05Mirar (Pontus Hagland) //! returns 0 if format doesn't match data, or the appropriate time object.
ff685a2000-08-04Mirar (Pontus Hagland) //!
dc21d42001-05-05Mirar (Pontus Hagland) //! note:
ff685a2000-08-04Mirar (Pontus Hagland) //! The zone will be a guess if it doesn't state an exact //! regional timezone (like "Europe/Stockholm") - //! most zone abbriviations (like "CET") are used by more //! then one region with it's own daylight saving rules. //! Also beware that for instance CST can be up to four different zones, //! central Australia or America being the most common. //!
dc21d42001-05-05Mirar (Pontus Hagland) //! <pre>
ff685a2000-08-04Mirar (Pontus Hagland) //! Abbreviation Interpretation //! AMT America/Manaus [UTC-4] //! AST America/Curacao [UTC-4] //! CDT America/Costa_Rica [UTC-6] //! CST America/El Salvador [UTC-6] //! EST America/Panama [UTC-5] //! GST Asia/Dubai [UTC+4] //! IST Asia/Jerusalem [UTC+2] //! WST Australia/Perth [UTC+8]
dc21d42001-05-05Mirar (Pontus Hagland) //! </pre>
ff685a2000-08-04Mirar (Pontus Hagland) //!
2c3cdd2000-08-11Mirar (Pontus Hagland) //! This mapping is modifiable in the ruleset, see
dc21d42001-05-05Mirar (Pontus Hagland) //! <ref>Ruleset.set_abbr2zone</ref>.
ff685a2000-08-04Mirar (Pontus Hagland) 
0f0ec42000-10-26Mirar (Pontus Hagland) // dwim time of day; needed to correct timezones
eb4d9c2000-08-04Mirar (Pontus Hagland) // this API may change without further notice
9eaf1d2008-06-28Martin Nilsson protected TimeRange dwim_tod(TimeRange origin,string whut,int h,int m,int s)
0f0ec42000-10-26Mirar (Pontus Hagland) {
210cfe2001-01-11Mirar (Pontus Hagland)  TimeRange tr; if (catch { tr=origin[whut](h,m,s);
36c4802003-03-30Mirar (Pontus Hagland)  }) { if (h==24 && m==0 && s==0) // special case return origin->end()->second(); else { object d=origin->day(); array(cHour) ha=origin->hours(); int n=search(ha->hour_no(),h); if (n!=-1) tr=ha[n]->minute(m)->second(s); else return 0; // no such hour } }
210cfe2001-01-11Mirar (Pontus Hagland) 
0f0ec42000-10-26Mirar (Pontus Hagland)  if (tr->hour_no()!=h || tr->minute_no()!=m) {
e5f8822000-10-26Mirar (Pontus Hagland) // werror("%O %O %O -> %O %O %O (%O)\n", // tr->hour_no(),tr->minute_no(),tr->second_no(), // h,m,s,tr);
0f0ec42000-10-26Mirar (Pontus Hagland)  if (tr->hour_no()!=h) tr=tr->add(h-tr->hour_no(),Hour); if (tr->minute_no()!=m) tr=tr->add(m-tr->minute_no(),Minute); if (tr->second_no()!=s) tr=tr->add(s-tr->second_no(),Second); if (tr->hour_no()!=h || tr->minute_no()!=m || tr->second_no()!=s) return 0; // no such hour } return tr; }
eb4d9c2000-08-04Mirar (Pontus Hagland) 
9eaf1d2008-06-28Martin Nilsson protected mapping abbr2zones;
5479552003-03-13Martin Nilsson 
0f0ec42000-10-26Mirar (Pontus Hagland) // dwim timezone and call dwim time of day above // this API may change without further notice
9eaf1d2008-06-28Martin Nilsson protected TimeRange dwim_zone(TimeRange origin,string zonename,
0f0ec42000-10-26Mirar (Pontus Hagland)  string whut,int ...args)
ff685a2000-08-04Mirar (Pontus Hagland) { if (zonename=="") return 0;
210cfe2001-01-11Mirar (Pontus Hagland) 
b7dca32013-05-28Martin Nilsson  if (zonename[0]=='"') sscanf(zonename,"\"%s\"",zonename); sscanf(zonename,"%*[ \t]%s",zonename);
676a5a2013-05-17Per Hedbor 
b7dca32013-05-28Martin Nilsson  if(sizeof(zonename)==4 && zonename[2]=='S') zonename = zonename[0..1] + zonename[3..3]; else if(sizeof(zonename)>4 && has_suffix(zonename, "DST")) zonename = zonename[..<3];
676a5a2013-05-17Per Hedbor 
b7dca32013-05-28Martin Nilsson  if (origin->rules->abbr2zone[zonename]) zonename=origin->rules->abbr2zone[zonename];
676a5a2013-05-17Per Hedbor 
b7dca32013-05-28Martin Nilsson  Calendar.Rule.Timezone zone = Calendar.Timezone[zonename];
676a5a2013-05-17Per Hedbor 
b7dca32013-05-28Martin Nilsson  if (!zone) { if (sscanf(zonename,"%[^+-]%s",string a,string b)==2 && a!="" && b!="") { TimeRange tr=dwim_zone(origin,a,whut,@args); if (!tr) return 0;
676a5a2013-05-17Per Hedbor 
b7dca32013-05-28Martin Nilsson  return dwim_tod(origin->set_timezone(
676a5a2013-05-17Per Hedbor  Calendar.Timezone.make_new_timezone( tr->timezone(), Calendar.Timezone.decode_timeskew(b))), whut,@args);
b7dca32013-05-28Martin Nilsson  } if(!abbr2zones) abbr2zones = master()->resolv("Calendar")["TZnames"]["abbr2zones"]; array pz=abbr2zones[zonename]; if (!pz) return 0; foreach (pz,string zn) { TimeRange try=dwim_zone(origin,zn,whut,@args); if (try && try->tzname()==zonename) return try; } return 0;
676a5a2013-05-17Per Hedbor  }
b7dca32013-05-28Martin Nilsson 
676a5a2013-05-17Per Hedbor  return dwim_tod(origin->set_timezone(zone),whut,@args);
ff685a2000-08-04Mirar (Pontus Hagland) }
78fd532000-07-12Mirar (Pontus Hagland) 
9eaf1d2008-06-28Martin Nilsson protected mapping(string:array) parse_format_cache=([]);
210cfe2001-01-11Mirar (Pontus Hagland) 
9eaf1d2008-06-28Martin Nilsson protected mapping dwim_year=([ "past_lower":70, "past_upper":100,
da53a82006-01-06Martin Bähr  "current_century":2000, "past_century":1900 ]);
e7dce62001-01-11Mirar (Pontus Hagland) TimeRange parse(string fmt,string arg,void|TimeRange context)
78fd532000-07-12Mirar (Pontus Hagland) {
210cfe2001-01-11Mirar (Pontus Hagland)  [string nfmt,array q]=(parse_format_cache[fmt]||({0,0}));
ff685a2000-08-04Mirar (Pontus Hagland) 
210cfe2001-01-11Mirar (Pontus Hagland)  if (!nfmt) { // nfmt=replace(fmt," %","%*[ \t]%"); // whitespace -> whitespace
32acac2008-05-14Marcus Comstedt #define ALNU "%[^ -,./:-?[-`{-¿-]"
57bc9e2001-05-18Mirar (Pontus Hagland) #define AMPM "%[ampAMP.]"
78fd532000-07-12Mirar (Pontus Hagland) #define NUME "%[0-9]"
e7dce62001-01-11Mirar (Pontus Hagland) #define ZONE "%[-+0-9A-Za-z/]"
210cfe2001-01-11Mirar (Pontus Hagland)  nfmt=replace(fmt, ({"%Y","%y","%M","%W","%D","%a","%e","%h","%m","%s","%p",
eb22d82003-10-01Dan Nelson  "%t","%f","%d","%z","%n","%S"}),
210cfe2001-01-11Mirar (Pontus Hagland)  ({ALNU,ALNU,ALNU,"%d",NUME,"%d",ALNU,"%d","%d","%d",AMPM,
eb22d82003-10-01Dan Nelson  NUME,NUME,NUME,ZONE,"%s","%d"}));
210cfe2001-01-11Mirar (Pontus Hagland)  #if 1 q=array_sscanf(fmt,"%{%*[^%]%%%1s%}")*({})*({})-({"*","%"}); #else // slower alternatives: array q=Array.map(replace(fmt,({"%*","%%"}),({"",""}))/"%", lambda(string s){ return s[..0];})-({""}); array q=({}); array pr=(array)fmt; int i=-1; while ((i=search(pr,'%',i+1))!=-1) q+=({sprintf("%c",pr[i+1])}); #endif
e7dce62001-01-11Mirar (Pontus Hagland)  if (sizeof(q)==0) error("format doesn't contain anything to parse\n"); if (q[-1]=="z") nfmt=replace(nfmt,ZONE,"%s");
210cfe2001-01-11Mirar (Pontus Hagland)  parse_format_cache[fmt]=({nfmt,q}); }
78fd532000-07-12Mirar (Pontus Hagland)  array res=array_sscanf(arg,nfmt);
210cfe2001-01-11Mirar (Pontus Hagland)  int i=search(res,""); if (i!=-1 && i<sizeof(res)-1) return 0;
78fd532000-07-12Mirar (Pontus Hagland)  if (sizeof(res)<sizeof(q)) return 0; // parse error mapping m=mkmapping(q,res);
e6ddef2001-01-11Mirar (Pontus Hagland)  if (i!=-1 && m->n!="") return 0;
210cfe2001-01-11Mirar (Pontus Hagland) 
e7dce62001-01-11Mirar (Pontus Hagland) // werror("%O\n",m);
210cfe2001-01-11Mirar (Pontus Hagland) // werror("bopa %O\n %O\n %O\n %O\n",fmt,arg,nfmt,m);
78fd532000-07-12Mirar (Pontus Hagland) 
e6ddef2001-01-11Mirar (Pontus Hagland) 
78fd532000-07-12Mirar (Pontus Hagland)  TimeRange low;
9f0b6c2008-02-07Martin Stjernholm  Calendar.Calendar cal=this;
78fd532000-07-12Mirar (Pontus Hagland) 
210cfe2001-01-11Mirar (Pontus Hagland) 
b15ef32000-08-12Mirar (Pontus Hagland) // #define NOCATCH #ifndef NOCATCH
78fd532000-07-12Mirar (Pontus Hagland)  if (catch {
b15ef32000-08-12Mirar (Pontus Hagland) #else werror("%O\n",m); #endif
0f0ec42000-10-26Mirar (Pontus Hagland)  if (m->n && m->n!="") return 0;
78fd532000-07-12Mirar (Pontus Hagland)  if (m->Y) m->Y=default_rules->language[f_year_number_from_name](m->Y); if (!zero_type(m->Y) && m->D && (int)m->M)
3928222000-10-29Mirar (Pontus Hagland)  low=m->day=cal->Day(m->Y,(int)m->M,(int)m->D);
78fd532000-07-12Mirar (Pontus Hagland) 
210cfe2001-01-11Mirar (Pontus Hagland) 
78fd532000-07-12Mirar (Pontus Hagland)  if (m->d) { int y,mo,d;
ead9722003-01-20Martin Nilsson  if (sizeof(m->d)==6)
78fd532000-07-12Mirar (Pontus Hagland)  { [y,mo,d]=(array(int))(m->d/2);
da53a82006-01-06Martin Bähr  if (y<dwim_year->past_lower) y+=dwim_year->current_century; else y+=dwim_year->past_century;
78fd532000-07-12Mirar (Pontus Hagland)  }
ead9722003-01-20Martin Nilsson  else if (sizeof(m->d)==8)
78fd532000-07-12Mirar (Pontus Hagland)  [y,mo,d]=(array(int))array_sscanf(m->d,"%4s%2s%2s"); else return 0; low=m->day=cal->Day(y,mo,d); } else { if (!zero_type(m->Y)) m->year=cal->Year(m->Y); else if (m->y) {
ead9722003-01-20Martin Nilsson  if (sizeof(m->y)<3)
78fd532000-07-12Mirar (Pontus Hagland)  { m->y=(int)m->y;
da53a82006-01-06Martin Bähr  // FIXME? these should be adjustable for different calendars. if (m->y<dwim_year->past_lower) m->y+=dwim_year->current_century; else if (m->y<dwim_year->past_upper) m->y+=dwim_year->past_century;
78fd532000-07-12Mirar (Pontus Hagland)  } low=m->year=cal->Year(m->y); }
e7dce62001-01-11Mirar (Pontus Hagland)  else low=m->year=context?context->year():cal->Year();
78fd532000-07-12Mirar (Pontus Hagland)  if (m->M) { m->month=low=m->year->month(m->M); }
537c212012-09-05Martin Stjernholm  if (m->W)
78fd532000-07-12Mirar (Pontus Hagland)  m->week=low=m->year->week("w"+m->W); if (!zero_type(m->D))
e7dce62001-01-11Mirar (Pontus Hagland)  m->day=low=(m->month||(context?context->month():cal->Month())) ->day((int)m->D);
78fd532000-07-12Mirar (Pontus Hagland)  else if (!zero_type(m->a))
537c212012-09-05Martin Stjernholm  m->day=low=(m->month || m->year)->day(m->a);
78fd532000-07-12Mirar (Pontus Hagland)  else if (!zero_type(m->e))
e7dce62001-01-11Mirar (Pontus Hagland)  m->day=low=(m->week||(context?context->week():cal->Week())) ->day(m->e);
78fd532000-07-12Mirar (Pontus Hagland)  else
e7dce62001-01-11Mirar (Pontus Hagland)  low=m->day=context?context->day():cal->Day();
dd23d02000-08-04Mirar (Pontus Hagland) 
4cdf3e2000-08-25Mirar (Pontus Hagland)  if (m->day && zero_type(m->Y) && zero_type(m->y) && m->e)
dd23d02000-08-04Mirar (Pontus Hagland)  if (m->month) { // scan for closest year that matches cYear y2=m->day->year(); object d2; int i; for (i=0; i<20; i++) { d2=(y2+i)->place(m->day); if (d2 && d2->week()->day(m->e)==d2) break; d2=(y2-i)->place(m->day); if (d2 && d2->week()->day(m->e)==d2) break; } if (i==20) return 0; low=m->day=d2; } else { // scan for closest month that matches cYear m2=m->day->month(); object d2; int i; for (i=0; i<20; i++) { d2=(m2+i)->place(m->day); if (d2 && d2->week()->day(m->e)==d2) break; d2=(m2-i)->place(m->day); if (d2 && d2->week()->day(m->e)==d2) break; } if (i==20) return 0; low=m->day=d2; }
78fd532000-07-12Mirar (Pontus Hagland)  }
eb4d9c2000-08-04Mirar (Pontus Hagland)  int h=0,mi=0,s=0;
9f3d1c2003-03-27Johan Sundström  float sub_second;
eb4d9c2000-08-04Mirar (Pontus Hagland)  string g=0;
ff685a2000-08-04Mirar (Pontus Hagland) 
78fd532000-07-12Mirar (Pontus Hagland)  if (m->t) {
ead9722003-01-20Martin Nilsson  if (sizeof(m->t)==6)
eb4d9c2000-08-04Mirar (Pontus Hagland)  [h,mi,s]=(array(int))(m->t/2),g="second";
ead9722003-01-20Martin Nilsson  else if (sizeof(m->t)==4)
eb4d9c2000-08-04Mirar (Pontus Hagland)  [h,mi]=(array(int))(m->t/2),g="minute";
78fd532000-07-12Mirar (Pontus Hagland)  else return 0; } else {
eb4d9c2000-08-04Mirar (Pontus Hagland)  if (!zero_type(m->h)) h=m->h,g="hour"; if (!zero_type(m->m)) mi=m->m,g="minute"; if (!zero_type(m->s)) s=m->s,g="second";
9f3d1c2003-03-27Johan Sundström  if (!zero_type(m->f)) sub_second=(float)("0."+m->f+"0"*9)[..10];
78fd532000-07-12Mirar (Pontus Hagland)  }
dd23d02000-08-04Mirar (Pontus Hagland)  if (!zero_type(m->p)) {
57bc9e2001-05-18Mirar (Pontus Hagland)  switch (lower_case(m->p)-".")
dd23d02000-08-04Mirar (Pontus Hagland)  { case "am": if (h==12) h=0; break; case "pm": if (h!=12) h+=12; break; default: return 0; // need "am" or "pm" } }
ff685a2000-08-04Mirar (Pontus Hagland)  if (m->z) // zone
9f3d1c2003-03-27Johan Sundström  low = dwim_zone(low,m->z,g,h,mi,s);
ff685a2000-08-04Mirar (Pontus Hagland)  else if (g)
9f3d1c2003-03-27Johan Sundström  low = dwim_tod(low,g,h,mi,s);
eb22d82003-10-01Dan Nelson  else if (!zero_type(m->S)) low = Second(m->S);
9f3d1c2003-03-27Johan Sundström  if (sub_second) low = low->fraction(sub_second); return low;
210cfe2001-01-11Mirar (Pontus Hagland) 
b15ef32000-08-12Mirar (Pontus Hagland) #ifndef NOCATCH
78fd532000-07-12Mirar (Pontus Hagland)  })
b15ef32000-08-12Mirar (Pontus Hagland) #endif
78fd532000-07-12Mirar (Pontus Hagland)  return 0; }
e6d5642012-05-06Henrik Grubbström (Grubba) //! method Day dwim_day(string date) //! method Day dwim_day(string date,TimeRange context)
78fd532000-07-12Mirar (Pontus Hagland) //! Tries a number of different formats on the given date (in order):
dc21d42001-05-05Mirar (Pontus Hagland) //! <pre>
78fd532000-07-12Mirar (Pontus Hagland) //! <ref>parse</ref> format as in //! "%y-%M-%D (%M) -W%W-%e (%e)" "2000-03-20 (Mar) -W12-1 (Mon)"
c7f0dd2002-05-25Martin Nilsson //! "%y-%M-%D" "2000-03-20", "00-03-20" //! "%M%/%D/%y" "3/20/2000"
78fd532000-07-12Mirar (Pontus Hagland) //! "%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" //! "%y%*[ /]%D%*[ /]%M" "00 20 mar" "2000 20/3" //! "%y%*[ /]%M%*[ /]%D" "2000 march 20"
c7f0dd2002-05-25Martin Nilsson //! "%D%.%M.%y" "20.3.2000"
78fd532000-07-12Mirar (Pontus Hagland) //! "%D%*[ -/]%M" "20/3" "20 mar" "20-03" //! "%M%*[ -/]%D" "3/20" "march 20"
c7f0dd2002-05-25Martin Nilsson //! "%M-%D-%y" "03-20-2000" //! "%D-%M-%y" "20-03-2000" //! "%e%*[- /]%D%*[- /]%M" "mon 20 march" //! "%e%*[- /]%M%*[- /]%D" "mon/march/20"
78fd532000-07-12Mirar (Pontus Hagland) //! "%e%*[ -/wv]%W%*[ -/]%y" "mon w12 -00" "1 w12 2000" //! "%e%*[ -/wv]%W" "mon w12"
c7f0dd2002-05-25Martin Nilsson //! "%d" "20000320", "000320"
78fd532000-07-12Mirar (Pontus Hagland) //! "today" "today" //! "last %e" "last monday" //! "next %e" "next monday"
dc21d42001-05-05Mirar (Pontus Hagland) //! </pre>
78fd532000-07-12Mirar (Pontus Hagland) //!
dc21d42001-05-05Mirar (Pontus Hagland) //! note:
78fd532000-07-12Mirar (Pontus Hagland) //! Casts exception if it fails to dwim out a day. //! "dwim" means do-what-i-mean. /* tests: Calendar.dwim_day("2000-03-20 (Mar) -W12-1 (Mon)"); Calendar.dwim_day("20/3/2000"); Calendar.dwim_day("20 mar 2000"); Calendar.dwim_day("20/3 -00"); Calendar.dwim_day("Mon 20 Mar 2000" ); Calendar.dwim_day("Mon 20/3 2000"); Calendar.dwim_day("2000-03-20"); Calendar.dwim_day("00-03-20"); Calendar.dwim_day("20000320"); Calendar.dwim_day("000320"); Calendar.dwim_day("-00 20/3" ); Calendar.dwim_day("-00 20 mar"); Calendar.dwim_day("-00 3/20" ); Calendar.dwim_day("-00 march 20"); Calendar.dwim_day("00 20 mar" ); Calendar.dwim_day("2000 20/3"); Calendar.dwim_day("2000 march 20"); Calendar.dwim_day("20/3" ); Calendar.dwim_day("20 mar" ); Calendar.dwim_day("20-03"); Calendar.dwim_day("3/20" ); Calendar.dwim_day("march 20"); Calendar.dwim_day("mon w12 -00" ); Calendar.dwim_day("1 w12 2000"); Calendar.dwim_day("mon w12"); Calendar.dwim_day("monday" ); Calendar.dwim_day("1"); Calendar.dwim_day("today"); Calendar.dwim_day("last monday"); Calendar.dwim_day("next monday");
3e6c8c2001-06-03Mirar (Pontus Hagland) Calendar.dwim_day("Sat Jun 2");
78fd532000-07-12Mirar (Pontus Hagland)  */
9eaf1d2008-06-28Martin Nilsson protected constant dwim_day_strings=
9877a22001-01-10Mirar (Pontus Hagland) ({ "%y-%M-%D (%*s) -W%W-%e (%e)",
3928222000-10-29Mirar (Pontus Hagland)  "%y-%M-%D", "%M/%D/%y",
dd23d02000-08-04Mirar (Pontus Hagland)  "%D%*[ /]%M%*[- /,]%y", "%M %D%*[- /,]%y", "%e%*[, ]%D%*[a-z:]%*[ /]%M%*[-/ ,]%y",
9877a22001-01-10Mirar (Pontus Hagland)  "%e%*[, ]%M%*[ ,]%D%*[ ,]%y",
dd23d02000-08-04Mirar (Pontus Hagland)  "-%y%*[ /]%D%*[ /]%M", "-%y%*[ /]%M%*[ /]%D", "%y%*[ /]%M%*[ /]%D",
ab6bb32000-10-10Mirar (Pontus Hagland)  "%y%*[ /]%D%*[ /]%M",
1355d52001-01-10Mirar (Pontus Hagland)  "%D.%M.%y",
dd23d02000-08-04Mirar (Pontus Hagland)  "%D%*[- /]%M", "%M%*[- /]%D",
3928222000-10-29Mirar (Pontus Hagland)  "%M-%D-%y", "%D-%M-%y",
33d97f2001-06-08Mirar (Pontus Hagland)  "%e%*[- /]%D%*[- /]%M",
3e6c8c2001-06-03Mirar (Pontus Hagland)  "%e%*[- /]%M%*[- /]%D",
dd23d02000-08-04Mirar (Pontus Hagland)  "%e%*[- /wv]%W%*[ -/]%y", "%e%*[- /wv]%W",
9877a22001-01-10Mirar (Pontus Hagland)  "%d" });
dd23d02000-08-04Mirar (Pontus Hagland) 
e7dce62001-01-11Mirar (Pontus Hagland) cDay dwim_day(string day,void|TimeRange context)
78fd532000-07-12Mirar (Pontus Hagland) { cDay d;
dd23d02000-08-04Mirar (Pontus Hagland)  foreach ( dwim_day_strings,
78fd532000-07-12Mirar (Pontus Hagland)  string dayformat)
e7dce62001-01-11Mirar (Pontus Hagland)  if ( (d=parse(dayformat+"%n",day,context)) )
3928222000-10-29Mirar (Pontus Hagland)  return d;
78fd532000-07-12Mirar (Pontus Hagland) 
4866ca2001-01-11Mirar (Pontus Hagland)  cDay t=context?context->day():Day();
e7dce62001-01-11Mirar (Pontus Hagland)  if ( (d=parse("%e",day,context)) )
78fd532000-07-12Mirar (Pontus Hagland)  { if (d>=t) return d; else return (d->week()+1)->place(d); }
44ee2e2004-08-19Fredrik Noring  if (sizeof(day)==4) catch { d = parse("%M/%D",day/2*"/",context); if(d) return d; };
78fd532000-07-12Mirar (Pontus Hagland) 
d66a7f2001-01-11Johan Sundström  if (day=="today") return t; if (day=="tomorrow") return t+1; if (day=="yesterday") return t-1;
78fd532000-07-12Mirar (Pontus Hagland)  if (sscanf(day,"last %s",day)) { cDay d=dwim_day(day); return (d->week()-1)->place(d); } if (sscanf(day,"next %s",day)) { cDay d=dwim_day(day); return (d->week()+1)->place(d); } error("Failed to dwim day from %O\n",day); }
437b692013-08-15Henrik Grubbström (Grubba) //! method Day dwim_time(string date_time) //! method Day dwim_time(string date_time, TimeRange context) //! Tries a number of different formats on the given date_time. //! //! note: //! Casts exception if it fails to dwim out a time. //! "dwim" means do-what-i-mean.
e7dce62001-01-11Mirar (Pontus Hagland) TimeofDay dwim_time(string what,void|TimeRange cx)
78fd532000-07-12Mirar (Pontus Hagland) { TimeofDay t;
0f0ec42000-10-26Mirar (Pontus Hagland) // #define COLON "$*[ :]" #define COLON ":"
eb5bd72002-07-15Martin Nilsson #define SPACED(X) replace(X," ","%*[ ]")
0f0ec42000-10-26Mirar (Pontus Hagland) 
d8dbe62003-10-15Martin Nilsson  what = String.trim_all_whites(what);
b3a01d2009-03-11Martin Nilsson  if (sizeof(what)>22 && (t=http_time(what,cx))) return t;
d8dbe62003-10-15Martin Nilsson  if (sizeof(what)>12 && (t=parse(SPACED("%e %M %D %h:%m:%s %Y"),what,cx))) return t; // ctime if (sizeof(what)>15 && (t=parse(SPACED("%e %M %D %h:%m:%s %z %Y"),what,cx))) return t; if (sizeof(what)>19 &&
880dc52003-12-31Martin Nilsson  (t=parse(SPACED("%e %M %D %h:%m:%s %z DST %Y"),what,cx))) return t;
210cfe2001-01-11Mirar (Pontus Hagland) 
ab6bb32000-10-10Mirar (Pontus Hagland)  foreach ( dwim_day_strings + ({""}), string dayformat ) foreach ( ({ "%t %z", "T%t %z", "T%t",
0f0ec42000-10-26Mirar (Pontus Hagland)  "%h"COLON"%m"COLON"%s %p %z", "%h"COLON"%m"COLON"%s %p", "%h"COLON"%m"COLON"%s %z", "%h"COLON"%m"COLON"%s%z", "%h"COLON"%m"COLON"%s", "%h"COLON"%m %p %z", "%h"COLON"%m %p", "%h"COLON"%m %z", "%h"COLON"%m%z", "%h"COLON"%m",
ab6bb32000-10-10Mirar (Pontus Hagland)  "%h%*[ ]%p",
210cfe2001-01-11Mirar (Pontus Hagland)  "%*[a-zA-Z.] %h"COLON"%m"COLON"%s %p %z", "%*[a-zA-Z.] %h"COLON"%m"COLON"%s %p", "%*[a-zA-Z.] %h"COLON"%m"COLON"%s %z", "%*[a-zA-Z.] %h"COLON"%m"COLON"%s%z", "%*[a-zA-Z.] %h"COLON"%m"COLON"%s", "%*[a-zA-Z.] %h"COLON"%m %p %z", "%*[a-zA-Z.] %h"COLON"%m %p", "%*[a-zA-Z.] %h"COLON"%m %z", "%*[a-zA-Z.] %h"COLON"%m%z", "%*[a-zA-Z.] %h"COLON"%m", "%*[a-zA-Z.] %h%*[ ]%p", }),
ab6bb32000-10-10Mirar (Pontus Hagland)  string todformat )
78fd532000-07-12Mirar (Pontus Hagland)  {
ab6bb32000-10-10Mirar (Pontus Hagland) // werror("try: %O\n %O\n", // dayformat+"%*[ ,]"+todformat, // todformat+"%*[ ,]"+dayformat);
0f0ec42000-10-26Mirar (Pontus Hagland)  if (dayformat=="") {
e7dce62001-01-11Mirar (Pontus Hagland)  if ( (t=parse(todformat+"%*[ ]%n",what,cx)) ) return t;
0f0ec42000-10-26Mirar (Pontus Hagland)  } else {
ad369b2011-06-09 Erik Dahl  if ( (t=parse(dayformat+"%*[ ,:T]"+todformat,what,cx)) ) return t;
dc21d42001-05-05Mirar (Pontus Hagland)  if ( (t=parse(todformat+"%*[ ,:]"+dayformat,what,cx)) ) return t;
0f0ec42000-10-26Mirar (Pontus Hagland)  }
78fd532000-07-12Mirar (Pontus Hagland)  } error("Failed to dwim time from %O\n",what); }
b3a01d2009-03-11Martin Nilsson // Parses time according to HTTP 1.1 (RFC 2616) HTTP-date token. TimeofDay http_time(string what, void|TimeRange cx) { TimeofDay t;
676a5a2013-05-17Per Hedbor  constant date1 = "%D %M %Y"; // 2+1+3+1+4=11 constant date2 = "%D-%M-%y"; // 2+1+3+1+2=9 constant date3 = "%M %*[ ]%D"; // 2+1+2=5 constant time = "%h:%m:%s"; // 2+1+2+1+2=8
b3a01d2009-03-11Martin Nilsson  // 3+2+ 11 +1+ 8 +4 = 29
edb6562013-05-26Martin Nilsson  // RFC 1123 (and RFC 822 which it bases its timestamp format on) // supports more variations than we support here.
676a5a2013-05-17Per Hedbor  constant rfc1123_date = "%e, "+date1+" "+time+" %z";
b3a01d2009-03-11Martin Nilsson  // 6+2+ 9 +1+ 8 +4 = 33
676a5a2013-05-17Per Hedbor  constant rfc850_date = "%e, "+date2+" "+time+" %z";
b3a01d2009-03-11Martin Nilsson  // 3+1+ 5 +1+ 8 +1+4 = 23
676a5a2013-05-17Per Hedbor  constant asctime_date = "%e "+date3+" "+time+" %Y";
b3a01d2009-03-11Martin Nilsson  if( sizeof(what)<23 ) return 0; if( (t=parse(rfc1123_date, what, cx)) || (t=parse(rfc850_date, what, cx)) || (t=parse(asctime_date+" %z", what+" GMT", cx)) ) return t; return 0; }
78fd532000-07-12Mirar (Pontus Hagland) //-- auxillary functions------------------------------------------------
dc21d42001-05-05Mirar (Pontus Hagland) //!
3f28812012-05-06Henrik Grubbström (Grubba) //! function mapping(string:int) datetime(int|void unix_time)
78fd532000-07-12Mirar (Pontus Hagland) //! Replacement for localtime; gives back a mapping:
dc21d42001-05-05Mirar (Pontus Hagland) //! <pre>
78fd532000-07-12Mirar (Pontus Hagland) //! ([ "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 //! ]);
dc21d42001-05-05Mirar (Pontus Hagland) //! </pre> //! This is the same as calling <ref>Second</ref>()-><ref to=Second.datetime>datetime</ref>(). //!
3f28812012-05-06Henrik Grubbström (Grubba) //! function string datetime_name(int|void unix_time) //! function string datetime_short_name(int|void unix_time)
dc21d42001-05-05Mirar (Pontus Hagland) //! 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> //! iso "2000-06-02 (Jun) -W22-5 (Fri) 11:57:18 CEST" //! iso_short "2000-06-02 11:57:18" //! iso_tod "11:57:18" //! </pre> // Sane replacement for localtime().
78fd532000-07-12Mirar (Pontus Hagland) mapping(string:int) datetime(int|void unix_time) { return Second("unix",unix_time||time())->datetime(); } string datetime_name(int|void unix_time) { return Second("unix",unix_time||time())->format_iso(); } string datetime_short_name(int|void unix_time) { return Second("unix",unix_time||time())->format_iso_short(); } string format_iso(int|void unix_time) { return Second("unix",unix_time||time())->format_iso(); } string format_iso_short(int|void unix_time) { return Second("unix",unix_time||time())->format_iso_short(); } string format_iso_tod(int|void unix_time) { return Second("unix",unix_time||time())->format_iso_tod(); } string format_day_iso(int|void unix_time) { return Day("unix",unix_time||time())->format_iso(); } string format_day_iso_short(int|void unix_time) { return Day("unix",unix_time||time())->format_iso_short(); }