78fd532000-07-12Mirar (Pontus Hagland) //! //! module Calendar //! submodule ISO //! //! This is the standard western calendar, //! which is a derivate of the Gregorian calendar, //! but with weeks that starts on monday //! instead of sunday. //! //! inherits Gregorian //!
a580e12000-09-27Fredrik Hübinette (Hubbe) #pike __REAL_VERSION__
a20af62000-09-26Fredrik Hübinette (Hubbe) 
78fd532000-07-12Mirar (Pontus Hagland) import "."; inherit Gregorian:Gregorian;
489a702001-01-11Mirar (Pontus Hagland) #include "constants.h"
78fd532000-07-12Mirar (Pontus Hagland) string calendar_name() { return "ISO"; } private static mixed __initstuff=lambda()
5550a21998-01-27Mirar (Pontus Hagland) {
78fd532000-07-12Mirar (Pontus Hagland)  f_week_day_shortname_from_number="week_day_shortname_from_number"; f_week_day_name_from_number="week_day_name_from_number"; f_year_name_from_number="year_name_from_number"; f_week_day_number_from_name="week_day_number_from_name"; }();
071d021998-09-27Mirar (Pontus Hagland) 
78fd532000-07-12Mirar (Pontus Hagland) static int compat_week_day(int n)
7d6bbc1999-02-13Fredrik Noring {
78fd532000-07-12Mirar (Pontus Hagland)  return n%7;
7d6bbc1999-02-13Fredrik Noring }
5550a21998-01-27Mirar (Pontus Hagland) 
78fd532000-07-12Mirar (Pontus Hagland) static string year_name_from_number(int y) { if (y>0) return ""+y; else return (1-y)+" BC";
5550a21998-01-27Mirar (Pontus Hagland) }
78fd532000-07-12Mirar (Pontus Hagland) static array(int) week_from_julian_day(int jd)
5550a21998-01-27Mirar (Pontus Hagland) {
78fd532000-07-12Mirar (Pontus Hagland) // [year,week,day-of-week,ndays,week-julian-day]
5550a21998-01-27Mirar (Pontus Hagland) 
78fd532000-07-12Mirar (Pontus Hagland)  [int y,int yjd]=year_from_julian_day(jd); int yday=jd-yjd+1;
7d6bbc1999-02-13Fredrik Noring 
78fd532000-07-12Mirar (Pontus Hagland)  int k=3+(yjd-3)%7; int w=(yday+k-1)/7; int wjd=jd-jd%7;
7d6bbc1999-02-13Fredrik Noring 
78fd532000-07-12Mirar (Pontus Hagland)  if (!w)
7d6bbc1999-02-13Fredrik Noring  {
78fd532000-07-12Mirar (Pontus Hagland) // handle the case that the day is in the previous year; // years previous to years staring on saturday, // ... and leap years starting on sunday y--; w=52+( (k==3) || ( (k==4) && year_leap_year(y) ) );
7d6bbc1999-02-13Fredrik Noring  }
78fd532000-07-12Mirar (Pontus Hagland)  else if (w==53 && k>=5-year_leap_year(y) && k<9-year_leap_year(y))
5550a21998-01-27Mirar (Pontus Hagland)  {
78fd532000-07-12Mirar (Pontus Hagland) // handle the case that the week is in the next year y++; w=1;
5550a21998-01-27Mirar (Pontus Hagland)  }
7d6bbc1999-02-13Fredrik Noring 
78fd532000-07-12Mirar (Pontus Hagland)  return ({y,w,1+(yjd+yday-1)%7,7,wjd});
7d6bbc1999-02-13Fredrik Noring }
78fd532000-07-12Mirar (Pontus Hagland) static array(int) week_from_week(int y,int w)
7d6bbc1999-02-13Fredrik Noring {
78fd532000-07-12Mirar (Pontus Hagland) // [year,week,1 (wd),ndays,week-julian-day]
7d6bbc1999-02-13Fredrik Noring 
78fd532000-07-12Mirar (Pontus Hagland)  int yjd=julian_day_from_year(y); int wjd=-3+yjd-(yjd+4)%7;
7d6bbc1999-02-13Fredrik Noring 
78fd532000-07-12Mirar (Pontus Hagland)  if (w<1 || w>52) // may or may not be out of this year return week_from_julian_day(wjd+w*7);
7d6bbc1999-02-13Fredrik Noring 
78fd532000-07-12Mirar (Pontus Hagland)  return ({y,w,1,7,wjd+w*7}); // fixme
7d6bbc1999-02-13Fredrik Noring }
78fd532000-07-12Mirar (Pontus Hagland) class cYear
7d6bbc1999-02-13Fredrik Noring {
78fd532000-07-12Mirar (Pontus Hagland)  inherit Gregorian::cYear; TimeRange place(TimeRange what,void|int force)
7d6bbc1999-02-13Fredrik Noring  {
78fd532000-07-12Mirar (Pontus Hagland)  if (what->is_day) { int wyd=what->yd; if (md==CALUNKNOWN) make_month(); if (wyd>=55) { int l1=year_leap_year(what->y); int l2=year_leap_year(y); if (l1||l2) { int ld1=(what->y<2000)?55:60; // 24th or 29th february int ld2=(y<2000)?55:60; // 24th or 29th february if (l1 && wyd==ld1) if (l2) wyd=ld2; else { if (!force) return 0; } else { if (l1 && wyd>ld1) wyd--; if (l2 && wyd>=ld2) wyd++; } } } if (!force && wyd>number_of_days()) return 0; return Day("ymd_yd",rules,y,yjd,yjd+wyd-1,wyd,what->n); }
7d6bbc1999-02-13Fredrik Noring 
78fd532000-07-12Mirar (Pontus Hagland)  return ::place(what);
7d6bbc1999-02-13Fredrik Noring  } }
78fd532000-07-12Mirar (Pontus Hagland) class cMonth
7d6bbc1999-02-13Fredrik Noring {
78fd532000-07-12Mirar (Pontus Hagland)  inherit Gregorian::cMonth;
7d6bbc1999-02-13Fredrik Noring 
78fd532000-07-12Mirar (Pontus Hagland)  TimeRange place(TimeRange what,int|void force)
7d6bbc1999-02-13Fredrik Noring  {
78fd532000-07-12Mirar (Pontus Hagland)  if (what->is_day) { int wmd=what->month_day(); if (md==CALUNKNOWN) make_month(); if (what->m==2 && m==2 && wmd>=24) { int l1=year_leap_year(what->y); int l2=year_leap_year(y); if (l1||l2) { int ld1=(what->y<2000)?24:29; // 24th or 29th february int ld2=(y<2000)?24:29; // 24th or 29th february if (l1 && wmd==ld1) if (l2) wmd=ld2; else { if (!force) return 0; } else { if (l1 && wmd>ld1) wmd--; if (l2 && wmd>=ld2) wmd++; } } } if (!force && wmd>number_of_days()) return 0; return Day("ymd_yd",rules,y,yjd,jd+wmd-1,yd+wmd-1,what->n); }
7d6bbc1999-02-13Fredrik Noring 
78fd532000-07-12Mirar (Pontus Hagland)  return ::place(what);
7d6bbc1999-02-13Fredrik Noring  } }