ed7e362000-09-27Mirar (Pontus Hagland) //! module Calendar
c90abc1998-11-20Mirar (Pontus Hagland) //! submodule Stardate
ed7e362000-09-27Mirar (Pontus Hagland) //! This implements TNG stardates.
c90abc1998-11-20Mirar (Pontus Hagland) 
a580e12000-09-27Fredrik Hübinette (Hubbe) #pike __REAL_VERSION__
2232742000-09-27Mirar (Pontus Hagland) 
ed7e362000-09-27Mirar (Pontus Hagland) import ".";
c90abc1998-11-20Mirar (Pontus Hagland) 
ed7e362000-09-27Mirar (Pontus Hagland) inherit TimeRanges;
78fd532000-07-12Mirar (Pontus Hagland) 
ed7e362000-09-27Mirar (Pontus Hagland) static constant TNGSTARPERJULIAN=1000.0/365.2425; static constant TNGSTARPERSECOND=TNGSTARPERJULIAN/86400; static constant TNG0JULIAN=2569518.5; static constant TNG0UNIX=11139552000; string calendar_name() { return "Stardate"; }
a20af62000-09-26Fredrik Hübinette (Hubbe) 
ed7e362000-09-27Mirar (Pontus Hagland) function(mixed...:cTick) Tick=cTick; class cTick { inherit 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) 
ed7e362000-09-27Mirar (Pontus Hagland) //! method void create(mixed ...) //! method void create(int|float date) //! method 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. //! //! known bugs: //! Since the precision is limited to the float type //! of pike you can get non-precise results: //! //! <pre> //! > 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) //! </pre>
c90abc1998-11-20Mirar (Pontus Hagland) 
ed7e362000-09-27Mirar (Pontus Hagland)  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)  {
ed7e362000-09-27Mirar (Pontus Hagland)  rules=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: rules=default_rules; create_unixtime_default(time()); return; } rules=default_rules; ::create(@args); } static void create_unixtime(int unixtime,int seconds) {
2232742000-09-27Mirar (Pontus Hagland)  t=(unixtime-TNG0UNIX)*TNGSTARPERSECOND;
ed7e362000-09-27Mirar (Pontus Hagland)  len=seconds*TNGSTARPERSECOND; } static void create_unixtime_default(int unixtime) {
2232742000-09-27Mirar (Pontus Hagland)  t=(unixtime-TNG0UNIX)*TNGSTARPERSECOND;
ed7e362000-09-27Mirar (Pontus Hagland)  len=0.0; } static void create_julian_day(int|float jd) {
2232742000-09-27Mirar (Pontus Hagland)  t=(jd-TNG0JULIAN)*TNGSTARPERJULIAN;
ed7e362000-09-27Mirar (Pontus Hagland)  len=0.0; }
2232742000-09-27Mirar (Pontus Hagland) // method float tic() // This gives back the start of the stardate period, // as a float. float tic() { return t; }
ed7e362000-09-27Mirar (Pontus Hagland) //! method float tics() //! This gives back the number of stardate tics //! in the period. float tics() { return len; } //! method int number_of_seconds() //! method int number_of_days() //! This gives back the Gregorian/Earth/ISO number of seconds //! and number of days, for convinience and conversion to //! other calendars. int number_of_seconds() { return (int)(len/TNGSTARPERSECOND); } 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)  } TimeRange add(int n,void|this_program step) { float x; if (!step) x=len; else { 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);
ed7e362000-09-27Mirar (Pontus Hagland)  return this_object(); } static void convert_from(TimeRange other) { 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; } static TimeRange _set_size(int n,TimeRange x) { 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)  } TimeRange place(TimeRange what,void|int force) { // can't do this return this_object(); } array(TimeRange) split(int n) { if (!n) return ({this_object()}); // foo
2232742000-09-27Mirar (Pontus Hagland)  float z=t;
ed7e362000-09-27Mirar (Pontus Hagland)  float l=len/n; array(TimeRange) res=({}); while (n--) res+=({Tick("stardate",rules,z,l)}),z+=l; return res; } TimeRange beginning() { if (!len) return this_object();
2232742000-09-27Mirar (Pontus Hagland)  return Tick("stardate",rules,t,0.0);
ed7e362000-09-27Mirar (Pontus Hagland)  } TimeRange end() { if (!len) return this_object();
2232742000-09-27Mirar (Pontus Hagland)  return Tick("stardate",rules,t+len,0.0);
ed7e362000-09-27Mirar (Pontus Hagland)  } TimeRange distance(TimeRange to) { 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)  } array _compare(TimeRange with) {
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;
78fd532000-07-12Mirar (Pontus Hagland)  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)  cTick set_ruleset(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) 
ed7e362000-09-27Mirar (Pontus Hagland)  string _sprintf(int t)
78fd532000-07-12Mirar (Pontus Hagland)  {
ed7e362000-09-27Mirar (Pontus Hagland)  switch (t) { case 'O': if (len!=0.0) 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)  //! string format_long() //! string format_short() //! string format_vshort() //! Format the stardate tick nicely. //! <pre> //! long "-322537.312" //! short "77463.312" (w/o >100000-component) //! short "7463.312" (w/o >10000-component) //! </pre> string format_long()
78fd532000-07-12Mirar (Pontus Hagland)  {
2232742000-09-27Mirar (Pontus Hagland)  return sprintf("%.3f",t);
78fd532000-07-12Mirar (Pontus Hagland)  }
ed7e362000-09-27Mirar (Pontus Hagland)  string format_short()
78fd532000-07-12Mirar (Pontus Hagland)  {
2232742000-09-27Mirar (Pontus Hagland)  return sprintf("%.3f",t-((int)t/100000)*100000);
78fd532000-07-12Mirar (Pontus Hagland)  }
ed7e362000-09-27Mirar (Pontus Hagland)  string format_vshort() {
2232742000-09-27Mirar (Pontus Hagland)  return sprintf("%.3f",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 //------------------------------------------------------------------------ //! method TimeofDay now() //! Give the zero-length time period of the //! current time. TimeofDay now() { return Tick();
c90abc1998-11-20Mirar (Pontus Hagland) }