123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- #ifndef LPJGUESS_GUESSNC_CFTIME_H
- #define LPJGUESS_GUESSNC_CFTIME_H
- #ifdef HAVE_NETCDF
- #include <string>
- namespace GuessNC {
- namespace CF {
- /// CF calendar types supported by this library
- enum CalendarType {
- STANDARD, // also known as gregorian
- PROLEPTIC_GREGORIAN, // a Gregorian calendar extended to dates before the Julian/Gregorian switch
- NO_LEAP
- };
- /// Parses a calendar string specification (such as "gregorian")
- CalendarType parse_calendar(const char* calendar);
- /// CF time units supported by this library
- enum TimeUnit {
- SECONDS = 0,
- MINUTES,
- HOURS,
- DAYS,
- NBR_TIMEUNITS
- };
- /// Parses a time unit string specification (such as "days")
- TimeUnit parse_time_unit(const char* time_unit);
- /// Represents a date and time of day
- /** Does not support time zones
- */
- class DateTime {
- public:
- /// Constructs a default DateTime (0000-01-01 00:00:00.0)
- DateTime();
- /// Constructs a DateTime
- /**
- * \param year Calendar year
- * \param month Month (1-12)
- * \param day Day (1-31)
- * \param hour Hour (0-23)
- * \param minute Minute (0-59)
- * \param second Second (0 up to, but not including 60)
- */
- DateTime(int year, int month, int day,
- int hour, int minute, double second);
- /// Constructs a DateTime from a CF date time specification
- /** The time specification is a string such as "1973-01-01 04:20:10"
- * If the string contains time zone information, that part will be
- * ignored.
- */
- DateTime(const char* specification);
- /// Comparison operator
- bool operator==(const DateTime& other) const;
- /// \returns year
- int get_year() const { return year; }
- /// \returns month number (1-12)
- int get_month() const { return month; }
- /// \returns day number (1-31)
- int get_day() const { return day; }
- /// \returns hour (0-23)
- int get_hour() const;
- /// \returns minute (0-59)
- int get_minute() const;
- /// \returns second (0 up to, but not including 60)
- /** Note that this might return fractional seconds */
- double get_second() const;
- /// \returns seconds since midnight this date
- double get_seconds_after_midnight() const;
- /// Adds an amount of time of a given time unit, given a certain calendar
- /** The original date is assumed to be a valid date in the given calendar.
- *
- * The result is by default rounded to closest second. The reason for this
- * is that doubles can't represent all numbers perfectly, so you may e.g.
- * end up a nanosecond before midnight even though you shouldn't, which
- * can be very bad if you care about dates but not about nanoseconds.
- * To disable this, set resolution to 0.
- */
- void add_time(double time, TimeUnit time_unit, CalendarType calendar_type,
- double resolution = 1.0);
- /// Creates a string representation of the object
- std::string to_string() const;
- private:
- /// Adds a given number of days to the date, given a certain calendar
- void add_days(int days, CalendarType calendar_type);
- /// Returns days since Jan 1 this year
- int get_day_index(CalendarType calendar_type) const;
-
- /// Help function for add_days, takes year long leaps
- void skip_ahead_whole_years(int& days, CalendarType calendar_type);
- /// Help function for add_days, takes month long leaps
- void skip_ahead_whole_months(int& days, CalendarType calendar_type);
- /// calendar year
- int year;
- /// calendar month (1-12)
- int month;
- /// calendar day (1-31)
- int day;
- /// seconds after midnight (0 up to, but not including 86400)
- double seconds;
- };
- /// A CF time unit specification consisting of a starting point and a time unit
- class TimeUnitSpecification {
- public:
- /// Default constructor
- /** Creates a time unit specification representing seconds since
- * the standard Unix epoch (1970-01-01 00:00:00). */
- TimeUnitSpecification();
- /// Constructor
- /** Parses a CF time unit specification string,
- * such as "days since 1970-01-01 00:00:00" */
- TimeUnitSpecification(const char* specification);
- /// Returns the DateTime corresponding to a time offset
- /** Calculates a DateTime in a certain calendar by adding
- * the time parameter to the reference_time according
- * to the chosen time_unit.
- *
- * Rounds to nearest second by default, see resolution parameter
- * to DateTime::add_time
- */
- DateTime get_date_time(double time, CalendarType calendar,
- double resolution = 1.0) const;
- private:
- /// Start time
- DateTime reference_time;
- /// How to interpret time offsets
- TimeUnit time_unit;
- };
- } // namespace CF
- } // namespace GuessNC
- #endif // HAVE_NETCDF
- #endif // LPJGUESS_GUESSNC_CFTIME_H
|