1 #ifndef EARTH_TIME_GROUP
2 #define EARTH_TIME_GROUP
5 // Author : Chris Koeritz
6 /******************************************************************************
7 * Copyright (c) 1999-$now By Author. This program is free software; you can *
8 * redistribute it and/or modify it under the terms of the GNU General Public *
9 * License as published by the Free Software Foundation; either version 2 of *
10 * the License or (at your option) any later version. This is online at: *
11 * http://www.fsf.org/copyleft/gpl.html *
12 * Please send any updates to: fred@gruntose.com *
13 \*****************************************************************************/
15 #include <basis/astring.h>
16 #include <basis/byte_array.h>
17 #include <basis/contracts.h>
18 #include <structures/object_packers.h>
20 //! A set of methods for rendering calendrical and clock times.
22 It is based on the Gregorian calendar currently in use by the USA and other
28 enum days { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY };
29 //!< The names of the days of the week.
31 days day_now(); //!< Returns the current local day.
33 const char *day_name(days to_name);
34 //!< Returns the name of the day "to_name".
36 enum months { JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST,
37 SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER };
38 //!< The names of the months in our calendar.
40 months month_now(); //!< returns the local month.
42 const char *month_name(months to_name);
43 //!< Returns the name of the month "to_name".
44 const char *short_month_name(months to_name);
45 //!< Returns a shorter, constant-length (3 characters) month name.
47 extern const int days_in_month[12];
48 //!< The number of days in each month in the standard year.
49 extern const int leap_days_in_month[12];
50 //!< The number of days in each month in a leap year.
52 extern const int julian_days_in_month[12];
53 //!< Number of days in each month based on the julian calendar.
54 extern const int julian_leap_days_in_month[12];
55 //!< Number of days in each month of a leap year in the julian calendar.
57 const int SECONDS_IN_MINUTE = 60; //!< Number of seconds in one minute.
58 const int MINUTES_IN_HOUR = 60; //!< Number of minutes in an hour.
59 const int HOURS_IN_DAY = 24; //!< Number of hours in a day.
60 const int DAYS_IN_YEAR = 365; //!< Number of days in a standard year.
61 const int LEAP_DAYS_IN_YEAR = 366; //!< Number of days in a leap year.
62 const double APPROX_DAYS_IN_YEAR = 365.2424;
63 //!< A more accurate measure of the number of days in a year.
64 /*!< This is the more accurate mean length of time in 24 hour days between
65 vernal equinoxes. it's about 11 minutes shy of 365.25 days. */
67 //! An enumeration of time zones, both relative and absolute.
69 LOCAL_ZONE, //!< The time zone this computer is configured to report.
70 GREENWICH_ZONE //!< The time zone of Greenwich Mean Time.
73 // now some structures for representing time...
75 //! A specific point in time as represented by a 24 hour clock.
76 class clock_time : public virtual basis::packable
79 int hour; //!< The hour represented in military time: 0 through 23.
80 int minute; //!< The number of minutes after the hour.
81 int second; //!< The number of seconds after the current minute.
82 int millisecond; //!< The number of milliseconds elapsed in this second.
83 int microsecond; //!< Number of microseconds elapsed in this millisecond.
85 //! Constructs a clock_time object given all the parts.
86 clock_time(int h = 0, int m = 0, int s = 0, int ms = 0, int us = 0)
87 : hour(h), minute(m), second(s), millisecond(ms),
91 int packed_size() const { return 5 * structures::PACKED_SIZE_INT32; }
93 virtual void pack(basis::byte_array &packed_form) const;
94 //!< Packs a clock time into an array of bytes.
95 virtual bool unpack(basis::byte_array &packed_form);
96 //!< Unpacks a clock time from an array of bytes.
98 bool operator < (const clock_time &to_compare) const;
99 //!< Returns true if this clock_time is earlier than "to_compare"
100 bool operator == (const clock_time &to_compare) const;
101 //!< Returns true if this clock_time is equal to "to_compare"
103 //! An enumeration of time formatting modes used when printing the time.
105 MERIDIAN = 0x1, //!< default: uses 12 hour with AM/PM and no seconds.
106 MILITARY = 0x2, //!< use military 24 hour time.
107 NO_AM_PM = 0x4, //!< use 12 hour time but don't include AM/PM.
108 SECONDS = 0x8, //!< include the number of seconds as a third field.
109 MILLISECONDS = 0x10 //!< milliseconds are fourth field (after secs).
112 basis::astring text_form(int how = MERIDIAN) const;
113 //!< Prints the clock_time according to "how".
114 /*!< "how" is a combination of time_formats. */
115 void text_form(basis::astring &to_stuff, int how = MERIDIAN) const;
116 //!< Prints the time into "to_stuff" given "how".
117 /*!< note that "to_stuff" will be appended to; the existing contents
120 static int normalize(clock_time &to_fix);
121 // ensures that the units in each field are in the proper range by
122 // promoting them upwards. if the clock_time goes above the maximum hour,
123 // then it rolls around. zero is returned for no rollover or a positive
124 // integer is returned for the number of rollovers that occurred. if
125 // there are any negative fields, they are rolled backwards.
126 // the returned rollovers are measured in days.
129 //! An object that represents a particular day in a year.
130 class day_in_year : public virtual basis::packable
133 months month; //!< The current month.
134 int day_in_month; //!< The day number within the month (starting at one).
135 days day_of_week; //!< The day of the week.
136 int day_of_year; //!< Numerical day, where January 1st is equal to zero.
138 int packed_size() const { return 4 * structures::PACKED_SIZE_INT32; }
140 //! Constructs a representation of the day specified.
141 day_in_year(months m = JANUARY, int dim = 1, days dow = SUNDAY,
142 int day_o_year = 1) : month(m), day_in_month(dim),
143 day_of_week(dow), day_of_year(day_o_year) {}
145 virtual void pack(basis::byte_array &packed_form) const;
146 //!< Packs a day object into an array of bytes.
147 virtual bool unpack(basis::byte_array &packed_form);
148 //!< Unpacks a day object from an array of bytes.
150 bool operator < (const day_in_year &to_compare) const;
151 //!< Returns true if this day is earlier than "to_compare"
152 /*!< Note that this only compares the month and day in the month. */
153 bool operator == (const day_in_year &to_compare) const;
154 //!< Returns true if this day is equal to "to_compare"
155 /*!< Note that this only compares the month and day in the month. */
157 //! An enumeration of ways to print out the current date.
159 // note: these classes may need to be revised in the year 9999.
160 SHORT_MONTH = 0x1, //!< default: three letter month.
161 LONG_MONTH = 0x2, //!< uses full month name.
162 INCLUDE_DAY = 0x4 //!< adds the name of the day.
165 basis::astring text_form(int how = SHORT_MONTH) const;
166 //!< Prints the day according to "how".
167 void text_form(basis::astring &to_stuff, int how = SHORT_MONTH) const;
168 //!< Prints the day according to "how" and stores it in "to_stuff".
170 static int normalize(day_in_year &to_fix, bool leap_year = false);
171 //!< normalizes the day as needed and returns the adjustment in years.
172 /*!< note that this only adjusts the day_in_month and month members
173 currently. the other counters are not changed. */
176 //! An object that represents a particular point in time.
177 /*! It contains both a time of day and the day in the year. */
178 class time_locus : public clock_time, public day_in_year,
179 public virtual basis::hoople_standard
182 int year; //!< The year, using the gregorian calendar.
184 time_locus() : clock_time(), day_in_year(), year() {}
186 DEFINE_CLASS_NAME("time_locus");
188 //! Constructs a location in time given its components.
189 time_locus(const clock_time &ct, const day_in_year &ytd, int year_in)
190 : clock_time(ct), day_in_year(ytd), year(year_in) {}
192 int packed_size() const { return clock_time::packed_size()
193 + day_in_year::packed_size() + structures::PACKED_SIZE_INT32; }
195 virtual void pack(basis::byte_array &packed_form) const;
196 //!< Packs a time_locus object into an array of bytes.
197 virtual bool unpack(basis::byte_array &packed_form);
198 //!< Unpacks a time_locus object from an array of bytes.
200 // these implement the orderable and equalizable interfaces.
201 virtual bool equal_to(const basis::equalizable &s2) const;
202 virtual bool less_than(const basis::orderable &s2) const;
203 //old bool operator < (const time_locus &to_compare) const;
204 //!< Returns true if this time_locus is earlier than "to_compare"
205 //old bool operator == (const time_locus &to_compare) const;
206 //!< Returns true if this time_locus is equal to "to_compare"
208 //! Enumerates the ways to show the year.
210 LONG_YEAR = 0x1, //!< default: full four digit year (problems in 9999).
211 SHORT_YEAR = 0x2 //!< use only last two digits of year. ugh--Y2K danger.
214 // fulfills obligation for text_formable.
215 virtual void text_form(basis::base_string &state_fill) const {
216 state_fill.assign(text_form_long(clock_time::MERIDIAN, day_in_year::SHORT_MONTH, LONG_YEAR));
219 basis::astring text_form_long(int t = clock_time::MERIDIAN,
220 int d = day_in_year::SHORT_MONTH, int y = LONG_YEAR) const;
221 //! Prints out the time_locus given the way to print each component.
222 /*< "t" is a combination of time_formats, "d" is a combination of
223 date_formats and "y" is a combination of locus_formats. */
224 void text_form_long(basis::astring &to_stuff, int t = clock_time::MERIDIAN,
225 int d = day_in_year::SHORT_MONTH, int y = LONG_YEAR) const;
226 //! Same as text_form() above, but stores into "to_stuff".
228 static int normalize(time_locus &to_fix);
229 //!< normalizes the time_locus for its clock time and date.
230 //hmmm: what are rollovers measured in?
233 int year_now(); //!< what year is it?
234 clock_time time_now(); //!< what time is it?
235 day_in_year date_now(); //!< what day on the calendar is it?
236 time_locus now(); //!< returns our current locus in the time continuum.
237 time_locus greenwich_now(); //!< returns Greenwich Mean Time (their now).