From: lfernand@ee.ryerson.ca (luis fernandes)
Subject: Re: When was Stardate 0.0 ?
Summary: C-Source code to calculate stardate.
Keywords: stardate 
Organization: Ryerson Polytechnical Institute, Toronto
Date: Thu, 30 Jul 1992 22:36:32 GMT

In article <1992Jul30.112823.1@bronco.fnal.gov> colombo@bronco.fnal.gov writes:

>They use big numbers in the shows, but when was the stardate zero?
Dunno.


>How do stardates work?  I mean how it it incremented?  I guess if
>I knew this, I could sorta work it backwards.

Here's some C-source to a stardate-calculator program, posted a while back
by Jay Windley...

Hope it helps.

zxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzx
Luis Fernandes  <lfernand@ee.ryerson.ca>
-Friendly Neighbourhood X Wizard's Apprentice
zxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzxzx

--cut-here--
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	README
#	stardate.1
#	stardate.c
# This archive created: Thu Jul 30 18:29:45 1992
export PATH; PATH=/bin:$PATH
if test -f 'README'
then
       echo shar: will not over-write existing file "'README'"
else
cat << \SHAR_EOF > 'README'
There is only the one C source file, so compile it with your favorite
C compiler.  I've only tested it using GCC in -traditional mode, so I
don't guarantee it will compile on all systems without modification.

I have used Unix time manipulation tools, but as far as I've seen
these tools (or equivalents) are available in most non-Unix C
implementations.

The usual disclaimers apply -- if this program hoses your machine it's
your fault.

I don't plan to "officially" maintain this program.  In other words,
send bug reports to

       jwindley@asylum.utah.edu

but don't expect me to jump right on them.

There is an nroff-style user manual as well, just to explain the
options.  Those bereft of nroff should still be able to glean the
necessary information.

Share and Enjoy.
SHAR_EOF
fi # end of overwriting check
if test -f 'stardate.1'
then
       echo shar: will not over-write existing file "'stardate.1'"
else
cat << \SHAR_EOF > 'stardate.1'
.TH STARDATE 1L "Starfleet Technical Support"
.SH NAME
stardate \- display current Stardate
.SH SYNOPSIS
.B stardate
[ \-d\fIn\fR ]
.SH DESCRIPTION
.I Stardate
computes the current Stardate using the algorithm specified by
Starfleet Standard NC\-C34/32446.7 and displays it on the default
logical output node.  The
.B -d
option specifies that
.I n
digits of precision are to be displayed after
the decimal point.  The
minimum (default) value for this parameter is is 1 and the maximum is 7.
.SH DIAGNOSTICS
If the option or its argument is incorrect, a soft exception occurs
and the program is terminated.  This program responds to sanity check
pulses generated during Level 4 diagnostic passes.
.SH CAVEATS
.I Stardate
is optimized for use aboard
.I Galaxy
and
.I Excelsior
class starships, and at all Starbases servicing these classes.
The computed Stardate is not guaranteed to be
compatible with planetary chronolog systems, and no support for
conversion has been provided.
.SH AUTHOR
.br
.nf
Jay Windley
Starfleet Computational Systems Support Command \- Galaxy Class
Utopia Planitia Fleet Yards, MARS
jwindley@asylum.utah.edu
SHAR_EOF
fi # end of overwriting check
if test -f 'stardate.c'
then
       echo shar: will not over-write existing file "'stardate.c'"
else
cat << \SHAR_EOF > 'stardate.c'
/*************************************************************
 * File:             stardate.c
 * Author:           Jay Windley
 * Created:           1 Jan 92
 * Copyright:        (c)  1 Jan 92 by Jay Windley
 * Description:      prints the current stardate to stdout
 *
 *************************************************************/

#include <stdio.h>
#include <sys/types.h>
#include <time.h>

#define	FIT(x,y) while((x)<0)(x)+=(y);while((x)>(y))(x)-=(y)

#define MAXPRECISION       7
#define OUTPUTFORMAT       "%%%03d.%df"

