Skip to content

Commit

Permalink
New datetime_timestamp_floating_point_behavior.py with output.
Browse files Browse the repository at this point in the history
  • Loading branch information
Ralf W. Grosse-Kunstleve committed Apr 29, 2023
1 parent ad67881 commit f688c13
Show file tree
Hide file tree
Showing 2 changed files with 256 additions and 0 deletions.
86 changes: 86 additions & 0 deletions python_datetime/datetime_timestamp_floating_point_behavior.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
"""Show datetime.datetime.timestamp() floating-point behavior.
Please review the output of this code first, then look back here.
* https://docs.python.org/3/library/datetime.html
* https://en.wikipedia.org/wiki/IEEE_754
"""

import datetime
import sys


def annotate_behavior(t_int, t_flt):
if int(t_flt) == t_int:
return "truncating"
if int(t_flt) == t_int + 1:
return "ROUNDING UP"
return "LOSSY"


def dt_strftime(dt):
return ("000" + dt.strftime("%Y-%m-%d %H:%M:%S.%f"))[-26:]


def run(args):
"""Please review the output of this code first, then look back here."""

assert len(args) == 1, "sample_max_exponent (e.g. 53 for IEEE 754)"

sample_max_exponent = int(args[0])

resolution_exponent = 6
resolution_num = 10**resolution_exponent # 1000000
resolution_nines = resolution_num - 1 # 999999
resolution_nines_over_num = resolution_nines / resolution_num # 0.999999

tz_utc = datetime.timezone.utc
dt_min = datetime.datetime.min.replace(tzinfo=tz_utc)
dt_max = datetime.datetime.max.replace(tzinfo=tz_utc)
dt_min_t = dt_min.timestamp()
dt_max_t = dt_max.timestamp()

print("datetime.min.timestamp()", dt_min_t, "", dt_strftime(dt_min))
print("datetime.max.timestamp()", dt_max_t, "", dt_strftime(dt_max))
print()

print(" offset t_int t_int+0.999999")

def print_mm(name, t, offset):
t_int = int(t) + offset
t_flt = t_int + resolution_nines_over_num
print(
f"{name} {offset:6} {t_int:13} {t_flt:15}"
f" {annotate_behavior(t_int, t_flt)}"
)

for offset in (0, 1):
print_mm("datetime.min", dt_min_t, offset)
for offset in (-1, 0):
print_mm("datetime.max", dt_max_t, offset)
print()

print("2**e offset t_int t_int+0.999999")
t_int_done = set()
for exponent in range(sample_max_exponent + 1):
ip2 = 2**exponent
for offset in (-1, 0, 1):
t_int = ip2 + offset
if t_int in t_int_done:
continue
t_int_done.add(t_int)
t_flt = t_int + resolution_nines_over_num
if t_flt < dt_max_t:
dt_utc = datetime.datetime.fromtimestamp(t_int, tz=tz_utc)
dt_fmt = dt_strftime(dt_utc)
else:
dt_fmt = "out of datetime range"
print(
f"{exponent:4} {offset:6} {t_int:16} {t_flt:20}"
f" {annotate_behavior(t_int, t_flt):11} {dt_fmt}"
)
print()


if __name__ == "__main__":
run(args=sys.argv[1:])
170 changes: 170 additions & 0 deletions python_datetime/datetime_timestamp_floating_point_behavior_output.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
datetime.min.timestamp() -62135596800.0 0001-01-01 00:00:00.000000
datetime.max.timestamp() 253402300800.0 9999-12-31 23:59:59.999999

offset t_int t_int+0.999999
datetime.min 0 -62135596800 -62135596799.0 ROUNDING UP
datetime.min 1 -62135596799 -62135596798.0 ROUNDING UP
datetime.max -1 253402300799 253402300800.0 ROUNDING UP
datetime.max 0 253402300800 253402300801.0 ROUNDING UP

