URI: 
       tcalcalcs.h - pism - [fork] customized build of PISM, the parallel ice sheet model (tillflux branch)
  HTML git clone git://src.adamsgaard.dk/pism
   DIR Log
   DIR Files
   DIR Refs
   DIR LICENSE
       ---
       tcalcalcs.h (10069B)
       ---
            1 /*
            2     The CalCalcs routines, a set of C-language routines to perform
            3     calendar calculations.
            4 
            5     Version 1.0, released 7 January 2010
            6 
            7     Copyright (C) 2010 David W. Pierce, dpierce@ucsd.edu
            8 
            9     This program is free software: you can redistribute it and/or modify
           10     it under the terms of the GNU General Public License as published by
           11     the Free Software Foundation, either version 3 of the License, or
           12     (at your option) any later version.
           13 
           14     This program is distributed in the hope that it will be useful,
           15     but WITHOUT ANY WARRANTY; without even the implied warranty of
           16     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
           17     GNU General Public License for more details.
           18 
           19     You should have received a copy of the GNU General Public License
           20     along with this program.  If not, see <http://www.gnu.org/licenses/>.
           21 */
           22 
           23 #ifdef __cplusplus
           24 extern "C" {
           25 #endif
           26 
           27 #define CALCALCS_VERSION_NUMBER        1.0
           28 
           29 struct cccalendar {
           30         int        sig;
           31         char        *name;
           32         int        ndays_reg, ndays_leap;
           33 
           34         int        (*c_isleap)        ( int, int * );
           35         int        (*c_date2jday)         ( int, int, int, int * );
           36         int        (*c_jday2date)         ( int, int *, int *, int * );
           37         int        (*c_dpm)           ( int, int, int * );
           38 
           39         /* The following implement "mixed" calendars, for example, our standard
           40          * civil calendar, which converts from Julian to Gregorian, with the
           41          * last day of the Julian calendar being 4 Oct 1582 and the first day
           42          * of the Gregorian calendar being 15 Oct 1582
           43          */
           44         int        mixed;
           45         struct cccalendar *early_cal, *late_cal;
           46         int        year_x, month_x, day_x;                /* These are the transition Y,M,D, i.e., the FIRST DATE the LATER CAL is used */
           47         int        year_px, month_px, day_px;        /* These are the DAY BEFORE the transition Y,M,D, i.e., the last date the earlier cal is used */
           48         int        jday_x;                                /* Julian day of the transition date */
           49 };
           50 
           51 /* A "country code", which holds the 2-letter code (abbreviation) for the country or region,
           52  * its long name, and the Y/M/D date that it transitioned from the Julian to Gregorian calendar
           53  */
           54 struct ccs_ccode {
           55         char        *code, *longname;
           56         int        year, month, day;
           57 };
           58 
           59 typedef struct cccalendar calcalcs_cal;
           60 typedef struct ccs_ccode  ccs_country_code;
           61 
           62 /* =====================================================================================
           63  * Here are all the services this library supplies 
           64  *
           65  * -------------------------------------------------------------------------
           66  * ccs_init_calendar : initialize a calendar.  Valid passed arguments are
           67  *                 one of the following strings:
           68  *        Standard, proleptic_Gregorian, proleptic_Julian, noleap (aka 365_day and no_leap), 360_day                
           69  *
           70  * The "Standard" calendar transitions from the Julian to the Gregorian calendar, 
           71  * with the last day of the Julian calender being 1582-10-04 and the next day being
           72  * the first day of the Gregorian calendar, with the date 1582-10-15.  This "transition date"
           73  * can be set to be the value used by various countries, or set to any arbitrary
           74  * date, using routine "set_cal_xition_date", below.
           75  */
           76 calcalcs_cal *ccs_init_calendar( const char *calname );
           77 
           78 /*------------------------------------------------------------------------------
           79  * Frees the storage previously allocated by ccs_init_calendar()
           80  */
           81 void ccs_free_calendar( calcalcs_cal *calendar );
           82 
           83 /*--------------------------------------------------------------------------
           84  * ccs_date2jday: turn a Y/M/D date into a (true) Julian day number.  Note that 
           85  *               a Julian day is not the day number of the year, but rather
           86  *              the integer day number starting from 1 on the day that would
           87  *            have been 1 Jan 4713 BC if the Julian calendar went back
           88  *              to that time.
           89  */
           90 int ccs_date2jday( calcalcs_cal *calendar, int year, int month, int day, int *jday );
           91 
           92 /*--------------------------------------------------------------------------
           93  * ccs_jday2date: turn a (true) Julian day number into a calendar date.
           94  */
           95 int ccs_jday2date( calcalcs_cal *calendar, int jday, int *year, int *month, int *day );
           96 
           97 /*--------------------------------------------------------------------------
           98  * ccs_isleap: determine if the specified year is a leap year in 
           99  *         the specified calendar
          100  */
          101 int ccs_isleap( calcalcs_cal *calendar, int year, int *leap );
          102 
          103 /*--------------------------------------------------------------------------
          104  * ccs_dpm: returns the days per month for the given year/month.
          105  * Note that during the month that transitions from a Julian to a 
          106  * Gregorian calendar, this might be a strange number of days.
          107  */
          108 int ccs_dpm( calcalcs_cal *calendar, int year, int month, int *dpm );
          109 
          110 /*--------------------------------------------------------------------------
          111  * ccs_date2doy: given a Y/M/D date, calculates the day number of the year, starting at 1 for
          112  *        January 1st.
          113  */
          114 int ccs_date2doy( calcalcs_cal *calendar, int year, int month, int day, int *doy );
          115 
          116 /*--------------------------------------------------------------------------
          117  *  ccs_doy2date: given a year and a day number in that year (with counting starting at 1 for
          118  *        Jan 1st), this returns the month and day of the month that the doy refers to.
          119  */
          120 int ccs_doy2date( calcalcs_cal *calendar, int year, int doy, int *month, int *day );
          121 
          122 /*--------------------------------------------------------------------------
          123  *  ccs_dayssince: Given a Y/M/D date in a specified calendar, and the number of days since
          124  *      that date, this returns the new Y/M/D date in a (possibly different) calendar.
          125  *
          126  * Note that specifying "zero" days since, and giving different calendars as the original
          127  *      and new calendars, essentially converts dates between calendars.
          128  */
          129 int ccs_dayssince( calcalcs_cal *calendar_orig, int year_orig, int month_orig, int day_orig,
          130                 int ndays_since, calcalcs_cal *calendar_new, int *year_new, int *month_new, int *day_new );
          131 
          132 /*--------------------------------------------------------------------------
          133  * get/set_cal_xition_date: these routines set the transition date for a Standard
          134  * calendar, which is the date that the Gregorian calendar was first used.
          135  * Before that, it is assumed that the Julian calendar was used.
          136  *
          137  * Historically, this transition date varies by country and region.  The
          138  * variation can be extreme, and over the centuries country boundaries have
          139  * changed, so this should be considered only the grossest approximation. For 
          140  * that matter, for several countries, different districts/regions converted
          141  * at different times anyway, so actually doing a good job at this task is
          142  * far beyond this library's capability.  Nevertheless, this does give some
          143  * basic simplified capabilities in this regard.  And you can always set
          144  * the routines to use an arbitrary transition date of your own calculation.
          145  *
          146  * How to use these routines:
          147  *   
          148  * If you know the transition date you want to impose, simply call
          149  * set_cal_xition_date with the specified transition date.  The date
          150  * specified is the FIRST date that the new (Gregorian) calendar was
          151  * used.  For exaple, in Italy, the Gregorian calendar was first used
          152  * on 15 October 1582.
          153  *
          154  * If you don't know what transition date to use, there is a brief
          155  * database with some APPROXIMATE dates of transition that can be accessed
          156  * by calling get_cal_xition_date with a two-letter country code, corresponding
          157  * to the internet suffix for the country.  (As a special case, "US" is used
          158  * for the United States of America.)  If the routine returns 0, then the
          159  * country code is recognized and the approximate transition date is returned
          160  * in the passed parameters year, month, day.  These should then be given to
          161  * routine set_cal_xition_date to make that calendar use the specified 
          162  * transition date.  If the get_cal_xition_date routine does not return 0,
          163  * then there is no information on that country in the database.
          164  * 
          165  * routine set_cal_xition_date returns 0 on success, and something other than
          166  * 0 on an error.  Errors include trying to set the transition date to an
          167  * invalid date, or trying to set the transition date for any calendar
          168  * other than the "Standard" calendar.
          169  *
          170  * The following country/region codes are recognized: AK (Alaska) 1867/10/18;  
          171  * AL (Albania) 1912/12/1; AT (Austria) 1583/10/16; BE (Belgium) 1582/12/25;
          172  * BG (Bulgaria) 1916/4/1; CN (China) 1929/1/1; CZ (Czechoslovakia) 1584/1/17;
          173  * DK (Denmark) 1700/3/1; NO (Norway) 1700/3/1; EG (Egypt) 1875/1/1; 
          174  * EE (Estonia) 1918/1/1; FI (Finland) 1753/3/1; FR (France) 1582/12/20;
          175  * DE (Germany, note different states actually used different dates between
          176  * 1583 and 1700!) 1583/11/22; UK (Great Britain and Dominions) 1752/9/14;
          177  * GR (Greece) 1924/3/23; HU (Hungary) 1587/11/1; IT (Italy) 1582/10/15;
          178  * JP (Japan) 1918/1/1; LV (Latvia) 1915/1/1; LT (Lithuania) 1915/1/1;
          179  * LU (Luxemburg) 1582/12/15; NL (Netherlands, note Catholic regions
          180  * transitioned in various dates of 1582/83, while Protestant regions
          181  * transitioned in various dates of 1700/01) 1582/10/15; NO (Norway) 1700/3/1;
          182  * PL (Poland) 1582/10/15; PT (Portugal) 1582/10/15; RO (Romania) 1919/4/14;
          183  * ES (Spain) 1582/10/15; SE (Sweden) 1753/3/1; CH (Switzerland, note,
          184  * varied bewteen 1584 and 1701 by Canton) 1584/1/22; TR (Turkey)
          185  * 1927/1/1; YU (Yugoslavia) 1919/1/1; UK (Great Britain and Dominions) 1752/9/14;
          186  * US (United States) 1752/9/14; SU (former Soviet Union) 1918/2/1; 
          187  * RU (Russia) 1918/2/1.
          188  */
          189 int ccs_set_xition_date( calcalcs_cal *calendar, int year, int month, int day );
          190 int ccs_get_xition_date( const char *country_code, int *year, int *month, int *day );
          191 
          192 /*--------------------------------------------------------------------------
          193  * calcalcs_err_str: return a static char * to an error string, given the error nmmber
          194  */
          195 char *ccs_err_str( int errno );
          196 
          197 #define CALCALCS_ERR_NO_YEAR_ZERO                -10
          198 #define CALCALCS_ERR_DATE_NOT_IN_CALENDAR        -11
          199 #define CALCALCS_ERR_INVALID_DAY_OF_YEAR        -12
          200 #define CALCALCS_ERR_NOT_A_MIXED_CALENDAR        -13
          201 #define CALCALCS_ERR_UNKNOWN_COUNTRY_CODE        -14
          202 #define CALCALCS_ERR_OUT_OF_RANGE                -15
          203 #define CALCALCS_ERR_NULL_CALENDAR                -16
          204 #define CALCALCS_ERR_INVALID_CALENDAR                -17
          205 
          206 #ifdef __cplusplus
          207 }
          208 #endif