// $Id: ESMCI_Calendar.h,v 1.10.2.1 2010/02/05 20:00:07 svasquez Exp $ // // Earth System Modeling Framework // Copyright 2002-2010, University Corporation for Atmospheric Research, // Massachusetts Institute of Technology, Geophysical Fluid Dynamics // Laboratory, University of Michigan, National Centers for Environmental // Prediction, Los Alamos National Laboratory, Argonne National Laboratory, // NASA Goddard Space Flight Center. // Licensed under the University of Illinois-NCSA License. // // ESMF Calendar C++ definition include file // // (all lines below between the !BOP and !EOP markers will be included in // the automated document processing.) //------------------------------------------------------------------------- // // these lines prevent this file from being read more than once if it // ends up being included multiple times #ifndef ESMCI_CALENDAR_H #define ESMCI_CALENDAR_H //------------------------------------------------------------------------- // put any constants or macros which apply to the whole component in this file. // anything public or esmf-wide should be up higher at the top level // include files. #include "ESMC_Start.h" #include "ESMF_TimeMgr.inc" //------------------------------------------------------------------------- //BOP // !CLASS: ESMCI::Calendar - encapsulates calendar types and behavior // // !DESCRIPTION: // // The code in this file defines the C++ {\tt Calendar} members and method // signatures (prototypes). The companion file {\tt ESMC\_Calendar.C} contains // the full code (bodies) for the {\tt Calendar} methods. // // The {\tt Calendar} class encapsulates the knowledge (attributes and // behavior) of all required calendar types: Gregorian, Julian, Julian Day, // Modified Julian Day, no-leap, 360-day, custom, and no-calendar. // // The {\tt Calendar} class encapsulates the definition of all required // calendar types. For each calendar type, it contains the number of months // per year, the number of days in each month, the number of seconds in a day, // the number of days per year, and the number of fractional days per year. // This flexible definition allows future calendars to be defined for any // planetary body, not just Earth. // // The {\tt Calendar} class defines two methods for converting in both // directions between the core {\tt BaseTime} class representation and a // calendar date. Calculations of time intervals (deltas) between // time instants is done by the base class {\tt BaseTime} in the core units // of seconds and fractional seconds. Thus, a calendar is only needed for // converting core time to calendar time and vice versa. // // Notes: // - Instantiate as few as possible; ideally no more than one calendar // type per application (for reference only, like a wall calendar) // But may have multiples for convienience such as one per component. // - Generic enough to define for any planetary body // - if secondsPerDay != 86400, then how are minutes and hours defined ? // Assume always minute=60 seconds; hour=3600 seconds // //------------------------------------------------------------------------- // // !USES: #include "ESMC_Base.h" // inherited Base class #include "ESMCI_BaseTime.h" // inherited BaseTime class #include "ESMC_Calendar.h" // for enum ESMC_CalendarType // TODO: replace with monthsPerYear property #define MONTHS_PER_YEAR 12 namespace ESMCI{ // forward reference to prevent #include recursion class Time; class TimeInterval; // !PUBLIC TYPES: class Calendar; // !PRIVATE TYPES: // class configuration type: not needed for Calendar // class definition type class Calendar { // class Calendar : public ESMC_Base { // TODO: inherit from ESMC_Base // class when fully aligned with // F90 equiv private: // corresponds to F90 module 'type ESMF_Calendar' members char name[ESMF_MAXSTR]; // name of calendar ESMC_CalendarType calendarType; // Calendar type int daysPerMonth[MONTHS_PER_YEAR]; int monthsPerYear; // TODO: make dynamically allocatable with monthsPerYear ESMC_I4 secondsPerDay; ESMC_I4 secondsPerYear; struct daysPerYear_s { ESMC_I4 d; // integer number of days per year ESMC_I4 dN; // fractional number of days per year (numerator) ESMC_I4 dD; // (denominator) } daysPerYear; // e.g. for Venus, d=0, dN=926, dD=1000 // array of calendar type name strings static const char *const calendarTypeName[CALENDAR_TYPE_COUNT]; // one-of-each calendar type held automatically, as needed static Calendar *internalCalendar[CALENDAR_TYPE_COUNT]; static Calendar *defaultCalendar; // set-up upon ESMF_Initialize(); // defaults to ESMC_CAL_NOCALENDAR int id; // unique identifier. used for equality // checks and to generate unique default // names. // TODO: inherit from ESMC_Base class static int count; // number of calendars created. Thread-safe // because int is atomic. // TODO: inherit from ESMC_Base class // !PUBLIC MEMBER FUNCTIONS: public: // set built-in calendar type int set(int nameLen, const char *name, // TODO: default (=0) ESMC_CalendarType calendarType); // set custom calendar type int set(int nameLen, const char *name=0, int *daysPerMonth=0, int monthsPerYear=0, ESMC_I4 *secondsPerDay=0, ESMC_I4 *daysPerYear=0, ESMC_I4 *daysPerYearDn=0, ESMC_I4 *daysPerYearDd=0); // get properties of any calendar type int get(int nameLen, int *tempNameLen, char *tempName, ESMC_CalendarType *calendarType=0, int *daysPerMonth=0, int sizeofDaysPerMonth=0, int *monthsPerYear=0, ESMC_I4 *secondsPerDay=0, ESMC_I4 *secondsPerYear=0, ESMC_I4 *daysPerYear=0, ESMC_I4 *daysPerYeardN=0, ESMC_I4 *daysPerYeardD=0); // Calendar doesn't need configuration, hence GetConfig/SetConfig // methods are not required // conversions based on UTC: time zone offset done by client // (TMG 2.4.5, 2.5.6) int convertToTime(ESMC_I8 yy, int mm, int dd, ESMC_I8 d, ESMC_R8 d_r8, BaseTime *t) const; int convertToDate(BaseTime *t, ESMC_I4 *yy=0, ESMC_I8 *yy_i8=0, int *mm=0, int *dd=0, ESMC_I4 *d=0, ESMC_I8 *d_i8=0, ESMC_R8 *d_r8=0) const; Time increment(const Time *time, const TimeInterval &timeinterval) const; Time decrement(const Time *time, const TimeInterval &timeinterval) const; bool isLeapYear(ESMC_I8 yy, int *rc=0) const; bool operator==(const Calendar &) const; bool operator==(const ESMC_CalendarType &) const; bool operator!=(const Calendar &) const; bool operator!=(const ESMC_CalendarType &) const; // TODO: add method to convert calendar interval to core time ? // required methods inherited and overridden from the ESMC_Base class // for persistence/checkpointing // friend to restore state friend Calendar *ESMCI_CalendarReadRestart(int, const char*, ESMC_IOSpec*, int*); // save state int writeRestart(ESMC_IOSpec *iospec=0) const; // internal validation int validate(const char *options=0) const; // for testing/debugging int print(const char *options=0, const Time *time=0) const; // native C++ constructors/destructors Calendar(void); Calendar(const Calendar &calendar); // copy constructor Calendar(const char *name, ESMC_CalendarType calendarType); Calendar(const char *name, int *daysPerMonth, int monthsPerYear, ESMC_I4 *secondsPerDay, ESMC_I4 *daysPerYear, ESMC_I4 *daysPerYeardN, ESMC_I4 *daysPerYearDd); ~Calendar(void); // < declare the rest of the public interface methods here > // friend function to allocate and initialize calendar from heap friend Calendar *ESMCI_CalendarCreate(int, const char*, ESMC_CalendarType, int*); // friend function to allocate and initialize internal calendar from heap friend int ESMCI_CalendarCreate(ESMC_CalendarType); // friend function to allocate and initialize custom calendar from heap friend Calendar *ESMCI_CalendarCreate(int, const char*, int*, int, ESMC_I4*, ESMC_I4*, ESMC_I4*, ESMC_I4*, int*); // friend function to copy a calendar friend Calendar *ESMCI_CalendarCreate(Calendar*, int*); // friend function to de-allocate calendar friend int ESMCI_CalendarDestroy(Calendar **); // friend function to de-allocate all internal calendars friend int ESMCI_CalendarFinalize(void); // friend functions to initialize and set the default calendar friend int ESMCI_CalendarInitialize(ESMC_CalendarType *); friend int ESMCI_CalendarSetDefault(Calendar **); friend int ESMCI_CalendarSetDefault(ESMC_CalendarType *); // !PRIVATE MEMBER FUNCTIONS: // private: friend class Time; friend class TimeInterval; // // < declare private interface methods here > // //EOP //------------------------------------------------------------------------- }; // end class Calendar // Note: though seemingly redundant with the friend declarations within // the class definition above, the following declarations are necessary // to appease some compilers (most notably IBM), as well as ANSI C++. // These also establish defaults to match F90 optional args. // friend function to allocate and initialize calendar from heap Calendar *ESMCI_CalendarCreate(int nameLen, const char *name=0, ESMC_CalendarType calendarType= ESMC_CAL_NOCALENDAR, int* rc=0); // friend function to allocate and initialize internal calendar from heap int ESMCI_CalendarCreate(ESMC_CalendarType calendarType); // friend function to allocate and initialize custom calendar from heap Calendar *ESMCI_CalendarCreate(int nameLen, const char *name=0, int *daysPerMonth=0, int monthsPerYear=0, ESMC_I4 *secondsPerDay=0, ESMC_I4 *daysPerYear=0, ESMC_I4 *daysPerYearDn=0, ESMC_I4 *daysPerYearDd=0, int *rc=0); // friend function to copy a calendar Calendar *ESMCI_CalendarCreate(Calendar *calendar, int *rc=0); // friend function to de-allocate calendar int ESMCI_CalendarDestroy(Calendar **calendar); // friend function to de-allocate all internal calendars int ESMCI_CalendarFinalize(void); // friend to restore state Calendar *ESMCI_CalendarReadRestart(int nameLen, const char* name=0, ESMC_IOSpec* iospec=0, int* rc=0); // friend functions to initialize and set the default calendar int ESMCI_CalendarInitialize(ESMC_CalendarType *calendarType); int ESMCI_CalendarSetDefault(Calendar **calendar); int ESMCI_CalendarSetDefault(ESMC_CalendarType *calendarType); } // namespace ESMCI #endif // ESMC_CALENDAR_H