diff options
Diffstat (limited to 'pr/src/misc/prtime.c')
-rw-r--r-- | pr/src/misc/prtime.c | 39 |
1 files changed, 32 insertions, 7 deletions
diff --git a/pr/src/misc/prtime.c b/pr/src/misc/prtime.c index 5f05d5ef..42ab815b 100644 --- a/pr/src/misc/prtime.c +++ b/pr/src/misc/prtime.c @@ -50,10 +50,8 @@ #include <string.h> #include <ctype.h> - -#ifdef XP_MAC +#include <errno.h> /* for EINVAL */ #include <time.h> -#endif /* * The COUNT_LEAPS macro counts the number of leap years passed by @@ -519,8 +517,6 @@ PR_NormalizeTime(PRExplodedTime *time, PRTimeParamFn params) *------------------------------------------------------------------------- */ -#include <time.h> - #if defined(HAVE_INT_LOCALTIME_R) /* @@ -1573,6 +1569,12 @@ PR_ParseTimeStringToExplodedTime( result->tm_year = year; if (dotw != TT_UNKNOWN) result->tm_wday = (((int)dotw) - ((int)TT_SUN)); + /* + * Mainly to compute wday and yday, but normalized time is also required + * by the check below that works around a Visual C++ 2005 mktime problem. + */ + PR_NormalizeTime(result, PR_GMTParameters); + /* The remaining work is to set the gmt and dst offsets in tm_params. */ if (zone == TT_UNKNOWN && default_to_gmt) { @@ -1622,7 +1624,32 @@ PR_ParseTimeStringToExplodedTime( date you are handing it is in daylight savings mode or not; and if you're wrong, it will "fix" it for you. */ localTime.tm_isdst = -1; + +#if _MSC_VER == 1400 /* 1400 = Visual C++ 2005 (8.0) */ + /* + * mktime will return (time_t) -1 if the input is a date + * after 23:59:59, December 31, 3000, US Pacific Time (not + * UTC as documented): + * http://msdn.microsoft.com/en-us/library/d1y53h2a(VS.80).aspx + * But if the year is 3001, mktime also invokes the invalid + * parameter handler, causing the application to crash. This + * problem has been reported in + * http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=266036. + * We avoid this crash by not calling mktime if the date is + * out of range. To use a simple test that works in any time + * zone, we consider year 3000 out of range as well. (See + * bug 480740.) + */ + if (result->tm_year >= 3000) { + /* Emulate what mktime would have done. */ + errno = EINVAL; + secs = (time_t) -1; + } else { + secs = mktime(&localTime); + } +#else secs = mktime(&localTime); +#endif if (secs != (time_t) -1) { PRTime usecs64; @@ -1644,8 +1671,6 @@ PR_ParseTimeStringToExplodedTime( + 1440 * (localTime.tm_mday - 2); } - /* mainly to compute wday and yday */ - PR_NormalizeTime(result, PR_GMTParameters); result->tm_params.tp_gmt_offset = zone_offset * 60; result->tm_params.tp_dst_offset = dst_offset * 60; |