Python crash on Windows with a datetime close to the epoch

后端 未结 1 1821
无人共我
无人共我 2020-12-10 21:11

Python 3.7 on Windows 10:

>>> from datetime import datetime
>>> datetime.fromtimestamp(0)
datetime.d         


        
1条回答
  •  一整个雨季
    2020-12-10 22:03

    Ok I did some digging in the source code of the Python. The problem lies within the function _PyTime_localtime. This calls the localtime_s function takes 2 arguments time_t t and struct tm *tm. Where t is a time_t object to convert and tm the resulting time structure. When you pass 0 as time_t, which is perfectly valid, the resulting structure has the field tm_hour set to 1 on my machine. Also there is other code for Non-Windows variants, which calls localtime_r in stead.

    Now the problem gets moved to the internally used function utc_to_seconds, which takes the time structure (split into arguments like so: int year, int month, int day, int hour, int minute, int second). Now for the year, month and day there is no problem, it gets converted to an ordinal (which is the correct ordinal btw). But then the function has the following last line:

    return ((ordinal * 24 + hour) * 60 + minute) * 60 + second;
    

    Where EPOCH is supposed to return 62135683200 there, but due to this extra hour we get 62135686800.

    This all comes together in the internal function local_to_seconds

    long long t, a, b, u1, u2, t1, t2, lt;
    t = utc_to_seconds(year, month, day, hour, minute, second);
    /* Our goal is to solve t = local(u) for u. */
    lt = local(t);
    if (lt == -1)
        return -1;
    a = lt - t;
    u1 = t - a;
    t1 = local(u1);
    

    Where t = 62135683200 and lt = 62135686800. We end up with u1 = -3600 which results in the invalid parameter.

    So to conclude: The problem is when you call timestamp. I'm not exactly sure what the solution would be to fix it in the C-code, but it definitely looks like a bug I guess.

    0 讨论(0)
提交回复
热议问题