【问题标题】:Python difference between partially known dates部分已知日期之间的Python差异
【发布时间】:2021-07-04 17:48:25
【问题描述】:

我正在尝试计算当前日期与给定(部分已知)日期之间的差异。例如:下面列出了有效的日期格式 (YYYY-MM-DD)。

YYYY-MM-DD
YYYY-MM-??
YYYY-??-??
????-??-??

例如,对于当天 (2021-07-04),结果将是

2021-12-02 -> 0 years, 5 months, however many days.
2022-06-?? -> 1 year, however many months
2077-??-?? -> ~56 Years
????-??-?? -> Unknown

所以基本上,当有 ?? 时,该部分被忽略,我们只检查日期的下一个较高部分,例如如果这一天标有 ??我们只看年份和月份等。

到目前为止,这是我汇总的内容:

@staticmethod
def calculate_time_left(release_date):
    # Only year is known:
    if re.match("([0-9]{4})-\?\?-\?\?", release_date):
        release_year = int(re.search("([0-9]{4})-\?\?-\?\?", release_date).group(1))
        current_year = int(datetime.datetime.now().year)
        if release_year == current_year:
            return "This year."
        else:
            return "~{} year(s).".format(release_year - current_year)
    elif re.match("([0-9]{4})-([0-9]{2})-\?\?", release_date):
        release_year = int(re.search("([0-9]{4})-([0-9]{2})-\?\?", release_date).group(1))
        current_year = int(datetime.datetime.now().year)
        release_month = int(re.search("([0-9]{4})-([0-9]{2})-\?\?", release_date).group(2))
        current_month = int(datetime.datetime.now().month)
        if release_year == current_year:
            if release_month == current_month:
                return "This month"
            else:
                return "~{} months".format(release_month - current_month)
        else:
            return "{} year(s) and {} months.".format(release_year - current_year, release_month - current_month)
    elif re.match("([0-9]{4})-([0-9]{2})-([0-9]{2})", release_date):
        release_year = int(re.search("([0-9]{4})-([0-9]{2})-([0-9]{2})", release_date).group(1))
        current_year = int(datetime.datetime.now().year)
        release_month = int(re.search("([0-9]{4})-([0-9]{2})-([0-9]{2})", release_date).group(2))
        current_month = int(datetime.datetime.now().month)
        release_day = int(re.search("([0-9]{4})-([0-9]{2})-([0-9]{2})", release_date).group(3))
        current_day = int(datetime.datetime.now().day)
        if release_year == current_year:
            if release_month == current_month:
                if release_day == current_day:
                    return "Today."
                else:
                    return "{} days.".format(release_day - current_day)
            else:
                if release_day == current_day:
                    "~{} months.".format(release_month - current_month)
                else:
                    return "~{} months and {} days.".format(release_month - current_month, release_day - current_day)
        else:
            if release_month == current_month:
                if release_day == current_day:
                    return "{} year(s).".format(release_year - current_year)
            else:
                if release_day == current_day:
                    return "{} year(s) and {} months.".format(release_year - current_year, release_month - current_month)
                else:
                    return "{} year(s), {} months and {} days.".format(release_year - current_year, release_month - current_month, release_day - current_day)

    return "Release date unknown."

我在这里遇到了几个问题:

  1. 我得到了月份和日期差异的负值。例如2022-01-02 将返回1 year(s), -6 months and -2 days
  2. 我觉得我不需要为每种情况都进行所有这些正则表达式匹配。可能有更好的方法来做到这一点。

我该如何正确解决这个问题?我觉得我的方法很差,而且容易出错。

【问题讨论】:

    标签: python regex date datetime substring


    【解决方案1】:

    对于负值,你可以使用绝对值函数来去除负值。我仍在查看您的代码,试图弄清楚您要完成的工作。这只是为了练习吗?此外,由于您没有将脚本用作任何实际目的的实际日期,因此只需将日期 (yyyy) (mm) (dd) 的每个部分视为常规整数。不,我认为你不需要正则表达式来解决这个问题,但你知道一点正则表达式是件好事。将数字视为整数,并根据您想要显示输出的方式对其进行格式化。我自己还在学python,就我的两分钱。

    【讨论】:

    • 我计划在某个时候在一个更大的项目中使用它,但我想首先开发这个算法隔离,以确保它正常工作。我知道可以使用 python 内置函数计算日期的差异,但由于我们在这里处理的是特定格式,所以它有点棘手。本质上,我只是想弄清楚,鉴于上述格式,该日期暂时离开了多少年、几个月或几天。并且输出应该只显示已知的部分,例如如果日期是 YYYY-MM-??,则只打印日期之前的年份和月份。希望这是有道理的:D
    【解决方案2】:

    我不确定你的整体算法应该返回什么,但这里有一种评估日期部分的方法:

    for date_string in ['2021-12-02', '2022-06-??', '2077-??-??', '????-??-??']:
        year, month, day = date_string.split('-')
    
        year_delta = month_delta = day_delta = 'unknown'
        if year.count('?') == 0:  # if there are no ? in the year string
            year_delta = int(year) - datetime.now().year
        if month.count('?') == 0:
            month_delta = int(month) - datetime.now().month
        if day.count('?') == 0:
            day_delta = int(day) - datetime.now().day
    
    

    【讨论】:

    • 我也不认为这完全正确。算法的返回值并不那么重要,我只想计算到给定(部分)日期的剩余时间。但例如2022-01-02 使用您的算法产生的月份为负数。不仅如此,年数也不正确。它返回 1 年,-6 个月和 -13 天。我认为答案应该是 0 年 5 个月 17 天(?)。我试着在脑海中粗略计算一下,但你明白了。
    • 你是对的,你肯定可以得到负值。例如,如果您比较 8 月和 2 月,那么第 8 个月与第 2 个月,您可以得到 -6 作为月份增量。因此,如果您正在尝试这样做,那么您会想要减少年份增量。天数与月数的类似问题 - 如果为负数,则将月增量减 1,例如,8 月 2 日与 2 月 16 日的间隔不是整整 6 个月,因此您可以将其称为 5,并可以计算该月的天数等。
    • 您介意在您的原始帖子中编辑此内容吗?如果增量取决于天数,则不完全确定如何计算正确的月份。
    猜你喜欢
    • 1970-01-01
    • 2011-02-01
    • 2012-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-19
    • 2014-12-18
    相关资源
    最近更新 更多