/******************************************************************
* The following are some functions that were included as FGTime
- * members, although they currently don't make used of any of the
+ * members, although they currently don't make use of any of the
* class's variables. Maybe this'll change in the future
*****************************************************************/
// Return time_t for Sat Mar 21 12:00:00 GMT
//
-// I believe the mktime() has a SYSV vs. BSD behavior difference.
+// On many systems it is ambiguous if mktime() assumes the input is in
+// GMT, or local timezone. To address this, a new function called
+// timegm() is appearing. It works exactly like mktime() but
+// explicitely interprets the input as GMT.
//
-// The BSD style mktime() is nice because it returns its result
-// assuming you have specified the input time in GMT
+// timegm() is available and documented under FreeBSD. It is
+// available, but completely undocumented on my current Debian 2.1
+// distribution.
//
-// The SYSV style mktime() is a pain because it returns its result
-// assuming you have specified the input time in your local timezone.
-// Therefore you have to go to extra trouble to convert back to GMT.
+// In the absence of timegm() we have to guess what mktime() might do.
+//
+// Many older BSD style systems have a mktime() that assumes the input
+// time in GMT. But FreeBSD explicitly states that mktime() assumes
+// local time zone
+//
+// The mktime() on many SYSV style systems (such as Linux) usually
+// returns its result assuming you have specified the input time in
+// your local timezone. Therefore, in the absence if timegm() you
+// have to go to extra trouble to convert back to GMT.
//
// If you are having problems with incorrectly positioned astronomical
// bodies, this is a really good place to start looking.
{
struct tm mt;
- // For now we assume that if daylight is not defined in
- // /usr/include/time.h that we have a machine with a BSD behaving
- // mktime()
-# if !defined(HAVE_DAYLIGHT)
-# define MK_TIME_IS_GMT 1
-# endif
-
- // timezone seems to work as a proper offset for Linux & Solaris
-# if defined( __linux__ ) || defined( __sun__ )
-# define TIMEZONE_OFFSET_WORKS 1
-# endif
-
mt.tm_mon = month;
mt.tm_mday = day;
mt.tm_year = year;
mt.tm_sec = sec;
mt.tm_isdst = -1; // let the system determine the proper time zone
-# if defined( MK_TIME_IS_GMT )
+ // For now we assume that if daylight is not defined in
+ // /usr/include/time.h that we have a machine with a mktime() that
+ // assumes input is in GMT ... this only matters if we are
+ // building on a system that does not have timegm()
+#if !defined(HAVE_DAYLIGHT)
+# define MK_TIME_IS_GMT 1
+#endif
+
+#if defined( HAVE_TIMEGM )
+ return ( timegm(&mt) );
+#elif defined( MK_TIME_IS_GMT )
return ( mktime(&mt) );
-# else // ! defined ( MK_TIME_IS_GMT )
+#else // ! defined ( MK_TIME_IS_GMT )
+
+ // timezone seems to work as a proper offset for Linux & Solaris
+# if defined( __linux__ ) || defined( __sun__ )
+# define TIMEZONE_OFFSET_WORKS 1
+# endif
long int start = mktime(&mt);
timezone = fix_up_timezone( timezone );
-# if defined( TIMEZONE_OFFSET_WORKS )
+# if defined( TIMEZONE_OFFSET_WORKS )
FG_LOG( FG_EVENT, FG_DEBUG,
"start = " << start << ", timezone = " << timezone );
return( start - timezone );
-# else // ! defined( TIMEZONE_OFFSET_WORKS )
+# else // ! defined( TIMEZONE_OFFSET_WORKS )
daylight = mt.tm_isdst;
if ( daylight > 0 ) {
FG_LOG( FG_EVENT, FG_DEBUG, " March 21 noon (CST) = " << start );
return ( start_gmt );
-# endif // ! defined( TIMEZONE_OFFSET_WORKS )
-# endif // ! defined ( MK_TIME_IS_GMT )
+# endif // ! defined( TIMEZONE_OFFSET_WORKS )
+#endif // ! defined ( MK_TIME_IS_GMT )
}
// Fix up timezone if using ftime()
#define LST_MAGIC_TIME_1998 890481600
+// For now we assume that if daylight is not defined in
+// /usr/include/time.h that we have a machine with a BSD behaving
+// mktime()
+#if !defined(HAVE_DAYLIGHT)
+# define MK_TIME_IS_GMT 1
+#endif
+
// Fix up timezone if using ftime()
long int fix_up_timezone( long int timezone_orig ) {
time_t get_start_gmt(int year) {
struct tm mt;
- // For now we assume that if daylight is not defined in
- // /usr/include/time.h that we have a machine with a BSD behaving
- // mktime()
-# if !defined(HAVE_DAYLIGHT)
-# define MK_TIME_IS_GMT 1
-# endif
-
- // timezone seems to work as a proper offset for Linux & Solaris
-# if defined( __linux__ ) || defined( __sun__ )
-# define TIMEZONE_OFFSET_WORKS 1
-# endif
-
mt.tm_mon = 2;
mt.tm_mday = 21;
mt.tm_year = year;
mt.tm_sec = 0;
mt.tm_isdst = -1; // let the system determine the proper time zone
-# if defined( MK_TIME_IS_GMT )
+#if defined( HAVE_TIMEGM )
+ return ( timegm(&mt) );
+#elif defined( MK_TIME_IS_GMT )
return ( mktime(&mt) );
-# else // ! defined ( MK_TIME_IS_GMT )
+#else // ! defined ( MK_TIME_IS_GMT )
+
+ // timezone seems to work as a proper offset for Linux & Solaris
+# if defined( __linux__ ) || defined( __sun__ )
+# define TIMEZONE_OFFSET_WORKS 1
+# endif
long int start = mktime(&mt);
timezone = fix_up_timezone( timezone );
-# if defined( TIMEZONE_OFFSET_WORKS )
+# if defined( TIMEZONE_OFFSET_WORKS )
printf("start = %ld, timezone = %ld\n", start, timezone);
return( start - timezone );
-# else // ! defined( TIMEZONE_OFFSET_WORKS )
+# else // ! defined( TIMEZONE_OFFSET_WORKS )
daylight = mt.tm_isdst;
if ( daylight > 0 ) {
printf(" March 21 noon (CST) = %ld\n", start);
return ( start_gmt );
-# endif // ! defined( TIMEZONE_OFFSET_WORKS )
-# endif // ! defined ( MK_TIME_IS_GMT )
+# endif // ! defined( TIMEZONE_OFFSET_WORKS )
+#endif // ! defined ( MK_TIME_IS_GMT )
}
if ( start_gmt == LST_MAGIC_TIME_1998 ) {
-#ifdef MK_TIME_IS_GMT
- printf("mktime() assumes GMT on your system, lucky you!\n");
+ printf("Time test = PASSED\n\n");
+#ifdef HAVE_TIMEGM
+ printf("You have timegm() which is just like mktime() except that\n");
+ printf("it explicitely expects input in GMT ... lucky you!\n");
+#elif MK_TIME_IS_GMT
+ printf("You don't seem to have timegm(), but mktime() seems to\n");
+ printf("assume input is GMT on your system ... I guess that works\n");
#else
printf("mktime() assumes local time zone on your system, but we can\n");
printf("compensate just fine.\n");
#endif
} else {
+ printf("Time test = FAILED\n\n");
printf("There is likely a problem with mktime() on your system.\n");
printf("This will cause the sun/moon/stars/planets to be in the\n");
printf("wrong place in the sky and the rendered time of day will be\n");