Index: trunk/doc/pslib/psLibADD.tex
===================================================================
--- trunk/doc/pslib/psLibADD.tex	(revision 3430)
+++ trunk/doc/pslib/psLibADD.tex	(revision 3436)
@@ -1,3 +1,3 @@
-%%% $Id: psLibADD.tex,v 1.66 2005-03-16 01:50:24 jhoblitt Exp $
+%%% $Id: psLibADD.tex,v 1.67 2005-03-17 01:36:07 jhoblitt Exp $
 \documentclass[panstarrs]{panstarrs}
 
@@ -786,24 +786,29 @@
 Correct time representation is \emph{critical} in astronomical software.  PSLib
 uses the \code{psTime} structure to represent time values.  This structure
-represents a time which is consists of seconds and fractions of seconds in a
-time system defined by the \code{psTimeType} element \code{type}.  Two possible
-time systems are currently available: TAI and UTC.  Both are defined in terms
-of the reference epoch ``1970-01-01T00:00:00Z'', but with minor modifications
-for leap seconds as needed.  The first represenatation, TAI (International
-Atomic Time), has seconds of uniform length (SI seconds) and no leap seconds.
-The exact zero reference is ``1970-01-01T00:00:10Z'' UTC.  The second
-representation is UTC, which has seconds of uniform length and leap seconds as
-needed to adjust it to remain within 0.9 seconds of the Earth's rotation.  It
-has a zero-point of exactly ``1970-01-01T00:00:00Z'' UTC.
+represents a time which consists of seconds and nanoseconds in a time
+system defined by the \code{psTimeType} element \code{type}.  All available
+time-systems are defined in terms of the reference epoch
+``1970-01-01T00:00:00Z'' (Gregorian\footnote{Gregorian Calendar -
+http://en.wikipedia.org/wiki/Gregorian\_calendar}), but with minor
+modifications, as needed, for for features such as leap-seconds.  The first
+represenatation, TAI (International Atomic Time), has seconds of uniform length
+(SI seconds) and no leap-seconds.  The exact zero reference is
+``1970-01-01T00:00:10Z'' UTC.  The second representation is UTC, which has
+seconds of uniform length and leap-seconds as needed to adjust it to remain
+within $0.9s$ of the Earth's rotation.  It has a zero-point of exactly
+``1970-01-01T00:00:00Z'' UTC.
 
 \paragraph{Coordinated Universal Time (UTC)}
 
-Coordinated Univeral Time (UTC) is a system of time with SI length
-seconds but attempts to stay within 1s of UT1.  This is done by the
-insertion of leap second whenever UTC-UT1 $\ge$ 0.9s.  By definition
-UTC-TAI is an integer number of seconds.  UTC went into effect on
-``1972-01-01T00:00:00Z'' and is defined as being TAI-UTC = 10s on that
-date.  For dates prior to 1972-01-01 a fixed offset of 10s relative
-to TAI will be assumed.
+Coordinated Univeral Time (UTC) is defined by the International
+Telecommunication Union (ITU)\footnote{ITU website -
+http://www.itu.int/home/index.html}.  It is a system of time with SI length
+seconds but attempts to stay within $1s$ of UT1.  This is done by the insertion
+of a ``leap-second'' whenever $\lvert UTC-UT1 \rvert \ge 0.9s$.  By
+definition\footnote{UTC definition -
+http://www.cl.cam.ac.uk/~mgk25/volatile/ITU-R-TF.460-4.pdf}, $UTC-TAI$ is an
+integer number of seconds.  UTC went into effect on ``1972-01-01T00:00:00Z''
+and is defined as being $TAI-UTC = 10s$ on that date.  For dates prior to
+``1972-01-01'' a fixed offset of 10s relative to TAI will be assumed.
 
 \begin{equation}
@@ -811,32 +816,34 @@
 \end{equation}
 
-Leapseconds are declared by the International Earth Rotation and Reference
-Systems Service (IERS).  Leapseconds only occur in the UTC time system and
-cannot be accurately predicted due to variations in the Earth's rotational
-period.  To determine the number of leapsecond in a given UTC date a table of
-leapseconds as annouced by the IERS must be consulted.  This table will have to
-be updated each time a new leapsecond occurs.
+Leap-seconds are declared by the International Earth Rotation and Reference
+Systems Service (IERS)\footnote{IERS website - http://www.iers.org/}.
+leap-seconds only occur in the UTC time system and cannot be accurately
+predicted due to variations in the Earth's rotational period.  To determine the
+number of leap-second in a given UTC date a table of leap-seconds as annouced by
+the IERS must be consulted.  This table will have to be updated each time a new
+leap-second occurs.
 
 For ease of conversion, UTC should be represented as the number of seconds
-since the UNIX epoch of ``1970-01-01T00:00:00Z''.  \emph{Times will always be
-expressed in the 'UTC' timezone.  Use of the local timezone is forbidden.}
+since the UNIX epoch of ``1970-01-01T00:00:00Z'', non-inclusive of leap-seconds.
+\emph{Times will always be expressed in the 'UTC timezone'.  Use of the local
+timezone is forbidden.}
 
 \paragraph{International Atomic Time (TAI)}
 
-International Atomic Time or Temps Atomique International (TAI) is a
-system of time defined by the Bureau International des Poids et
-Mesures (BIPM) with SI length seconds as measured at sea level.  To
-convert from UTC to TAI add the base delta of $10s$ and all of
-the accumulated leapsecons since 1972-01-01 up until the UTC date
-being converted.
-
-\begin{equation}
-{\rm TAI} = {\rm UTC} + 10{\rm s} + {\rm leapseconds}
+International Atomic Time or Temps Atomique International (TAI) is a system of
+time defined by the Bureau International des Poids et Mesures
+(BIPM)\footnote{BIPM website - http://www.bipm.fr/} with SI length seconds as
+measured at sea level.  To convert from UTC to TAI add the base delta of $10s$
+and all of the accumulated leap-seconds since ``1972-01-01'' up until the UTC
+date being converted.
+
+\begin{equation}
+{\rm TAI} = {\rm UTC} + 10{\rm s} + {\rm leap-seconds}
 \end{equation}
 
 For ease of conversion, TAI should be represented as the number of
-seconds since the UNIX epoch of "1970-01-01T00:00:00".
-
-\paragraph{Leap seconds}
+seconds since the UNIX epoch of ``1970-01-01T00:00:00Z''.
+
+\paragraph{Leap-seconds}
 
 Leap seconds keep UTC within 0.9s of UT1.  The offset between TAI and
@@ -874,87 +881,132 @@
 file will be made configurable.
 
-This data is available from
-\code{ftp://maia.usno.navy.mil/ser7/tai-utc.dat}
+This data is available from: \code{ftp://maia.usno.navy.mil/ser7/tai-utc.dat}
 
 \paragraph{Gregorian dates to seconds}
 
-The below algorithm converts from Gregorian-formatted dates to
-seconds since the UNIX epoch.
-
+The Perl code below, based on an algorithm described in the book ``Calendrical
+Calculations''\footnote{Calendrical Calculations -
+http://emr.cs.iit.edu/home/reingold/calendar-book/second-edition/} and modified
+to return seconds, converts from Gregorian-formatted dates to seconds since the
+UNIX epoch.
+
+Given year, month, day as \code{$y, $m, $d}.
 \begin{verbatim}
-    Given year, month, day.
-
-    ### Make month in range 3..14 (treat Jan & Feb as months 13..14 of prev year):
-    if ( month <= 2 )
+    use integer;
+
+    my $adj;
+
+    # make month in range 3..14 (treat Jan & Feb as months 13..14 of
+    # prev year)
+    if ( $m <= 2 )
     {
-        year -= ( temp = ( 14 - month ) / 12 )
-        month += 12 * temp
+        $y -= ( $adj = ( 14 - $m ) / 12 );
+        $m += 12 * $adj;
     }
-    else if ( month > 14 )
+    elsif ( $m > 14 )
     {
-        year += ( temp = ( month - 3 ) / 12 )
-        month -= 12 * temp
+        $y += ( $adj = ( $m - 3 ) / 12 );
+        $m -= 12 * $adj;
     }
+
+    # make year positive (oh, for a use integer 'sane_div'!)
+    if ( $y < 0 )
+    {
+        $d -= 146097 * ( $adj = ( 399 - $y ) / 400 );
+        $y += 400 * $adj;
+    }
+
+    # add: day of month, days of previous 0-11 month period that began
+    # w/March, days of previous 0-399 year period that began w/March
+    # of a 400-multiple year), days of any 400-year periods before
+    # that, and 306 days to adjust from Mar 1, year 0-relative to Jan
+    # 1, year 1-relative (whew)
+
+    $d += ( $m * 367 - 1094 ) / 12 + $y % 100 * 1461 / 4 +
+          ( $y / 100 * 36524 + $y / 400 ) - 306;
+
+    # convert from count of days to seconds since the UNIX epoch
+    $unix = ( ( $d - 1 ) * 86400 ) - 62135596800;
+    $utc = $unix - leapseconds($unix);
+\end{verbatim}
+Outputs seconds as \code{$utc}.
+
+To go the other way:
+
+Given the number of seconds since the UNIX epoch as \code{$utc}.
+\begin{verbatim}
+    use integer;
+
+    my $unix = $utc + leapseconds( $utc )
+    $d = ( unix + 62135596800 ) / 86400
  
-    ### make year positive
-    if ( year < 0 )
+    my $rd = $d;
+
+    my $yadj = 0;
+    my ( $c, $y, $m );
+
+    # add 306 days to make relative to Mar 1, 0; also adjust $d to be
+    # within a range (1..2**28-1) where our calculations will work
+    # with 32bit ints
+    if ( $d > 2**28 - 307 )
     {
-        day -= 146097 * ( temp = ( 399 - year ) / 400 )
-        year += 400 * temp
+        # avoid overflow if $d close to maxint
+        $yadj = ( $d - 146097 + 306 ) / 146097 + 1;
+        $d -= $yadj * 146097 - 306;
     }
- 
-    ### add: day of month, days of previous 0-11 month period that began
-    ### w/March, days of previous 0-399 year period that began w/March
-    ### of a 400-multiple year), days of any 400-year periods before
-    ### that, and 306 days to adjust from Mar 1, year 0-relative to Jan
-    ### 1, year 1-relative
-    day += ( month * 367 - 1094 ) / 12 + year % 100 * 1461 / 4 +
-          ( year / 100 * 36524 + year / 400 ) - 306
-
-    unix = ( ( day - 1 ) * 86400 ) - 62135596800
-    utc = unix - leapseconds(unix)
+    elsif ( ( $d += 306 ) <= 0 )
+    {
+        $yadj =
+          -( -$d / 146097 + 1 );    # avoid ambiguity in C division of negatives        $d -= $yadj * 146097;
+    }
+
+    $c = ( $d * 4 - 1 ) / 146097;   # calc # of centuries $d is after 29 Feb of yr 0
+    $d -= $c * 146097 / 4;          # (4 centuries = 146097 days)
+    $y = ( $d * 4 - 1 ) / 1461;     # calc number of years into the century,
+    $d -= $y * 1461 / 4;            # again March-based (4 yrs =~ 146[01] days)
+    $m = ( $d * 12 + 1093 ) / 367;  # get the month (3..14 represent March through
+    $d -= ( $m * 367 - 1094 ) / 12; # February of following year)
+    $y += $c * 100 + $yadj * 400;   # get the real year, which is off by
+    ++$y, $m -= 12 if $m > 12;      # one if month is January or February
+
+    if ( $_[0] )
+    {
+        my $dow;
+
+        if ( $rd < -6 )
+        {
+            $dow = ( $rd + 6 ) % 7;
+            $dow += $dow ? 8 : 1;
+        }
+        else
+        {
+            $dow = ( ( $rd + 6 ) % 7 ) + 1;
+        }
+
+        my $doy =
+            $class->_end_of_last_month_day_of_year( $y, $m );
+
+        $doy += $d;
+
+        my $quarter;
+        {
+            no integer;
+            $quarter = int( ( 1 / 3.1 ) * $m ) + 1;
+        }
+
+        my $qm = ( 3 * $quarter ) - 2;
+
+        my $doq =
+            ( $doy -
+              $class->_end_of_last_month_day_of_year( $y, $qm )
+            );
 \end{verbatim}
-
-To go the other way:
-
-\begin{verbatim}
-    unix = utc + leapseconds(utc)
-    day = ( unix + 62135596800 ) / 86400
-    temp = 0
- 
-    ### add 306 days to make relative to Mar 1, 0; also adjust day to be
-    ### within a range (1..2**28-1) where our calculations will work
-    ### with 32bit ints
-    if ( day > 2**28 - 307 )
-    {
-        ### avoid overflow if day close to maxint
-        temp = ( day - 146097 + 306 ) / 146097 + 1
-        day -= temp * 146097 - 306
-    }
-    else if ( ( day += 306 ) <= 0 )
-    {
-        temp = -( -day / 146097 + 1 )  ### avoid ambiguity in C division of negatives
-        day -= temp * 146097
-    }
- 
-    cent = ( day * 4 - 1 ) / 146097    ### calc number of centuries day is after 29 Feb of yr 0
-    day -= cent * 146097 / 4           ### (4 centuries = 146097 days)
-    year = ( day * 4 - 1 ) / 1461      ### calc number of years into the century,
-    day -= year * 1461 / 4             ### again March-based (4 yrs =~ 146[01] days)
-    month = ( day * 12 + 1093 ) / 367  ### get the month (3..14 represent March through
-    day -= ( month * 367 - 1094 ) / 12 ### February of following year)
-    year += cent * 100 + temp * 400    ### get the real year, which is off by
-    if ( month > 12 )                  ### one if month is January or February
-    {
-        year++
-	month -= 12
-    }
-
-
-    Output year, month, day.
-\end{verbatim}
-
-(Above taken from \code{DateTime.pm} (C) 2003 Dave Rolsky, available
-from \code{datetime.perl.org}.)
+Outputs year, month, day as \code{$y, $m, $d}.
+
+\emph{The above code was taken [and slightly altered] from
+\code{DateTime.pm}\footnote{DateTime.pm -
+http://search.cpan.org/~drolsky/DateTime/} (C)  2003 Dave Rolsky.
+Please see the DateTime project website\footnote{DateTime project -
+http://datetime.perl.org} for further details.}
 
 
@@ -978,12 +1030,11 @@
 post-2003 definition.
 
-UT1 is continuously measured by the International Earth Rotation
-Service\footnote{IERS - http://maia.usno.navy.mil/}, and tabulated values of the
-offset of UT1 from UTC are published at regular intervals, along with predicted
-future values.  IERS Bulletin A gives "rapid response" values necessary for
-real-time and near real-time data analysis (such as Pan-STARRS Otis and IPP
-subsystems). Bulletin B gives the results of a final, definitive data
-reduction.  An amalgam of Bulletin A and B values is published daily on the
-IERS website\footnote{IERS Bulletin A \& B -
+UT1 is continuously measured by the International Earth Rotation Service, and
+tabulated values of the offset of UT1 from UTC are published at regular
+intervals, along with predicted future values.  IERS Bulletin A gives ``rapid
+response'' values necessary for real-time and near real-time data analysis
+(such as Pan-STARRS Otis and IPP subsystems). Bulletin B gives the results of a
+final, definitive data reduction.  An amalgam of Bulletin A and B values is
+published daily on the IERS website\footnote{IERS Bulletin A \& B -
 http://maia.usno.navy.mil/ser7/finals2000A.daily} along with a desciption of
 the format\footnote{IERS finals2000A.daily table format -
@@ -1003,19 +1054,60 @@
 IERS publications references above, and should be interpolated in the same way.
 
-\paragraph{Julian Day and Modified Julian Day}
-
-Julian Day (JD) and Modified Julian Day (MJD) are both continuous time
-representations, with one julian day interval having a length of 86400
-TAI seconds.  MJD is equal to JD - 2400000.5 and has a zero point
-equal to that of TAI, while JD has a zero point 0.5 off of TAI.
+\paragraph{Julian Date and Modified Julian Date}
+
+The follow definitions of Julian Date (JD) and Modified Julian Date (MJD) was
+taken from, ``RESOLUTION B1: ON THE USE OF JULIAN DATES'' of ``The XXIIIrd
+International Astronomical Union General Assembly''\footnote{RESOLUTION B1: ON
+THE USE OF JULIAN DATES -
+http://www.iers.org/iers/earth/resolutions/UAI\_b1.html}.
+
+\subparagraph{Julian Date}
+
+\begin{verbatim}
+1. Julian day number (JDN)
+
+The Julian day number associated with the solar day is the number assigned to a
+day in a continuous count of days beginning with the Julian day number 0
+assigned to the day starting at Greenwich mean noon on 1 January 4713 BC,
+Julian proleptic calendar -4712.
+
+2. Julian Date (JD)
+
+The Julian Date (JD) of any instant is the Julian day number for the preceding
+noon plus the fraction of the day since that instant. A Julian Date begins at
+12h 0m 0s and is composed of 86400 seconds. To determine time intervals in a
+uniform time system it is necessary to express the JD in a uniform time scale.
+For that purpose it is recommended that JD be specified as SI seconds in
+Terrestrial Time (TT) where the length of day is 86,400 SI seconds.
+
+In some cases it may be necessary to specify Julian Date using a different time
+scale. (See Seidelmann, 1992, for an explanation of the various time scales in
+use). The time scale used should be indicated when required such as JD(UT1). It
+should be noted that time intervals calculated from differences of Julian Dates
+specified in non-uniform time scales, such as UTC, may need to be corrected for
+changes in time scales (e.g. leap seconds).
+\end{verbatim}
+
+\subparagraph{Modified Julian Date}
+
+\begin{verbatim}
+"that for those cases where it is convenient to employ a day beginning at
+midnight, the Modified Julian Date (equivalent to the Julian Date minus 2 400
+000.5) be used"
+\end{verbatim}
+
+\subparagraph{JD and MJD conversion}
+
 Conversion between \code{psTime} values and MJD and JD are determined
 from:
 
+Where \code{psTime} is a \code{PS_TIME_TAI}.
 \begin{verbatim}
-mjd = psTime.sec/86400.0 + psTime.usec/86400000000.0 + 40587.0;
- jd = psTime.sec/86400.0 + psTime.usec/86400000000.0 + 2440587.5;
+mjd = psTime.sec/86400.0 + psTime.nsec/86400000000000.0 + 40587.0;
+ jd = psTime.sec/86400.0 + psTime.nsec/86400000000000.0 + 2440587.5;
 \end{verbatim}
 
-$2451545.0$ JD $= 51544.5$ MJD is equivalent to ``2000-01-01T00:00:00Z''.
+For reference $2451545.0$ JD $= 51544.5$ MJD is equivalent to
+``2000-01-01T00:00:00Z''.
 
 \begin{equation}
