From: curt Date: Fri, 3 Sep 1999 00:24:30 +0000 (+0000) Subject: Added support for timegm() which returns time_t and explicitely expects GMT X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=8d1be9f893820c70ce3a49a8dc16f9a1aa4f2a45;p=flightgear.git Added support for timegm() which returns time_t and explicitely expects GMT input. --- diff --git a/acconfig.h b/acconfig.h index bcdaae990..e708de346 100644 --- a/acconfig.h +++ b/acconfig.h @@ -153,6 +153,9 @@ /* Define if you have that is POSIX.1 compatible. */ #undef HAVE_SYS_WAIT_H +/* Define if you have timegm() */ +#undef HAVE_TIMEGM + /* Define if you external variables timezone. */ #undef HAVE_TIMEZONE diff --git a/src/Time/fg_time.cxx b/src/Time/fg_time.cxx index 92f9c6a7f..ad92f980c 100644 --- a/src/Time/fg_time.cxx +++ b/src/Time/fg_time.cxx @@ -341,20 +341,31 @@ void FGTime::update(FGInterface *f) /****************************************************************** * 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. @@ -363,18 +374,6 @@ time_t FGTime::get_gmt(int year, int month, int day, int hour, int min, int sec) { 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; @@ -383,9 +382,24 @@ time_t FGTime::get_gmt(int year, int month, int day, int hour, int min, int sec) 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); @@ -397,11 +411,11 @@ time_t FGTime::get_gmt(int year, int month, int day, int hour, int min, int sec) 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 ) { @@ -422,8 +436,8 @@ time_t FGTime::get_gmt(int year, int month, int day, int hour, int min, int sec) 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() diff --git a/tests/test-mktime.cxx b/tests/test-mktime.cxx index 7602d1742..9f5d4129e 100644 --- a/tests/test-mktime.cxx +++ b/tests/test-mktime.cxx @@ -22,6 +22,13 @@ #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 ) { @@ -53,18 +60,6 @@ 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; @@ -73,9 +68,16 @@ time_t get_start_gmt(int 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); @@ -85,10 +87,10 @@ time_t get_start_gmt(int year) { 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 ) { @@ -108,8 +110,8 @@ time_t get_start_gmt(int year) { 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 ) } @@ -120,13 +122,19 @@ int main() { 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");