]> git.mxchange.org Git - simgear.git/blob - simgear/timing/sg_time.hxx
Mark's dynamic sun color changes.
[simgear.git] / simgear / timing / sg_time.hxx
1 /**
2  * \file sg_time.hxx
3  * Data structures and routines for managing time related values.
4  */
5
6 // Written by Curtis Olson, started August 1997.
7 //
8 // Copyright (C) 1997  Curtis L. Olson  - http://www.flightgear.org/~curt
9 //
10 // This library is free software; you can redistribute it and/or
11 // modify it under the terms of the GNU Library General Public
12 // License as published by the Free Software Foundation; either
13 // version 2 of the License, or (at your option) any later version.
14 //
15 // This library is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 // Library General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with this program; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
23 //
24 // $Id$
25
26
27 #ifndef _SG_TIME_HXX
28 #define _SG_TIME_HXX
29
30
31 #ifndef __cplusplus
32 # error This library requires C++
33 #endif
34
35
36 #include <simgear/compiler.h>
37
38 #ifdef SG_HAVE_STD_INCLUDES
39 #  include <ctime>
40 #else
41 #  include <time.h>
42 #endif
43
44 #include <simgear/timing/timezone.h>
45
46
47 /**
48  * A class to calculate and manage a variety of time parameters.
49  * The SGTime class provides many real-world time values. It
50  * calculates current time in seconds, GMT time, local time zone,
51  * local offset in seconds from GMT, Julian date, and sidereal
52  * time. All of these operate with seconds as their granularity so
53  * this class is not intended for timing sub-second events. These
54  * values are intended as input to things like real world lighting
55  * calculations and real astronomical object placement.
56
57  * To properly use the SGTime class there are a couple of things to be
58  * aware of. After creating an instance of the class, you will need to
59  * periodically (i.e. before every frame) call the update()
60  * method. Optionally, if you care about updating time zone
61  * information based on your latitude and longitude, you can call the
62  * updateLocal() method periodically as your position changes by
63  * significant amounts.
64
65  */
66
67 class SGTime {
68
69 private:
70     // tzContainer stores all the current Timezone control points/
71     SGTimeZoneContainer* tzContainer;
72
73     // Points to the current local timezone name;
74     string zonename;
75
76     // Unix "calendar" time in seconds
77     time_t cur_time;
78
79     // Break down of equivalent GMT time
80 #if defined(_MSC_VER) || defined(__MINGW32__)
81     struct tm m_gmt;    // copy of system gmtime(&time_t) structure
82 #else
83     struct tm *gmt;
84 #endif
85
86     // offset of local time relative to GMT
87     time_t local_offset;
88
89     // Julian date
90     double jd;
91
92     // modified Julian date
93     double mjd;
94
95     // side real time at prime meridian
96     double gst;
97
98     // local sidereal time
99     double lst;
100
101     // the difference between the precise / expensive sidereal time
102     // algorithm result and the quick course result.  course_gst +
103     // gst_diff has pretty good accuracy over the span of a couple hours
104     double gst_diff;
105
106     /** init common constructor code */
107     void init( double lon_rad, double lat_rad, const string& root,
108                time_t init_time );
109
110 public:
111
112     /** Default constructor */
113     SGTime();
114
115     /**
116      * Create an instance based on a specified position and data file path.
117      * This creates an instance of the SGTime object. When calling the
118      * constructor you need to provide a root path pointing to your
119      * time zone definition tree. Optionally, you can call a form of
120      * the constructor that accepts your current longitude and
121      * latitude in radians.
122      *
123      * If you don't know your position when you call the SGTime
124      * constructor, you can just use the first form (which assumes 0,
125      * 0).
126      * @param lon_rad current longitude (radians)
127      * @param lat_rad current latitude (radians)
128      * @param root root path point to data file location (timezone, etc.)
129      * @param init_time provide an initialization time, 0 means use
130               current clock time */
131     SGTime( double lon_rad, double lat_rad, const string& root,
132             time_t init_time );
133
134     /**
135      * Create an instance given a data file path.
136      * @param root root path point to data file location (timezone, etc.)
137      */
138     SGTime( const string& root );
139
140     /** Destructor */
141     ~SGTime();
142
143     /** 
144      * Update the time related variables.
145      * The update() method requires you to pass in your position and
146      * an optional time offset in seconds. The offset (or warp) allows
147      * you to offset "sim" time relative to "real" time. The update()
148      * method is designed to be called by the host application before
149      * every frame.
150      * @param lon_rad current longitude (radians)
151      * @param lat_rad current latitude (radians)
152      * @param ct specify a unix time, otherwise specify 0 to use current
153               clock time
154      * @param warp an optional time offset specified in seconds.  This
155      *        allows us to advance or rewind "time" if we choose to.  */
156     void update( double lon_rad, double lat_rad, time_t ct, long int warp );
157
158     /**
159      * Given lon/lat, update timezone information and local_offset
160      * The updateLocal() method is intended to be called less
161      * frequently - only when your position is likely to be changed
162      * enough that your timezone may have changed as well. In the
163      * FlightGear project we call updateLocal() every few minutes from
164      * our periodic event manager.
165      * @param lon_rad current longitude (radians)
166      * @param lat_rad current latitude (radians)
167      * @param root base path containing time zone directory */
168     void updateLocal( double lon_rad, double lat_rad, const string& root );
169
170     /** @return current system/unix time in seconds */
171     inline time_t get_cur_time() const { return cur_time; };
172
173     /** @return time zone name for your current position*/
174     inline const char * get_zonename() const { return zonename.c_str(); }
175
176     /** @return GMT in a "brokent down" tm structure */
177 #if defined(_MSC_VER) || defined(__MINGW32__)
178     inline struct tm* getGmt()const { return (struct tm *)&m_gmt; };
179 #else
180     inline struct tm* getGmt()const { return gmt; };
181 #endif
182
183     /** @return julian date */
184     inline double getJD() const { return jd; };
185
186     /** @return modified julian date */
187     inline double getMjd() const { return mjd; };
188
189     /** @return local side real time */
190     inline double getLst() const { return lst; };
191
192     /** @return grenich side real time (lst when longitude == 0) */
193     inline double getGst() const { return gst; };
194
195     /** @return offset in seconds to local timezone time */
196     inline time_t get_local_offset() const { return local_offset; };
197 };
198
199
200 // Some useful utility functions that don't make sense to be part of
201 // the SGTime class
202
203 /**
204  * \relates SGTime
205  * Return unix time in seconds for the given date (relative to GMT)
206  * @param year current GMT year
207  * @param month current GMT month
208  * @param day current GMT day
209  * @param hour current GMT hour
210  * @param minute current minute
211  * @param second current second
212  * @return unix/system time in seconds
213  */
214 time_t sgTimeGetGMT(int year, int month, int day, 
215                     int hour, int minute, int second);
216
217 /**
218  * \relates SGTime
219  * this is just a wrapper for sgTimeGetGMT that allows an alternate
220  * form of input parameters.
221  * @param the_time the current GMT time in the tm structure
222  * @return unix/system time in seconds
223  */
224 inline time_t sgTimeGetGMT(struct tm* the_time) {
225     // printf("Using: %24s as input\n", asctime(the_time));
226     return sgTimeGetGMT(the_time->tm_year,
227                         the_time->tm_mon,
228                         the_time->tm_mday,
229                         the_time->tm_hour,
230                         the_time->tm_min,
231                         the_time->tm_sec);
232 }
233
234 /**
235  * \relates SGTime
236  * Given a date in our form, return the equivalent modified Julian
237  * date (number of days elapsed since 1900 jan 0.5), mjd.  Adapted
238  * from Xephem.
239  * @param mn month
240  * @param dy day
241  * @param yr year
242  * @return modified julian date */
243 double sgTimeCalcMJD(int mn, double dy, int yr);
244
245 /**
246  * \relates SGTime
247  * Given an optional offset from current time calculate the current
248  * modified julian date.
249  * @param ct specify a unix time, otherwise specify 0 to use current
250           clock time
251  * @param warp number of seconds to offset from current time (0 if no offset)
252  * @return current modified Julian date (number of days elapsed
253  * since 1900 jan 0.5), mjd. */
254 double sgTimeCurrentMJD( time_t ct /* = 0 */, long int warp /* = 0 */ );
255
256 /**
257  * \relates SGTime
258  * Given an mjd, calculate greenwich mean sidereal time, gst
259  * @param mjd modified julian date
260  * @return greenwich mean sidereal time (gst) */
261 double sgTimeCalcGST( double mjd );
262
263 /**
264  * \relates SGTime
265  * Format time in a pretty form
266  * @param p time specified in a tm struct
267  * @param buf buffer space to contain the result
268  * @return pointer to character array containt the result
269  */
270 char* sgTimeFormatTime( const struct tm* p, char* buf );
271
272
273 #endif // _SG_TIME_HXX