cftime.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. #ifndef LPJGUESS_GUESSNC_CFTIME_H
  2. #define LPJGUESS_GUESSNC_CFTIME_H
  3. #ifdef HAVE_NETCDF
  4. #include <string>
  5. namespace GuessNC {
  6. namespace CF {
  7. /// CF calendar types supported by this library
  8. enum CalendarType {
  9. STANDARD, // also known as gregorian
  10. PROLEPTIC_GREGORIAN, // a Gregorian calendar extended to dates before the Julian/Gregorian switch
  11. NO_LEAP
  12. };
  13. /// Parses a calendar string specification (such as "gregorian")
  14. CalendarType parse_calendar(const char* calendar);
  15. /// CF time units supported by this library
  16. enum TimeUnit {
  17. SECONDS = 0,
  18. MINUTES,
  19. HOURS,
  20. DAYS,
  21. NBR_TIMEUNITS
  22. };
  23. /// Parses a time unit string specification (such as "days")
  24. TimeUnit parse_time_unit(const char* time_unit);
  25. /// Represents a date and time of day
  26. /** Does not support time zones
  27. */
  28. class DateTime {
  29. public:
  30. /// Constructs a default DateTime (0000-01-01 00:00:00.0)
  31. DateTime();
  32. /// Constructs a DateTime
  33. /**
  34. * \param year Calendar year
  35. * \param month Month (1-12)
  36. * \param day Day (1-31)
  37. * \param hour Hour (0-23)
  38. * \param minute Minute (0-59)
  39. * \param second Second (0 up to, but not including 60)
  40. */
  41. DateTime(int year, int month, int day,
  42. int hour, int minute, double second);
  43. /// Constructs a DateTime from a CF date time specification
  44. /** The time specification is a string such as "1973-01-01 04:20:10"
  45. * If the string contains time zone information, that part will be
  46. * ignored.
  47. */
  48. DateTime(const char* specification);
  49. /// Comparison operator
  50. bool operator==(const DateTime& other) const;
  51. /// \returns year
  52. int get_year() const { return year; }
  53. /// \returns month number (1-12)
  54. int get_month() const { return month; }
  55. /// \returns day number (1-31)
  56. int get_day() const { return day; }
  57. /// \returns hour (0-23)
  58. int get_hour() const;
  59. /// \returns minute (0-59)
  60. int get_minute() const;
  61. /// \returns second (0 up to, but not including 60)
  62. /** Note that this might return fractional seconds */
  63. double get_second() const;
  64. /// \returns seconds since midnight this date
  65. double get_seconds_after_midnight() const;
  66. /// Adds an amount of time of a given time unit, given a certain calendar
  67. /** The original date is assumed to be a valid date in the given calendar.
  68. *
  69. * The result is by default rounded to closest second. The reason for this
  70. * is that doubles can't represent all numbers perfectly, so you may e.g.
  71. * end up a nanosecond before midnight even though you shouldn't, which
  72. * can be very bad if you care about dates but not about nanoseconds.
  73. * To disable this, set resolution to 0.
  74. */
  75. void add_time(double time, TimeUnit time_unit, CalendarType calendar_type,
  76. double resolution = 1.0);
  77. /// Creates a string representation of the object
  78. std::string to_string() const;
  79. private:
  80. /// Adds a given number of days to the date, given a certain calendar
  81. void add_days(int days, CalendarType calendar_type);
  82. /// Returns days since Jan 1 this year
  83. int get_day_index(CalendarType calendar_type) const;
  84. /// Help function for add_days, takes year long leaps
  85. void skip_ahead_whole_years(int& days, CalendarType calendar_type);
  86. /// Help function for add_days, takes month long leaps
  87. void skip_ahead_whole_months(int& days, CalendarType calendar_type);
  88. /// calendar year
  89. int year;
  90. /// calendar month (1-12)
  91. int month;
  92. /// calendar day (1-31)
  93. int day;
  94. /// seconds after midnight (0 up to, but not including 86400)
  95. double seconds;
  96. };
  97. /// A CF time unit specification consisting of a starting point and a time unit
  98. class TimeUnitSpecification {
  99. public:
  100. /// Default constructor
  101. /** Creates a time unit specification representing seconds since
  102. * the standard Unix epoch (1970-01-01 00:00:00). */
  103. TimeUnitSpecification();
  104. /// Constructor
  105. /** Parses a CF time unit specification string,
  106. * such as "days since 1970-01-01 00:00:00" */
  107. TimeUnitSpecification(const char* specification);
  108. /// Returns the DateTime corresponding to a time offset
  109. /** Calculates a DateTime in a certain calendar by adding
  110. * the time parameter to the reference_time according
  111. * to the chosen time_unit.
  112. *
  113. * Rounds to nearest second by default, see resolution parameter
  114. * to DateTime::add_time
  115. */
  116. DateTime get_date_time(double time, CalendarType calendar,
  117. double resolution = 1.0) const;
  118. private:
  119. /// Start time
  120. DateTime reference_time;
  121. /// How to interpret time offsets
  122. TimeUnit time_unit;
  123. };
  124. } // namespace CF
  125. } // namespace GuessNC
  126. #endif // HAVE_NETCDF
  127. #endif // LPJGUESS_GUESSNC_CFTIME_H