Logo Search packages:      
Sourcecode: libical version File versions  Download package

caldate.c

/*
 *    Copyright (c) 1986-2000, Hiram Clawson 
 *    All rights reserved.
 *
 *    Redistribution and use in source and binary forms, with or
 *    without modification, are permitted provided that the following
 *    conditions are met:
 *
 *          Redistributions of source code must retain the above
 *          copyright notice, this list of conditions and the
 *          following disclaimer.
 *
 *          Redistributions in binary form must reproduce the
 *          above copyright notice, this list of conditions and
 *          the following disclaimer in the documentation and/or
 *          other materials provided with the distribution.
 *
 *          Neither name of The Museum of Hiram nor the names of
 *          its contributors may be used to endorse or promote products
 *          derived from this software without specific prior
 *          written permission. 
 *
 *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 *    CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
 *    INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 *    MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 *    IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 *    INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 *    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 *    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 *    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 *    STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 *    IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 *    THE POSSIBILITY OF SUCH DAMAGE. 
 */

#include "astime.h"     /*    time structures   */

/**
 *    caldat computes the day of the week, the day of the year
 *    the gregorian (or julian) calendar date and the universal
 *    time from the julian decimal date.
 *    for astronomical purposes, The Gregorian calendar reform occurred
 *    on 15 Oct. 1582.  This is 05 Oct 1582 by the julian calendar.

 *    Input:      a ut_instant structure pointer, where the j_date element
 *          has been set. ( = 0 for 01 Jan 4713 B.C. 12 HR UT )
 *
 *    output:  will set all the other elements of the structure.
 *          As a convienence, the function will also return the year.
 *
 *    Reference: Astronomial formulae for calculators, meeus, p 23
 *    from fortran program by F. Espenak - April 1982 Page 277,
 *    50 Year canon of solar eclipses: 1986-2035
 *
 */

long caldat( date )
struct ut_instant * date;
{
      double frac;
      long jd;
      long ka;
      long kb;
      long kc;
      long kd;
      long ke;
      long ialp;

      jd = (long) (date->j_date + 0.5);   /* integer julian date */
      frac = date->j_date + 0.5 - (double) jd + 1.0e-10; /* day fraction */
      ka = (long) jd;
      if ( jd >= 2299161L )
      {
            ialp = ( (double) jd - 1867216.25 ) / ( 36524.25 );
            ka = jd + 1L + ialp - ( ialp >> 2 );
      }
      kb = ka + 1524L;
      kc =  ( (double) kb - 122.1 ) / 365.25;
      kd = (double) kc * 365.25;
      ke = (double) ( kb - kd ) / 30.6001;
      date->day = kb - kd - ((long) ( (double) ke * 30.6001 ));
      if ( ke > 13L )
            date->month = ke - 13L;
      else
            date->month = ke - 1L;
      if ( (date->month == 2) && (date->day > 28) )
            date->day = 29;
      if ( (date->month == 2) && (date->day == 29) && (ke == 3L) )
            date->year = kc - 4716L;
      else if ( date->month > 2 )
            date->year = kc - 4716L;
      else
            date->year = kc - 4715L;
      date->i_hour = date->d_hour = frac * 24.0;      /* hour */
      date->i_minute = date->d_minute =
            ( date->d_hour - (double) date->i_hour ) * 60.0; /* minute */
      date->i_second = date->d_second =
            ( date->d_minute - (double) date->i_minute ) * 60.0;/* second */
      date->weekday = (jd + 1L) % 7L;     /* day of week */
      if ( date->year == ((date->year >> 2) << 2) )
            date->day_of_year =
                  ( ( 275 * date->month ) / 9)
                  - ((date->month + 9) / 12)
                  + date->day - 30;
      else
            date->day_of_year =
                  ( ( 275 * date->month ) / 9)
                  - (((date->month + 9) / 12) << 1)
                  + date->day - 30;
      return( date->year );
}

/**
 *    juldat computes the julian decimal date (j_date) from
 *    the gregorian (or Julian) calendar date.
 *    for astronomical purposes, The Gregorian calendar reform occurred
 *    on 15 Oct. 1582.  This is 05 Oct 1582 by the julian calendar.
 *    Input:  a ut_instant structure pointer where Day, Month, Year and
 *          i_hour, i_minute, d_second have been set for the date
 *          in question.
 *
 *    Output: the j_date and weekday elements of the structure will be set.
 *          Also, the return value of the function will be the j_date too.
 *
 *    Reference: Astronomial formulae for calculators, meeus, p 23
 *    from fortran program by F. Espenak - April 1982 Page 276,
 *    50 Year canon of solar eclipses: 1986-2035
 */

double juldat( date )
struct ut_instant * date;
{
      double frac, gyr;
      long iy0, im0;
      long ia, ib;
      long jd;

      /* decimal day fraction */
      frac = (( double)date->i_hour/ 24.0)
            + ((double) date->i_minute / 1440.0)
            + (date->d_second / 86400.0);
      /* convert date to format YYYY.MMDDdd     */
      gyr = (double) date->year
            + (0.01 * (double) date->month)
            + (0.0001 * (double) date->day)
            + (0.0001 * frac) + 1.0e-9;
      /* conversion factors */
      if ( date->month <= 2 )
      {
            iy0 = date->year - 1L;
            im0 = date->month + 12;
      }
      else
      {
            iy0 = date->year;
            im0 = date->month;
      }
      ia = iy0 / 100L;
      ib = 2L - ia + (ia >> 2);
      /* calculate julian date      */
      if ( date->year < 0L )
            jd = (long) ((365.25 * (double) iy0) - 0.75)
                  + (long) (30.6001 * (im0 + 1L) )
                  + (long) date->day + 1720994L;
      else
            jd = (long) (365.25 * (double) iy0)
                  + (long) (30.6001 * (double) (im0 + 1L))
                  + (long) date->day + 1720994L;
      if ( gyr >= 1582.1015 ) /* on or after 15 October 1582      */
            jd += ib;
      date->j_date = (double) jd + frac + 0.5;
      jd = (long) (date->j_date + 0.5);
      date->weekday = (jd + 1L) % 7L;
      return( date->j_date );
}     /*    end of      double juldat( date )   */

Generated by  Doxygen 1.6.0   Back to index