a580e12000-09-27Fredrik Hübinette (Hubbe) #pike __REAL_VERSION__
2232742000-09-27Mirar (Pontus Hagland) 
3524712015-05-26Martin Nilsson //! This implements TNG stardates.
5479552003-03-13Martin Nilsson 
9eaf1d2008-06-28Martin Nilsson protected constant TNGSTARPERJULIAN=1000.0/365.2425; protected constant TNGSTARPERSECOND=TNGSTARPERJULIAN/86400; protected constant TNG0JULIAN=2569518.5; protected constant TNG0UNIX=11139552000;
ed7e362000-09-27Mirar (Pontus Hagland)  string calendar_name() { return "Stardate"; }
a20af62000-09-26Fredrik Hübinette (Hubbe) 
ed7e362000-09-27Mirar (Pontus Hagland) function(mixed...:cTick) Tick=cTick;
5479552003-03-13Martin Nilsson  //!
ed7e362000-09-27Mirar (Pontus Hagland) class cTick {
6088ee2003-11-07Henrik Grubbström (Grubba)  inherit Calendar.TimeRange;
c90abc1998-11-20Mirar (Pontus Hagland) 
ed7e362000-09-27Mirar (Pontus Hagland)  constant is_stardate=1;
c90abc1998-11-20Mirar (Pontus Hagland) 
2232742000-09-27Mirar (Pontus Hagland)  float t;
ed7e362000-09-27Mirar (Pontus Hagland)  float len;
c90abc1998-11-20Mirar (Pontus Hagland) 
5dc75a2003-03-13Martin Nilsson  //! @decl void create(mixed ... args)
5479552003-03-13Martin Nilsson  //! @decl void create(int|float date) //! @decl void create() //! Apart from the standard creation methods //! (julian day, etc), you can create a stardate //! from the stardate number. The length //! of the period will then be zero. //! //! You can also omit any arguments to create now. //! //! @bugs //! Since the precision is limited to the float type //! of Pike you can get non-precise results: //!
e5ef062003-04-01Martin Nilsson  //! @code //! > Calendar.Second(Calendar.Stardate.Day(Calendar.Year())); //! Result: Second(Fri 31 Dec 1999 23:59:18 CET - Sun 31 Dec 2000 23:59:18 CET) //! @endcode
dc21d42001-05-05Mirar (Pontus Hagland) 
d7db5d2013-05-31Martin Nilsson  protected void create(mixed ...args)
c90abc1998-11-20Mirar (Pontus Hagland)  {
ed7e362000-09-27Mirar (Pontus Hagland)  switch (sizeof(args))
c90abc1998-11-20Mirar (Pontus Hagland)  {
ed7e362000-09-27Mirar (Pontus Hagland)  case 4: // internal if (args[0]=="stardate")
c90abc1998-11-20Mirar (Pontus Hagland)  {
ed7e362000-09-27Mirar (Pontus Hagland)  rules=args[1];
2232742000-09-27Mirar (Pontus Hagland)  t=args[2];
ed7e362000-09-27Mirar (Pontus Hagland)  len=args[3]; return;
c90abc1998-11-20Mirar (Pontus Hagland)  }
ed7e362000-09-27Mirar (Pontus Hagland)  break; case 1: if (intp(args[0]) || floatp(args[0]))
c90abc1998-11-20Mirar (Pontus Hagland)  {
6088ee2003-11-07Henrik Grubbström (Grubba)  rules=Calendar.default_rules;
2232742000-09-27Mirar (Pontus Hagland)  t=(float)args[0];
ed7e362000-09-27Mirar (Pontus Hagland)  len=0.0; return;
c90abc1998-11-20Mirar (Pontus Hagland)  }
ed7e362000-09-27Mirar (Pontus Hagland)  break; case 0:
6088ee2003-11-07Henrik Grubbström (Grubba)  rules=Calendar.default_rules;
ed7e362000-09-27Mirar (Pontus Hagland)  create_unixtime_default(time()); return; }
6088ee2003-11-07Henrik Grubbström (Grubba)  rules=Calendar.default_rules;
ed7e362000-09-27Mirar (Pontus Hagland)  ::create(@args); }
9eaf1d2008-06-28Martin Nilsson  protected void create_unixtime(int unixtime,int seconds)
ed7e362000-09-27Mirar (Pontus Hagland)  {
2232742000-09-27Mirar (Pontus Hagland)  t=(unixtime-TNG0UNIX)*TNGSTARPERSECOND;
ed7e362000-09-27Mirar (Pontus Hagland)  len=seconds*TNGSTARPERSECOND; }
9eaf1d2008-06-28Martin Nilsson  protected void create_unixtime_default(int unixtime)
ed7e362000-09-27Mirar (Pontus Hagland)  {
2232742000-09-27Mirar (Pontus Hagland)  t=(unixtime-TNG0UNIX)*TNGSTARPERSECOND;
ed7e362000-09-27Mirar (Pontus Hagland)  len=0.0; }
9eaf1d2008-06-28Martin Nilsson  protected void create_julian_day(int|float jd)
ed7e362000-09-27Mirar (Pontus Hagland)  {
2232742000-09-27Mirar (Pontus Hagland)  t=(jd-TNG0JULIAN)*TNGSTARPERJULIAN;
ed7e362000-09-27Mirar (Pontus Hagland)  len=0.0; }
5479552003-03-13Martin Nilsson  //! This gives back the start of the stardate period, //! as a float.
2232742000-09-27Mirar (Pontus Hagland)  float tic() { return t; }
5479552003-03-13Martin Nilsson  //! This gives back the number of stardate tics //! in the period.
ed7e362000-09-27Mirar (Pontus Hagland)  float tics() { return len; }
5479552003-03-13Martin Nilsson  //! This gives back the Gregorian/Earth/ISO number of seconds, //! for convinience and conversion to other calendars.
ed7e362000-09-27Mirar (Pontus Hagland)  int number_of_seconds() { return (int)(len/TNGSTARPERSECOND); }
5479552003-03-13Martin Nilsson  //! This gives back the Gregorian/Earth/ISO number of days, //! for convinience and conversion to other calendars.
ed7e362000-09-27Mirar (Pontus Hagland)  int number_of_days() { return (int)(len/TNGSTARPERJULIAN); } int unix_time() {
2232742000-09-27Mirar (Pontus Hagland)  return ((int)(t/TNGSTARPERSECOND))+TNG0UNIX;
ed7e362000-09-27Mirar (Pontus Hagland)  } float julian_day() {
2232742000-09-27Mirar (Pontus Hagland)  return ((int)(t/TNGSTARPERJULIAN))+TNG0JULIAN;
ed7e362000-09-27Mirar (Pontus Hagland)  }
9eaf1d2008-06-28Martin Nilsson  protected Calendar.TimeRange _add(int n,void|this_program step)
ed7e362000-09-27Mirar (Pontus Hagland)  { float x;
3524712015-05-26Martin Nilsson  if (!step)
ed7e362000-09-27Mirar (Pontus Hagland)  x=len;
3524712015-05-26Martin Nilsson  else
ed7e362000-09-27Mirar (Pontus Hagland)  { if (!step->is_stardate) error("add: Incompatible type %O\n",step); x=step->len; } if (n&&x)
2232742000-09-27Mirar (Pontus Hagland)  return Tick("stardate",rules,t+x,len);
563bd72004-01-11Martin Nilsson  return this;
ed7e362000-09-27Mirar (Pontus Hagland)  }
9eaf1d2008-06-28Martin Nilsson  protected void convert_from(Calendar.TimeRange other)
ed7e362000-09-27Mirar (Pontus Hagland)  { if (other->unix_time) create_unixtime_default(other->unix_time()); else ::convert_from(other); if (other->is_stardate) {
2232742000-09-27Mirar (Pontus Hagland)  t=other->t;
ed7e362000-09-27Mirar (Pontus Hagland)  len=other->len;
78fd532000-07-12Mirar (Pontus Hagland)  }
ed7e362000-09-27Mirar (Pontus Hagland)  else if (other->number_of_seconds) len=TNGSTARPERSECOND*other->number_of_seconds(); else if (other->number_of_days) len=TNGSTARPERJULIAN*other->number_of_days(); else len=0.0; }
9eaf1d2008-06-28Martin Nilsson  protected Calendar.TimeRange _set_size(int n, Calendar.TimeRange x)
ed7e362000-09-27Mirar (Pontus Hagland)  { if (!x->is_stardate) error("distance: Incompatible type %O\n",x);
2232742000-09-27Mirar (Pontus Hagland)  return Tick("stardate",rules,t,x->len);
ed7e362000-09-27Mirar (Pontus Hagland)  }
6088ee2003-11-07Henrik Grubbström (Grubba)  Calendar.TimeRange place(Calendar.TimeRange what,void|int force)
ed7e362000-09-27Mirar (Pontus Hagland)  { // can't do this
563bd72004-01-11Martin Nilsson  return this;
ed7e362000-09-27Mirar (Pontus Hagland)  }
6088ee2003-11-07Henrik Grubbström (Grubba)  array(Calendar.TimeRange) split(int n)
ed7e362000-09-27Mirar (Pontus Hagland)  {
563bd72004-01-11Martin Nilsson  if (!n) return ({this}); // foo
ed7e362000-09-27Mirar (Pontus Hagland) 
2232742000-09-27Mirar (Pontus Hagland)  float z=t;
ed7e362000-09-27Mirar (Pontus Hagland)  float l=len/n;
6088ee2003-11-07Henrik Grubbström (Grubba)  array(Calendar.TimeRange) res=({});
ed7e362000-09-27Mirar (Pontus Hagland)  while (n--) res+=({Tick("stardate",rules,z,l)}),z+=l; return res; }
6088ee2003-11-07Henrik Grubbström (Grubba)  Calendar.TimeRange beginning()
ed7e362000-09-27Mirar (Pontus Hagland)  {
563bd72004-01-11Martin Nilsson  if (!len) return this;
2232742000-09-27Mirar (Pontus Hagland)  return Tick("stardate",rules,t,0.0);
ed7e362000-09-27Mirar (Pontus Hagland)  }
6088ee2003-11-07Henrik Grubbström (Grubba)  Calendar.TimeRange end()
ed7e362000-09-27Mirar (Pontus Hagland)  {
563bd72004-01-11Martin Nilsson  if (!len) return this;
2232742000-09-27Mirar (Pontus Hagland)  return Tick("stardate",rules,t+len,0.0);
ed7e362000-09-27Mirar (Pontus Hagland)  }
6088ee2003-11-07Henrik Grubbström (Grubba)  Calendar.TimeRange distance(Calendar.TimeRange to)
ed7e362000-09-27Mirar (Pontus Hagland)  { if (!to->is_stardate) error("distance: Incompatible type %O\n",to);
2232742000-09-27Mirar (Pontus Hagland)  if (to->t<t)
ed7e362000-09-27Mirar (Pontus Hagland)  error("negative distance\n");
2232742000-09-27Mirar (Pontus Hagland)  return Tick("stardate",rules,t,to->t-t);
ed7e362000-09-27Mirar (Pontus Hagland)  }
6088ee2003-11-07Henrik Grubbström (Grubba)  array(int(-1..1)) _compare(Calendar.TimeRange with)
ed7e362000-09-27Mirar (Pontus Hagland)  {
2232742000-09-27Mirar (Pontus Hagland)  float b1=t; float e1=t+len;
ed7e362000-09-27Mirar (Pontus Hagland)  float b2,e2; if (with->is_stardate)
2232742000-09-27Mirar (Pontus Hagland)  b2=with->t,e2=b2+with->len;
3524712015-05-26Martin Nilsson  else
ed7e362000-09-27Mirar (Pontus Hagland)  ::_compare(with); #define CMP(A,B) ( ((A)<(B))?-1:((A)>(B))?1:0 ) return ({ CMP(b1,b2),CMP(b1,e2),CMP(e1,b2),CMP(e1,e2) });
c90abc1998-11-20Mirar (Pontus Hagland)  }
2232742000-09-27Mirar (Pontus Hagland)  int __hash() { return (int)t; }
ed7e362000-09-27Mirar (Pontus Hagland) 
9f0b6c2008-02-07Martin Stjernholm  Calendar.TimeRange set_ruleset(Calendar.Ruleset r)
c90abc1998-11-20Mirar (Pontus Hagland)  {
2232742000-09-27Mirar (Pontus Hagland)  return Tick("stardate",r,t,len);
c90abc1998-11-20Mirar (Pontus Hagland)  }
78fd532000-07-12Mirar (Pontus Hagland) 
d7db5d2013-05-31Martin Nilsson  protected string _sprintf(int t, mapping m)
78fd532000-07-12Mirar (Pontus Hagland)  {
ed7e362000-09-27Mirar (Pontus Hagland)  switch (t) { case 'O':
3524712015-05-26Martin Nilsson  if (len!=0.0)
ed7e362000-09-27Mirar (Pontus Hagland)  return sprintf("Tick(%s)",nice_print_period()); return sprintf("Tick(%s)",nice_print()); default: return 0; }
78fd532000-07-12Mirar (Pontus Hagland)  }
ed7e362000-09-27Mirar (Pontus Hagland)  string nice_print_period() { if (len>0.010) return sprintf("%s..%s",nice_print(),end()->nice_print()); else return sprintf("%s..%+g",nice_print(),len); }
78fd532000-07-12Mirar (Pontus Hagland) 
ed7e362000-09-27Mirar (Pontus Hagland)  string nice_print()
78fd532000-07-12Mirar (Pontus Hagland)  {
2232742000-09-27Mirar (Pontus Hagland)  return sprintf("%.3f",t);
78fd532000-07-12Mirar (Pontus Hagland)  }
ed7e362000-09-27Mirar (Pontus Hagland) 
5479552003-03-13Martin Nilsson  //! @decl string format_long(void|int precision) //! @decl string format_short(void|int precision) //! @decl string format_vshort(void|int precision) //! Format the stardate tick nicely. Precision is the number of //! decimals. Defaults to 3. //! @xml{<matrix> //! <r><c>long</c><c>"-322537.312"</c><c></c></r> //! <r><c>short</c><c>"77463.312"</c><c>(w/o >100000-component)</c></r> //! <r><c>vshort</c><c>"7463.312"</c><c>(w/o >10000-component)</c></r> //! </matrix>@}
ed7e362000-09-27Mirar (Pontus Hagland) 
e026802002-10-26Martin Nilsson  string format_long(void|int p)
78fd532000-07-12Mirar (Pontus Hagland)  {
e026802002-10-26Martin Nilsson  return sprintf("%.*f",p||3,t);
78fd532000-07-12Mirar (Pontus Hagland)  }
e026802002-10-26Martin Nilsson  string format_short(void|int p)
78fd532000-07-12Mirar (Pontus Hagland)  {
e026802002-10-26Martin Nilsson  return sprintf("%.*f",p||3,t-((int)t/100000)*100000);
78fd532000-07-12Mirar (Pontus Hagland)  }
ed7e362000-09-27Mirar (Pontus Hagland) 
e026802002-10-26Martin Nilsson  string format_vshort(void|int p)
ed7e362000-09-27Mirar (Pontus Hagland)  {
e026802002-10-26Martin Nilsson  return sprintf("%.*f",p||3,t-((int)t/10000)*10000);
ed7e362000-09-27Mirar (Pontus Hagland)  } } // compat function(mixed...:cTick) TNGDate=cTick; // for events function(mixed...:cTick) Day=cTick; //------------------------------------------------------------------------ // global convinience functions //------------------------------------------------------------------------
5479552003-03-13Martin Nilsson //! Give the zero-length time period of the current time.
9f0b6c2008-02-07Martin Stjernholm /*Calendar.Time.TimeofDay*/cTick now()
ed7e362000-09-27Mirar (Pontus Hagland) { return Tick();
c90abc1998-11-20Mirar (Pontus Hagland) }