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