通过迭代从 UNIX 时间计算日期 - 逻辑缺陷?

Posted

技术标签:

【中文标题】通过迭代从 UNIX 时间计算日期 - 逻辑缺陷?【英文标题】:Calculating Date from UNIX Time via Iteration - Logic Flaw? 【发布时间】:2021-10-10 23:37:40 【问题描述】:

我正在尝试创建一个函数,该函数在给定自纪元以来的秒数的情况下以字符串格式 (MM-DD-YYYY) 返回日期。我相信我的函数中的逻辑是合理的,我在这里发帖是因为可能有一些关于 UNIX 时间的东西我不明白。我正在寻找任何可以阐明我的盲点在哪里的人。我相信我的逻辑和思维过程是正确的,但显然不是。希望有人可以帮助清理它,这可能对其他新手有所帮助。

我的函数被传递了一个参数,秒(int),即自纪元以来的秒数。然后我必须返回一个字符串'MM-DD-YYYY'。小时、分钟、秒和时区无关紧要。我正在使用 Python,因此 int 大小和 2038 问题也不重要。我的函数迭代地计算日期。我基本上一直在递减 seconds 参数多年,然后是几个月,然后是几天,以跟踪已经过去的时间。一旦我无法再在这三个领域(年 -> 月 -> 天)中的每一个进行迭代,我就找到了我的日期。除了我发现的日期不正确。

年数计算

我采用 seconds 参数,并按给定年份的秒数递减,除非递减导致负数。我跟踪增加的年份,因为我递减。如果年份是闰年,我会递减 86400 * 366。对于普通年份,86400 * 365。我会在每次迭代的 year 跟踪器中添加 +1。

月数计算

seconds 参数现在包含剩余的秒数,小于一年的长度。我会减少每个月的秒数,除非减少导致负数。一月 = 86400 * 31,二月是 28 天还是 29 天,具体取决于是否是闰年,依此类推。

天数计算

秒参数现在包含小于一个月的秒数。我遵循相同的过程,递减 86400(并跟踪天数),直到我不能再递减秒数。

逻辑缺陷?

根据我对 UNIX 时间的了解,我应该使用这种方法得出正确的 MM-DD-YYYY 日期。但是,我的函数还差 2 天。

输入:9876543210

输出:'12-20-2282'

预期:'12-22-2282'

功能假设

输入总是一个正整数

我不需要进行时区转换或计算。假定为 GMT。

代码

def date_from_epoch_seconds(seconds: int) -> str:
    """
    Returns a date in string format ('MM-DD-YYYY') given param:seconds since epoch
    :param: seconds: int, number of seconds since epoch
    :return: string: date 'MM-DD-YYY'
    """

    # variables
    DAYS_IN_COMMON_MONTH = 1: 31, \
                            2: 28, \
                            3: 31, \
                            4: 30, \
                            5: 31, \
                            6: 30, \
                            7: 31, \
                            8: 31, \
                            9: 30, \
                            10: 31, \
                            11: 30, \
                            12: 31
    DAY = 86400
    year = 1970
    month = 1
    day = 1

    # calculate year
    while True:

        # get the number of seconds in this year
        if year % 4 != 0:
            add_year = DAY * 365
        else:
            add_year = DAY * 366

        # exit criteria
        if seconds - add_year < 0:
            break

        # add a year
        seconds -= add_year
        year += 1

    print(f"Year calculated: year")

    # calculate month
    while True:

        # get the number of seconds in this month
        if month == 2 and year % 4 == 0:
            add_month = DAY * 29
        else:
            add_month = DAY * DAYS_IN_COMMON_MONTH[month]

        # exit criteria
        if seconds - add_month < 0:
            break

        seconds -= add_month
        month += 1

    print(f"months calculated = month")

    # calculate day
    while True:
        if seconds - DAY < 0:
            break
        seconds -= DAY
        day += 1

    print(f"day calculated = day")
    print()
    return str(twoDigitInt(month)) + "-" + \
           str(twoDigitInt(day)) + "-" + \
           str(year)

【问题讨论】:

【参考方案1】:

您的闰年计算错误。 2100 年和 2200 年不是闰年。能被 100 整除的年份不是闰年,除非它们也能被 400 整除。

【讨论】:

我们很幸运,2000 可以被 400 整除。 谢谢。我已经阅读了很多关于 UNIX 时间的页面,但没有一篇提到过。

以上是关于通过迭代从 UNIX 时间计算日期 - 逻辑缺陷?的主要内容,如果未能解决你的问题,请参考以下文章

Php Laravel 日期数组循环逻辑

熊猫日期时间到 unix 时间戳秒

根据日期计算嵌套循环中的帖子

在 MS Access SQL 查询中从普通日期转换为 unix 纪元日期

将 UNIX 纪元转换为日期对象

SQL 问题 - 如何在 SQL Server 中使用迭代日期逻辑进行输出