2**e offset t_int t_int+0.999999
0 -1 0 0.999999 truncating 1970-01-01 00:00:00.000000
0 0 1 1.9999989999999999 truncating 1970-01-01 00:00:01.000000
0 1 2 2.999999 truncating 1970-01-01 00:00:02.000000
1 1 3 3.999999 truncating 1970-01-01 00:00:03.000000
2 0 4 4.999999 truncating 1970-01-01 00:00:04.000000
2 1 5 5.999999 truncating 1970-01-01 00:00:05.000000
3 -1 7 7.999999 truncating 1970-01-01 00:00:07.000000
3 0 8 8.999999 truncating 1970-01-01 00:00:08.000000
3 1 9 9.999999 truncating 1970-01-01 00:00:09.000000
4 -1 15 15.999999 truncating 1970-01-01 00:00:15.000000
4 0 16 16.999999 truncating 1970-01-01 00:00:16.000000
4 1 17 17.999999 truncating 1970-01-01 00:00:17.000000
5 -1 31 31.999999 truncating 1970-01-01 00:00:31.000000
5 0 32 32.999999 truncating 1970-01-01 00:00:32.000000
5 1 33 33.999999 truncating 1970-01-01 00:00:33.000000
6 -1 63 63.999999 truncating 1970-01-01 00:01:03.000000
6 0 64 64.999999 truncating 1970-01-01 00:01:04.000000
6 1 65 65.999999 truncating 1970-01-01 00:01:05.000000
7 -1 127 127.999999 truncating 1970-01-01 00:02:07.000000
7 0 128 128.999999 truncating 1970-01-01 00:02:08.000000
7 1 129 129.999999 truncating 1970-01-01 00:02:09.000000
8 -1 255 255.999999 truncating 1970-01-01 00:04:15.000000
8 0 256 256.999999 truncating 1970-01-01 00:04:16.000000
8 1 257 257.999999 truncating 1970-01-01 00:04:17.000000
9 -1 511 511.999999 truncating 1970-01-01 00:08:31.000000
9 0 512 512.999999 truncating 1970-01-01 00:08:32.000000
9 1 513 513.999999 truncating 1970-01-01 00:08:33.000000
10 -1 1023 1023.999999 truncating 1970-01-01 00:17:03.000000
10 0 1024 1024.999999 truncating 1970-01-01 00:17:04.000000
10 1 1025 1025.999999 truncating 1970-01-01 00:17:05.000000
11 -1 2047 2047.999999 truncating 1970-01-01 00:34:07.000000
11 0 2048 2048.999999 truncating 1970-01-01 00:34:08.000000
11 1 2049 2049.999999 truncating 1970-01-01 00:34:09.000000
12 -1 4095 4095.999999 truncating 1970-01-01 01:08:15.000000
12 0 4096 4096.999999 truncating 1970-01-01 01:08:16.000000
12 1 4097 4097.999999 truncating 1970-01-01 01:08:17.000000
13 -1 8191 8191.999999 truncating 1970-01-01 02:16:31.000000
13 0 8192 8192.999999 truncating 1970-01-01 02:16:32.000000
13 1 8193 8193.999999 truncating 1970-01-01 02:16:33.000000
14 -1 16383 16383.999999 truncating 1970-01-01 04:33:03.000000
14 0 16384 16384.999999 truncating 1970-01-01 04:33:04.000000
14 1 16385 16385.999999 truncating 1970-01-01 04:33:05.000000
15 -1 32767 32767.999999 truncating 1970-01-01 09:06:07.000000
15 0 32768 32768.999999 truncating 1970-01-01 09:06:08.000000
15 1 32769 32769.999999 truncating 1970-01-01 09:06:09.000000
16 -1 65535 65535.999999 truncating 1970-01-01 18:12:15.000000
16 0 65536 65536.999999 truncating 1970-01-01 18:12:16.000000
16 1 65537 65537.999999 truncating 1970-01-01 18:12:17.000000
17 -1 131071 131071.999999 truncating 1970-01-02 12:24:31.000000
17 0 131072 131072.999999 truncating 1970-01-02 12:24:32.000000
17 1 131073 131073.999999 truncating 1970-01-02 12:24:33.000000
18 -1 262143 262143.999999 truncating 1970-01-04 00:49:03.000000
18 0 262144 262144.999999 truncating 1970-01-04 00:49:04.000000
18 1 262145 262145.999999 truncating 1970-01-04 00:49:05.000000
19 -1 524287 524287.999999 truncating 1970-01-07 01:38:07.000000
19 0 524288 524288.999999 truncating 1970-01-07 01:38:08.000000
19 1 524289 524289.999999 truncating 1970-01-07 01:38:09.000000
20 -1 1048575 1048575.999999 truncating 1970-01-13 03:16:15.000000
20 0 1048576 1048576.999999 truncating 1970-01-13 03:16:16.000000
20 1 1048577 1048577.999999 truncating 1970-01-13 03:16:17.000000
21 -1 2097151 2097151.999999 truncating 1970-01-25 06:32:31.000000
21 0 2097152 2097152.999999 truncating 1970-01-25 06:32:32.000000
21 1 2097153 2097153.999999 truncating 1970-01-25 06:32:33.000000
22 -1 4194303 4194303.999999 truncating 1970-02-18 13:05:03.000000
22 0 4194304 4194304.999999 truncating 1970-02-18 13:05:04.000000
22 1 4194305 4194305.999999 truncating 1970-02-18 13:05:05.000000
23 -1 8388607 8388607.999999 truncating 1970-04-08 02:10:07.000000
23 0 8388608 8388608.999999 truncating 1970-04-08 02:10:08.000000
23 1 8388609 8388609.999999 truncating 1970-04-08 02:10:09.000000
24 -1 16777215 16777215.999999 truncating 1970-07-14 04:20:15.000000
24 0 16777216 16777216.999999 truncating 1970-07-14 04:20:16.000000
24 1 16777217 16777217.999999 truncating 1970-07-14 04:20:17.000000
25 -1 33554431 33554431.999999 truncating 1971-01-24 08:40:31.000000
25 0 33554432 33554432.999999 truncating 1971-01-24 08:40:32.000000
25 1 33554433 33554433.999999 truncating 1971-01-24 08:40:33.000000
26 -1 67108863 67108863.999999 truncating 1972-02-16 17:21:03.000000
26 0 67108864 67108864.999999 truncating 1972-02-16 17:21:04.000000
26 1 67108865 67108865.999999 truncating 1972-02-16 17:21:05.000000
27 -1 134217727 134217727.999999 truncating 1974-04-03 10:42:07.000000
27 0 134217728 134217728.999999 truncating 1974-04-03 10:42:08.000000
27 1 134217729 134217729.999999 truncating 1974-04-03 10:42:09.000000
28 -1 268435455 268435455.999999 truncating 1978-07-04 21:24:15.000000
28 0 268435456 268435456.999999 truncating 1978-07-04 21:24:16.000000
28 1 268435457 268435457.999999 truncating 1978-07-04 21:24:17.000000
29 -1 536870911 536870911.999999 truncating 1987-01-05 18:48:31.000000
29 0 536870912 536870912.999999 truncating 1987-01-05 18:48:32.000000
29 1 536870913 536870913.999999 truncating 1987-01-05 18:48:33.000000
30 -1 1073741823 1073741823.999999 truncating 2004-01-10 13:37:03.000000
30 0 1073741824 1073741824.999999 truncating 2004-01-10 13:37:04.000000
30 1 1073741825 1073741825.999999 truncating 2004-01-10 13:37:05.000000
31 -1 2147483647 2147483647.999999 truncating 2038-01-19 03:14:07.000000
31 0 2147483648 2147483648.999999 truncating 2038-01-19 03:14:08.000000
31 1 2147483649 2147483649.999999 truncating 2038-01-19 03:14:09.000000
32 -1 4294967295 4294967295.999999 truncating 2106-02-07 06:28:15.000000
32 0 4294967296 4294967296.999999 truncating 2106-02-07 06:28:16.000000
32 1 4294967297 4294967297.999999 truncating 2106-02-07 06:28:17.000000
33 -1 8589934591 8589934591.999999 truncating 2242-03-16 12:56:31.000000
33 0 8589934592 8589934592.999998 truncating 2242-03-16 12:56:32.000000
33 1 8589934593 8589934593.999998 truncating 2242-03-16 12:56:33.000000
34 -1 17179869183 17179869183.999998 truncating 2514-05-30 01:53:03.000000
34 0 17179869184 17179869185.0 ROUNDING UP 2514-05-30 01:53:04.000000
34 1 17179869185 17179869186.0 ROUNDING UP 2514-05-30 01:53:05.000000
35 -1 34359738367 34359738368.0 ROUNDING UP 3058-10-26 03:46:07.000000
35 0 34359738368 34359738369.0 ROUNDING UP 3058-10-26 03:46:08.000000
35 1 34359738369 34359738370.0 ROUNDING UP 3058-10-26 03:46:09.000000
36 -1 68719476735 68719476736.0 ROUNDING UP 4147-08-20 07:32:15.000000
36 0 68719476736 68719476737.0 ROUNDING UP 4147-08-20 07:32:16.000000
36 1 68719476737 68719476738.0 ROUNDING UP 4147-08-20 07:32:17.000000
37 -1 137438953471 137438953472.0 ROUNDING UP 6325-04-08 15:04:31.000000
37 0 137438953472 137438953473.0 ROUNDING UP 6325-04-08 15:04:32.000000
37 1 137438953473 137438953474.0 ROUNDING UP 6325-04-08 15:04:33.000000
38 -1 274877906943 274877906944.0 ROUNDING UP out of datetime range
38 0 274877906944 274877906945.0 ROUNDING UP out of datetime range
38 1 274877906945 274877906946.0 ROUNDING UP out of datetime range
39 -1 549755813887 549755813888.0 ROUNDING UP out of datetime range
39 0 549755813888 549755813889.0 ROUNDING UP out of datetime range
39 1 549755813889 549755813890.0 ROUNDING UP out of datetime range
40 -1 1099511627775 1099511627776.0 ROUNDING UP out of datetime range
40 0 1099511627776 1099511627777.0 ROUNDING UP out of datetime range
40 1 1099511627777 1099511627778.0 ROUNDING UP out of datetime range
41 -1 2199023255551 2199023255552.0 ROUNDING UP out of datetime range
41 0 2199023255552 2199023255553.0 ROUNDING UP out of datetime range
41 1 2199023255553 2199023255554.0 ROUNDING UP out of datetime range
42 -1 4398046511103 4398046511104.0 ROUNDING UP out of datetime range
42 0 4398046511104 4398046511105.0 ROUNDING UP out of datetime range
42 1 4398046511105 4398046511106.0 ROUNDING UP out of datetime range
43 -1 8796093022207 8796093022208.0 ROUNDING UP out of datetime range
43 0 8796093022208 8796093022209.0 ROUNDING UP out of datetime range
43 1 8796093022209 8796093022210.0 ROUNDING UP out of datetime range
44 -1 17592186044415 17592186044416.0 ROUNDING UP out of datetime range
44 0 17592186044416 17592186044417.0 ROUNDING UP out of datetime range
44 1 17592186044417 17592186044418.0 ROUNDING UP out of datetime range
45 -1 35184372088831 35184372088832.0 ROUNDING UP out of datetime range
45 0 35184372088832 35184372088833.0 ROUNDING UP out of datetime range
45 1 35184372088833 35184372088834.0 ROUNDING UP out of datetime range
46 -1 70368744177663 70368744177664.0 ROUNDING UP out of datetime range
46 0 70368744177664 70368744177665.0 ROUNDING UP out of datetime range
46 1 70368744177665 70368744177666.0 ROUNDING UP out of datetime range
47 -1 140737488355327 140737488355328.0 ROUNDING UP out of datetime range
47 0 140737488355328 140737488355329.0 ROUNDING UP out of datetime range
47 1 140737488355329 140737488355330.0 ROUNDING UP out of datetime range
48 -1 281474976710655 281474976710656.0 ROUNDING UP out of datetime range
48 0 281474976710656 281474976710657.0 ROUNDING UP out of datetime range
48 1 281474976710657 281474976710658.0 ROUNDING UP out of datetime range
49 -1 562949953421311 562949953421312.0 ROUNDING UP out of datetime range
49 0 562949953421312 562949953421313.0 ROUNDING UP out of datetime range
49 1 562949953421313 562949953421314.0 ROUNDING UP out of datetime range
50 -1 1125899906842623 1125899906842624.0 ROUNDING UP out of datetime range
50 0 1125899906842624 1125899906842625.0 ROUNDING UP out of datetime range
50 1 1125899906842625 1125899906842626.0 ROUNDING UP out of datetime range
51 -1 2251799813685247 2251799813685248.0 ROUNDING UP out of datetime range
51 0 2251799813685248 2251799813685249.0 ROUNDING UP out of datetime range
51 1 2251799813685249 2251799813685250.0 ROUNDING UP out of datetime range
52 -1 4503599627370495 4503599627370496.0 ROUNDING UP out of datetime range
52 0 4503599627370496 4503599627370497.0 ROUNDING UP out of datetime range
52 1 4503599627370497 4503599627370498.0 ROUNDING UP out of datetime range
53 -1 9007199254740991 9007199254740992.0 ROUNDING UP out of datetime range
53 0 9007199254740992 9007199254740992.0 truncating out of datetime range
53 1 9007199254740993 9007199254740992.0 LOSSY out of datetime range

0 comments on commit f688c13

Please sign in to comment.