2004-01-30
2004-01-30 16:17:57 by Henrik Grubbström (Grubba) <grubba@grubba.org>
-
a7c4d9956f9a91d1d12c9346cdfa7ee2c6e115b4
(147 lines)
(+107/-40)
[
Show
| Annotate
]
Branch: 7.9
mktime() now uses my_timegm() when an UTC offset has been specified.
Rev: src/builtin_functions.c:1.525
2:
|| This file is part of Pike. For copyright information see COPYRIGHT.
|| Pike is distributed under GPL, LGPL and MPL. See the file COPYING
|| for more information.
- || $Id: builtin_functions.c,v 1.524 2004/01/11 01:16:08 nilsson Exp $
+ || $Id: builtin_functions.c,v 1.525 2004/01/30 16:17:57 grubba Exp $
*/
#include "global.h"
- RCSID("$Id: builtin_functions.c,v 1.524 2004/01/11 01:16:08 nilsson Exp $");
+ RCSID("$Id: builtin_functions.c,v 1.525 2004/01/30 16:17:57 grubba Exp $");
#include "interpret.h"
#include "svalue.h"
#include "pike_macros.h"
4369:
}
#endif
+ #ifdef HAVE_GMTIME
+ /* Returns the approximate difference in seconds between the
+ * two struct tm's.
+ *
+ * NOTE: No checks for out of range are performed.
+ */
+ static time_t my_tm_diff(const struct tm *t1, const struct tm *t2)
+ {
+ return (t1->tm_year - t2->tm_year) * 31557600 +
+ (t1->tm_mon - t2->tm_mon) * 2629800 +
+ (t1->tm_mday - t2->tm_mday) * 86400 +
+ (t1->tm_hour - t2->tm_hour) * 3600 +
+ (t1->tm_min - t2->tm_min) * 60 +
+ (t1->tm_sec - t2->tm_sec);
+ }
+
+ /* Inverse operation of gmtime().
+ */
+ static time_t my_timegm(struct tm *target_tm)
+ {
+ time_t current_ts = 0;
+ time_t diff_ts;
+ struct tm *current_tm;
+ int loop_cnt = 0;
+
+ /* Assume dst is one hour. */
+ target_tm->tm_hour -= target_tm->tm_isdst;
+
+ /* This loop seems stable, and usually converges in two passes.
+ * The loop counter is for paranoia reasons.
+ */
+ while((diff_ts = my_tm_diff(target_tm, current_tm = gmtime(¤t_ts)))) {
+ current_ts += diff_ts;
+ loop_cnt++;
+ if (loop_cnt > 20) {
+ /* Infinite loop? */
+ return -1;
+ }
+ }
+ /* Check that the result tm looks like what we expect... */
+ if ((current_tm->tm_sec == target_tm->tm_sec) &&
+ (current_tm->tm_min == target_tm->tm_min)) {
+ /* Odds are that the rest of the fields are correct (1:3600). */
+ return current_ts;
+ }
+ return -1;
+ }
+ #endif /* HAVE_GMTIME */
+
#ifdef HAVE_MKTIME
/*! @decl int mktime(mapping(string:int) tm)
*! @decl int mktime(int sec, int min, int hour, int mday, int mon, int year, @
4470: Inside #if defined(HAVE_MKTIME)
date.tm_isdst = -1;
}
+ date.tm_zone = NULL;
+
+ #ifdef HAVE_GMTIME
+ if((args > 7) && (Pike_sp[7-args].subtype == NUMBER_NUMBER))
+ {
+ /* UTC-relative time. Use my_timegm(). */
+ retval = my_timegm(&date);
+ if (retval == -1)
+ PIKE_ERROR("mktime", "Cannot convert.\n", Pike_sp, args);
+ retval += Pike_sp[7-args].u.integer;
+ } else {
+ #endif /* HAVE_GMTIME */
+
#ifdef STRUCT_TM_HAS_GMTOFF
/* BSD-style */
date.tm_gmtoff = 0;
4524:
retval += 3600 * (Pike_sp[6-args].u.integer - date.tm_isdst);
}
#endif /* STRUCT_TM_HAS_GMTOFF || STRUCT_TM_HAS___TM_GMTOFF */
+ #ifdef HAVE_GMTIME
+ }
+ #endif /* HAVE_GMTIME */
pop_n_elems(args);
push_int(retval);
8304: Inside #if defined(HAVE_MKTIME)
/* function(int,int,int,int,int,int,int,void|int:int)|function(object|mapping:int) */
ADD_EFUN("mktime",f_mktime,
- tOr(tFunc(tInt tInt tInt tInt tInt tInt tInt tOr(tVoid,tInt),tInt),
+ tOr(tFunc(tInt tInt tInt tInt tInt tInt
+ tOr(tVoid,tInt) tOr(tVoid,tInt),tInt),
tFunc(tOr(tObj,tMapping),tInt)),OPT_TRY_OPTIMIZE);
#endif