# Bug - Date Library

**URL:** <https://swi-prolog.discourse.group/t/bug-date-library/5118>\
**Category:** Help!\
**Tags:** bug\
**Created:** [March 14, 2022, 8:47am UTC](https://swi-prolog.discourse.group/t/bug-date-library/5118 "2022-03-14T08:47:09Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![watson](https://avatars.discourse-cdn.com/v4/letter/w/ce73a5/32.png) [@watson](https://swi-prolog.discourse.group/u/watson)\
**Post date:** [March 14, 2022, 8:47am UTC](https://swi-prolog.discourse.group/t/bug-date-library/5118/1 "2022-03-14T08:47:09Z")

</div>

Hi, I believe I have found a bug in the `date` library. The full code is provided on the StackOverflow link below. But I think the bug exists somewhere in here:

```prolog
    DateTime1 = date(Y1, M1, D1, H1, Mn1, S1, _, _, _),
    S2 is S1 + X,
    date_time_stamp(date(Y1, M1, D1, H1, Mn1, S2, _, _, _), Stamp2),

```

When attempting to increment the seconds value `S1` by a value `X` large enough that the `Mn1` value needs to be incremented by `1`, the `Mn1` value will instead be incremented by `2`. E.g. a `Mn1` value of `22`, `S` value of `59` and `X` value of `1`, the `Mn1` value should increment to `23` but it instead increments to `24`. When attempting the same logic with Minutes and Hours instead, it works.

> <https://stackoverflow.com/questions/71429450/incrementing-datetime-by-second>

---

<div class="post-metadata">

**Author:** ![brebs](https://avatars.discourse-cdn.com/v4/letter/b/e9c0ed/32.png) [@brebs](https://swi-prolog.discourse.group/u/brebs)\
**Post date:** [March 14, 2022, 1:29pm UTC](https://swi-prolog.discourse.group/t/bug-date-library/5118/2 "2022-03-14T13:29:30Z")

</div>

Here is the major mistake:

```prolog
S2 is S1 + X

```

The number of seconds (including milliseconds as the fraction) in a valid time must be \>= 0 and \< 60.

Example of _safe_ datetime arithmetic (also showing the imperfection of floating-point arithmetic):

```prolog
?- D = datetime(2021, 12, 31, 23, 59, 59.9), datetime_add(D, 2 secs, D2).
D = datetime(2021,12,31,23,59,59.9),
D2 = datetime(2022,1,1,0,0,1.8999999999999986).

```

---

<div class="post-metadata">

**Author:** ![watson](https://avatars.discourse-cdn.com/v4/letter/w/ce73a5/32.png) [@watson](https://swi-prolog.discourse.group/u/watson)\
**Post date:** [March 14, 2022, 1:50pm UTC](https://swi-prolog.discourse.group/t/bug-date-library/5118/3 "2022-03-14T13:50:04Z")

</div>

I don’t think there is any issue with `S2 is S1 + X`. Using the documentation [timedate documentation](https://www.swi-prolog.org/pldoc/man?section=timedate) under `date_time_stamp` it explains that going beyond `0` to `59` is allowed.

```prolog
This example computes the date 200 days after 2006-07-14:
?- date_time_stamp(date(2006,7,214,0,0,0,0,-,-), Stamp),
   stamp_date_time(Stamp, D, 0),
   date_time_value(date, D, Date).
Date = date(2007, 1, 30)

```

This example is with increasing the day value past 31, it also works for minutes when going over 59 as shown on StackOverflow but it breaks for seconds.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [March 14, 2022, 2:02pm UTC](https://swi-prolog.discourse.group/t/bug-date-library/5118/4 "2022-03-14T14:02:25Z")

</div>

Not sure why, but it works fine if you actually pass on the timezone info:

```prolog
:- use_module(library(date)).

get_dt(Datestring, Y, M, D, H, Mn, S, X) :-
    parse_time(Datestring, Stamp1),
    stamp_date_time(Stamp1, DateTime1, 'UTC'),
    DateTime1 = date(Y1, M1, D1, H1, Mn1, S1, Off, TZ, DST),
    S2 is S1 + X,
    date_time_stamp(date(Y1, M1, D1, H1, Mn1, S2, Off, TZ, DST), Stamp2),
    stamp_date_time(Stamp2, DateTime2, 'UTC'),
    DateTime2 = date(Y, M, D, H, Mn, S, _, _, _).

```

```prolog
?- get_dt('2020-03-04 06:22:59.012315131', Y, M, D, H, Mn, S, 1).
Y = 2020,
M = 3,
D = 4,
H = 6,
Mn = 23,
S = 0.012315034.

```

Surely passing on is a good idea. I’m afraid I do not have time right now to figure out what exactly is supposed to happen if you pass variables.

Surely if you want to compute second offsets, doing so based on the time stamp is a lot easier. The non-normalized values for the time stamp are useful if you want to change a date by a month or a year as these do not have a defined number of seconds.

---

<div class="post-metadata">

**Author:** ![watson](https://avatars.discourse-cdn.com/v4/letter/w/ce73a5/32.png) [@watson](https://swi-prolog.discourse.group/u/watson)\
**Post date:** [March 14, 2022, 2:08pm UTC](https://swi-prolog.discourse.group/t/bug-date-library/5118/5 "2022-03-14T14:08:32Z")

</div>

Great find thanks, could you post on StackOverflow and I can close the question if possible?

---

<div class="post-metadata">

**Author:** ![jeshan](https://avatars.discourse-cdn.com/v4/letter/j/4da419/32.png) [@jeshan](https://swi-prolog.discourse.group/u/jeshan)\
**Post date:** [March 16, 2022, 5:30am UTC](https://swi-prolog.discourse.group/t/bug-date-library/5118/6 "2022-03-16T05:30:13Z")

</div>

in case he can’t, feel free to answer it yourself. it’s allowed on SO.
