Python datetime 到十进制年份:休息一天,bug 在哪里?

Lau*_*ham 2 python datetime

datetime.datetime根据以前的答案实现了一个十进制年份(年份分数)转换器。我没有得到预期的结果,但我找不到错误。

from datetime import datetime, timedelta

def decimal_year_to_datetime(decimal_year_float):
    year = int(decimal_year_float)
    remain = decimal_year_float - year
    base = datetime(year, 1, 1)
    whole_year_time_delta = (base.replace(year=base.year + 1) - base)
    fractional_seconds = whole_year_time_delta.total_seconds() * remain
    our_time_delta = timedelta(seconds=fractional_seconds)
    result = base + our_time_delta
    return result

def test_conversion():
    year = 2013
    month = 1
    day = 1
    hour = 2
    minute = 16
    second = 48
    date = datetime(year=year, month=month, day=day)
    fraction_of_the_day = (hour + (minute + second / 60.0) / 60.0) / 24.
    days_in_year = (date.replace(year=date.year + 1) - date).days
    dec_yr = year + (date.timetuple().tm_yday + 
                     fraction_of_the_day) / float(days_in_year)

    expect_date = datetime(year=year, month=month, day=day, 
                              hour=hour, minute=minute, second=second)

    got_date = decimal_year_to_datetime(dec_yr)

    assert(got_date == expect_date)

if __name__ == '__main__':
    test_conversion()
Run Code Online (Sandbox Code Playgroud)

我的转换似乎有一天(零分之一秒)。但是我看不到错误。

我错过了一些明显的东西吗?

jon*_*rpe 6

你一天就出去了(一个典型的栅栏错误!)因为,虽然我们认为 1 月 1 日是一年中的第一天,但​​在计算方面这是第零天。最简单的解决方法是添加 a - 1,但您的方法通常看起来很复杂;我会这样做:

def dt_to_dec(dt):
    """Convert a datetime to decimal year."""
    year_start = datetime(dt.year, 1, 1)
    year_end = year_start.replace(year=dt.year+1)
    return dt.year + ((dt - year_start).total_seconds() /  # seconds so far
        float((year_end - year_start).total_seconds()))  # seconds in year
Run Code Online (Sandbox Code Playgroud)

正在使用:

>>> dec = dt_to_dec(datetime(2013, 1, 1, 2, 16, 48))
>>> dec
2013.0002602739726
>>> decimal_year_to_datetime(dec)
datetime.datetime(2013, 1, 1, 2, 16, 47, 999999)
Run Code Online (Sandbox Code Playgroud)

(考虑到浮点精度,这与您可能得到的一样接近......)

  • 在 Python 3 上,你可以把它写成 `dt.year + (dt - year_start) / (year_end - year_start)`。注意:[假设`dt`、`year_start`、`year_end` 日期都具有相同的UTC 偏移量。否则可能会引入错误](http://stackoverflow.com/questions/29851357/python-datetime-to-decimal-year-one-day-off-where-is-the-bug?lq=1#comment47838933_29851357) (2认同)