Skip to content

Commit

Permalink
FIXED: Windows format_time/3 implementation for time stamps > 32 bits.
Browse files Browse the repository at this point in the history
While the Windows `time_t` is 64 bits, it doesn't seem to localtime()
seems broken handling large time offsets.
  • Loading branch information
JanWielemaker committed Sep 30, 2024
1 parent 91ad94b commit d4b8911
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 5 deletions.
6 changes: 5 additions & 1 deletion src/Tests/library/test_date.pl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Author: Jan Wielemaker
E-mail: [email protected]
WWW: www.swi-prolog.org
Copyright (c) 2006-2021, University of Amsterdam
Copyright (c) 2006-2024, University of Amsterdam
VU University Amsterdam
SWI-Prolog Solutions b.v.
All rights reserved.
Expand Down Expand Up @@ -225,6 +225,10 @@
parse_time('2006-W49-5', iso_8601, T).
test(iso_8601, T =:= 1165536000) :-
parse_time('2006-342', iso_8601, T).
test(iso_8601, S == '1732-02-22') :-
parse_time('1732-02-22', iso_8601, Stamp),
assertion(Stamp =:= -7506086400),
format_time(atom(S), '%Y-%m-%d', Stamp).

:- end_tests(parse_time).

Expand Down
15 changes: 11 additions & 4 deletions src/os/pl-tai.c
Original file line number Diff line number Diff line change
Expand Up @@ -983,14 +983,20 @@ format_time(+Spec, +Format, +Stamp)
* Sub-second times
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

#ifdef __WINDOWS__
typedef int32_t stime_t;
#else
typedef time_t stime_t;
#endif

static foreign_t
pl_format_time(term_t out, term_t format, term_t time, int posix)
{ struct taia taia;
struct caltime ct;
struct ftm tb;
int weekday, yearday;
wchar_t *fmt;
time_t unixt;
stime_t unixt;
int64_t ut64;
size_t fmtlen;
redir_context ctx;
Expand All @@ -1006,11 +1012,12 @@ pl_format_time(term_t out, term_t format, term_t time, int posix)

leapsecs_sub(&tai);
ut64 = tai.x - TAI_UTC_OFFSET;
unixt = (time_t) ut64;
unixt = (stime_t) ut64;

if ( (int64_t)unixt == ut64 )
{ tb.utcoff = tz_offset();
PL_localtime_r(&unixt, &tb.tm);
{ time_t ta = unixt;
tb.utcoff = tz_offset();
PL_localtime_r(&ta, &tb.tm);
tb.sec = (double)tb.tm.tm_sec + modf(tb.stamp, &ip);
if ( tb.tm.tm_isdst > 0 )
{ tb.utcoff -= 3600;
Expand Down

0 comments on commit d4b8911

Please sign in to comment.