gpt4 book ai didi

python - 为任何架构获得尽可能高的 gmtime

转载 作者:行者123 更新时间:2023-11-28 21:50:20 34 4
gpt4 key购买 nike

我有一个开始的问题 here .我发现了原因并且没有尝试解决其他问题。

我需要将 CherryPy 设置为在不同平台上可用的最长可能 session 时间。为此 CherryPy 使用 time.gmtime()。在我的 Windows 64 位上,我可以毫无问题地将 session 超时设置为 future 100 年,但这在 armhf 平台上不起作用。 armhf 允许我将 session 设置为 22 年。

不是 我正在寻找一种根据体系结构动态设置超时的方法。

在 armhf 上,我尝试使用 time.gmtime(sys.maxsize) 返回 2038 年的日期。time.gmtime(sys.maxsize+1)返回一个 OverflowError: timestamp out of range for platform time_t 错误。所以我想这是可能的最晚日期。

问题是在我的 64 位 Windows 机器上执行相同操作(其中 sys.maxsize = 9223372036854775807)time.gmtime(sys.maxsize) 返回 OSError:[Errno 22] 无效参数。有没有办法跨任何架构/平台执行此操作?

编辑:这个问题不仅是由我在 CherryPy 中的代码引起的,其中 session 的超时值对于某些平台/架构(主要是 arm)来说太高了,但在其中一些平台/架构(Arm7)上它也是由 CherryPy 内部引起的。

最佳答案

time.gmtime() 接受一个 float ,因此它的输入受限于 sys.float_info.maxint in the range of C long (or long long if available) .

要找到“可能的最高日期”,我们可以使用二进制搜索,如 @BlackJack's answer :

#!/usr/bin/env python
import ctypes
import sys
import time

MAX_TIME = max(int(sys.float_info.max),
2**(8*ctypes.sizeof(getattr(ctypes, 'c_longlong', ctypes.c_long))))
BOUNDARY = 0.5
assert False < BOUNDARY < True # necessary for the binary search to work

class GmtimeOverflowTable:
def __getitem__(self, timestamp):
assert timestamp >= 0
try:
time.gmtime(timestamp)
except (OSError, OverflowError, ValueError): # ValueError for Python <3.3
return True # overflow
return False

def find_max_gmtime_timestamp():
overflow = GmtimeOverflowTable()
assert overflow[float('+inf')] and not overflow[0]
if overflow[MAX_TIME]:
ts = binary_search(overflow, BOUNDARY, 0, MAX_TIME)
assert overflow[ts] and not overflow[ts - 1]
return ts - 1
raise OverflowError("Max gmtime timestamp is larger than " + str(MAX_TIME))

print(find_max_gmtime_timestamp())

其中 binary_search() 是一个自定义函数,用于接受 bisect.bisect() 范围之外的输入:

def binary_search(haystack, needle, lo, hi): # avoid bisect() range limitation
while lo < hi:
mid = (lo + hi) // 2
if haystack[mid] > needle:
hi = mid
elif haystack[mid] < needle:
lo = mid + 1
else:
return mid
return hi

我机器上的结果:

| Python version       | max gmtime timestamp |
|----------------------+----------------------|
| Python 2.7.9 | 67768036191676795 |
| Python 3.4.3 | 67768036191676799 |
| Pypy (Python 2.7.9) | 67768036191676795 |
| Pypy3 (Python 3.2) | 67768036191676795 |
| Jython 2.7.0 | 9223372036854777 |

67768036191676799 Python 3 最大gmtime()时间戳对应最大32位int年:

>>> import time; time.gmtime(67768036191676799)                                    
time.struct_time(tm_year=2147485547, tm_mon=12, tm_mday=31, tm_hour=23, tm_min=59, tm_sec=59, tm_wday=2, tm_yday=365, tm_isdst=0)
>>> 2147485547-1900
2147483647
>>> 2**31-1
2147483647

In general, Python time.gmtime() delegates to the platform C gmtime() function :

Most of the functions defined in this module call platform C library functions with the same name. It may sometimes be helpful to consult the platform documentation, because the semantics of these functions varies among platforms.

The corresponding function signature in C11 :

struct tm *gmtime(const time_t *timer);

time_t limits are implementation-defined in C :

The range and precision of times representable in clock_t and time_t are implementation-defined.

time_t is required to be a real type on c11 :

real types
integer types
char
sίgned integer types
standard sίgned integer types
signed char, short int, int, long int, long long int
extended sίgned integer types
unsίgned integer types
standard unsίgned integer types
_Bool, unsigned char, unsigned short int, unsigned int,
unsigned long int, unsigned long long int
extended unsίgned integer types
enumeration types
real floating types
float, double, long double

也就是说,原则上 time_t 可以是扩展整数类型或例如 long double。

time_t is an integer type on POSIX

max time_t 可能大于 sys.maxsize 例如,time_t 在 32 位系统上可能是 64 位类型。

另见:


可以在不知道time_t 限制的情况下找到最大gmtime() 时间戳:

def find_max_gmtime_timestamp():
ts = 1
overflow = GmtimeOverflowTable()
assert overflow[float('+inf')] and not overflow[ts]
while not overflow[ts]:
ts *= 2
ts = binary_search(overflow, BOUNDARY, ts//2, ts)
max_ts = ts - 1
assert overflow[max_ts+1] and not overflow[max_ts]
return max_ts

结果是一样的。

如果 TZ=right/UTC 那么结果是 67768036191676825 对应于相同的最大时间 2147485547-12-31 23:59:59 UTCright/UTC 时间戳更大,因为它包括闰秒(26 as of 2015-07-01)。

关于python - 为任何架构获得尽可能高的 gmtime,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32045725/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com