/*---------------------------------------------------------------------*
 *TAG (                           julian_day                           );
 *---------------------------------------------------------------------*
 * Returns the New Epoch Julian Day for the given Gregorian calendar
 * day.
 */
double julian_day (month, day, year)
     int month, day, year;
{
  int loc_month;
  int loc_year;
  int a, b, c, d;
  
  loc_month = month;
  loc_year = year;
  
  /* correct for March-based B.C. year */
  if (year < 0) loc_year ++;
  if (month < 3) {
    loc_month = month + 12;
    loc_year --;
  }
  
  /* set up A and B for Julian to Gregorian calendar change */
  if (year < 1582) b = 0;
  else if (year == 1582) {
    if (month < 10) b = 0;
    else if (month == 10) {
      if (day < 15) b = 0;
      else {
	a = loc_year / 100;
	b = 2 - a + (a/4);
      }
    } else {
      a = loc_year / 100;
      b = 2 - a + (a/4);
    }
  } else {
    a = loc_year / 100;
    b = 2 - a + (a/4);		/* century is set up */
  }
  
  /* fudge for year and month */
  c = (int) (365.25 * loc_year) - 694025;
  d = (int) (30.6001 * (loc_month + 1));
  
  return (double) (b + c + d + day) - .5;
}

/*---------------------------------------------------------------------*
 *TAG (                            sidereal                            );
 *---------------------------------------------------------------------*
 * Returns Greenwich Mean Sidereal Time for the given Greenwich Mean
 * Solar Time on the given NE Julian Day.
 */
double sidereal (gmt, jd, gyear)
     double gmt;		/* Greenwich Mean Time, decimal	*/
     double jd;			/* Julian Day */
     int gyear;			/* calendar year */
{
  register double dayfudge, yrfudge, jhund;
  double initjd, hourfudge, time0, lst;
  
  /* find Julian century at start of year */
  initjd = julian_day (1, 0, gyear);
  jhund = initjd / 36525.0;
  
  /* apply polynomial correction */
  dayfudge = 6.6460656 + (0.051262 + (jhund * 0.00002581)) * jhund;
  yrfudge = 2400.0 * (jhund - ( (double) (gyear - 1900) / 100));
  hourfudge = 24.0 - dayfudge - yrfudge;
  time0 = (jd - initjd) * 0.0657098 - hourfudge;
  
  /* adjust to modulo 24 hours */
  lst = (gmt * 1.002737908) + time0;
  FIT (lst, 24.0);
  return lst;
}

/*---------------------------------------------------------------------*
 *TAG (                              main                              );
 *---------------------------------------------------------------------*
 * Behaves as expected.
 */
void main (argc, argv)
     int argc;
     char *argv[];
{
  int jd, precis;
  double gmt, gmst;
  time_t t;
  struct tm *tm;
  char buf[16];
  char fmt[16];

  if (argc > 1) {
    if (strncmp (argv[1], "-d", 2) == 0) {
      if (sscanf (&argv[1][2], "%d", &precis) == 0) {
	fprintf (stderr, "%s: invalid precision specification\n", argv[0]);
	exit (1);
      }

      if (precis < 1) precis = 1;
      if (precis > MAXPRECISION) precis = MAXPRECISION;
    } else {
      fprintf (stderr, "%s: invalid option\n", argv[0]);
      exit (1);
    }
  } else precis = 1;
  
  t = time (NULL);
  tm = gmtime (&t);
  jd = julian_day (tm->tm_mon + 1, tm->tm_mday, tm->tm_year + 1900);
  gmt = (double) tm->tm_hour +
    tm->tm_min / 60.0 +
    tm->tm_sec / 3600.0;
  gmst = sidereal (gmt, (double) jd, tm->tm_year);
  sprintf (fmt, OUTPUTFORMAT, precis + 6, precis);
  sprintf (buf, fmt, (double) jd + gmst / 24.0);
  puts (buf);
}
SHAR_EOF
fi # end of overwriting check
#	End of shell archive
exit 0
Newsgroups: rec.arts.startrek.tech