自学内容网 自学内容网

【蓝桥杯】43693.日期问题

题目描述

  小明正在整理一批历史文献。这些历史文献中出现了很多日期。小明知道这些日期都在 1960 年 1 月 1 日至 2059 年 12 月 31 日。令小明头疼的是,这些日期采用的格式非常不统一,有采用年/月/日的,有采用月/日/年的,还有采用日/月/年的。

  更加麻烦的是,年份也都省略了前两位,使得文献上的一个日期,存在很多可能的日期与其对应。比如 02/03/04,可能是 2002 年 03 月 04 日、2004 年 02 月 03 日或 2004 年 03 月 02 日。

  给出一个文献上的日期,你能帮助小明判断有哪些可能的日期对其对应吗?

输入描述

一个日期,格式是 “AA/BB/CC” (0≤A,B,C≤9)。

输出描述

  输出若干个不相同的日期,每个日期一行,格式是 “yyyy−MM−dd”。多个日期按从早到晚排列。

输入输出样例

示例

输入:

02/03/04

输出:

2002-03-04
2004-02-03
2004-03-02

题目分析

  比较简单,无非就是分情况讨论而已。第一种情况:"年 / 月 / 日"的格式;第二种情况:"月 / 日 / 年"的格式;第三种情况:"日 / 月 / 年"的格式;
  年份的区间在1960年至2059年,跨度100年,其中 y e a r year year >= 60的,是19开头的年份, y e a r year year < 60的,是20开头的年份;月份的区间在01月到12月;日期的区间在01日到31日。根据输入的字符串,做拆分之后,寻找可能的组合即可。
  但是有几个限制规则需要注意:

  1. 2月没有30日和31日,闰年可以有29日,不是闰年只有01-28日。
  2. 对于 4、6、9、11 月的天数不能超过 30 天。

代码实现

感谢 @练洋洋 同学提供的代码。不过在这个版本的代码中没有判断闰年和判断单双月最后一天的功能。

import os
import sys
import datetime

def is_valid_date(year, month, day):
    """
    此函数用于判断输入的年、月、日是否为有效的日期,并检查是否在 1960 年 1 月 1 日至 2059 年 12 月 31 日之间
    :param year: 年份
    :param month: 月份
    :param day: 日期
    :return: 若为有效日期且在指定范围内返回 True,否则返回 False
    """
    try:
        # 使用 datetime.date 类尝试创建日期对象
        date = datetime.date(year, month, day)
        # 检查日期是否在 1960 年 1 月 1 日至 2059 年 12 月 31 日之间
        if datetime.date(1960, 1, 1) <= date <= datetime.date(2059, 12, 31):
            return True
        else:
            return False
    # 若输入的年、月、日组合不合法会引发 ValueError 异常
    except ValueError:
        return False


# 从标准输入读取日期字符串,并使用 map 函数将其按 / 分割并转换为整数存储在 a, b, c 中
a, b, c = map(int, input().split('/'))
# 存储满足条件的日期元组列表
dates = []

# 假设日期格式为年/月/日
if 1 <= b <= 12 and 1 <= c <= 31:
    # 如果年份前两位大于等于 60,则年份是 19xx 年
    if a >= 60:
        # 调用 is_valid_date 函数判断日期是否有效
        if is_valid_date(1900 + a, b, c):
            dates.append((1900 + a, b, c))
    # 否则年份是 20xx 年
    else:
        if is_valid_date(2000 + a, b, c):
            dates.append((2000 + a, b, c))

# 假设日期格式为月/日/年
if 1 <= a <= 12 and 1 <= c <= 31:
    # 对年份的处理,根据 c 的大小判断是 19xx 年还是 20xx 年
    if c >= 60:
        if is_valid_date(1900 + c, a, b):
            dates.append((1900 + c, a, b))
    else:
        if is_valid_date(2000 + c, a, b):
            dates.append((2000 + c, a, b))

# 假设日期格式为日/月/年
if 1 <= a <= 31 and 1 <= b <= 12:
    # 对年份的处理,根据 c 的大小判断是 19xx 年还是 20xx 年
    if c >= 60:
        if is_valid_date(1900 + c, b, a):
            dates.append((1900 + c, b, a))
    else:
        if is_valid_date(2000 + c, b, a):
            dates.append((2000 + c, b, a))

# 对 dates 列表去重
dates = list(set(dates))
# 对日期列表进行排序,排序依据是元组中的元素,即年、月、日
dates.sort()
# 遍历排序后的日期列表,将其按照指定格式输出
for date in dates:
    print('{:04d}-{:02d}-{:02d}'.format(date[0], date[1], date[2]))

修改之后的代码,加入了非闰年天数不超过28天以及部分月份天数不能超过 30 天的限制,要更加合理一些:

import os
import sys
import datetime

def is_valid_date(year, month, day):
    """
    此函数用于判断输入的年、月、日是否为有效的日期,并检查是否在 1960 年 1 月 1 日至 2059 年 12 月 31 日之间
    :param year: 年份
    :param month: 月份
    :param day: 日期
    :return: 若为有效日期且在指定范围内返回 True,否则返回 False
    """
    # 定义大月的月份集合
    big_months = {1, 3, 5, 7, 8, 10, 12}
    # 定义小月的月份集合
    small_months = {4, 6, 9, 11}
    try:
        if month == 2:
            # 判断是否为闰年
            if (year % 4 == 0 and year % 100!= 0) or (year % 400 == 0):
                if 1 <= day <= 29:
                    date = datetime.date(year, month, day)
                    if datetime.date(1960, 1, 1) <= date <= datetime.date(2059, 12, 31):
                        return True
                else:
                    return False
            else:
                if 1 <= day <= 28:
                    date = datetime.date(year, month, day)
                    if datetime.date(1960, 1, 1) <= date <= datetime.date(2059, 12, 31):
                        return True
                else:
                    return False
        elif month in big_months:
            if 1 <= day <= 31:
                date = datetime.date(year, month, day)
                if datetime.date(1960, 1, 1) <= date <= datetime.date(2059, 12, 31):
                    return True
            else:
                return False
        elif month in small_months:
            if 1 <= day <= 30:
                date = datetime.date(year, month, day)
                if datetime.date(1960, 1, 1) <= date <= datetime.date(2059, 12, 31):
                    return True
            else:
                return False
        else:
            return False
    except ValueError:
        return False

def main():
    # 从标准输入读取日期字符串,并使用 map 函数将其按 / 分割并转换为整数存储在 a, b, c 中
    a, b, c = map(int, input().split('/'))
    # 存储满足条件的日期元组列表
    dates = []

    # 假设日期格式为年/月/日
    if 1 <= b <= 12 and 1 <= c <= 31:
        # 如果年份前两位大于等于 60,则年份是 19xx 年
        if a >= 60:
            # 调用 is_valid_date 函数判断日期是否有效
            if is_valid_date(1900 + a, b, c):
                dates.append((1900 + a, b, c))
        # 否则年份是 20xx 年
        else:
            if is_valid_date(2000 + a, b, c):
                dates.append((2000 + a, b, c))

    # 假设日期格式为月/日/年
    if 1 <= a <= 12 and 1 <= c <= 31:
        # 对年份的处理,根据 c 的大小判断是 19xx 年还是 20xx 年
        if c >= 60:
            if is_valid_date(1900 + c, a, b):
                dates.append((1900 + c, a, b))
        else:
            if is_valid_date(2000 + c, a, b):
                dates.append((2000 + c, a, b))

    # 假设日期格式为日/月/年
    if 1 <= a <= 31 and 1 <= b <= 12:
        # 对年份的处理,根据 c 的大小判断是 19xx 年还是 20xx 年
        if c >= 60:
            if is_valid_date(1900 + c, b, a):
                dates.append((1900 + c, b, a))
        else:
            if is_valid_date(2000 + c, b, a):
                dates.append((2000 + c, b, a))

    # 对 dates 列表去重
    dates = list(set(dates))
    # 对日期列表进行排序,排序依据是元组中的元素,即年、月、日
    dates.sort()
    # 遍历排序后的日期列表,将其按照指定格式输出
    for date in dates:
        print('{:04d}-{:02d}-{:02d}'.format(date[0], date[1], date[2]))

if __name__ == "__main__":
    main()

原文地址:https://blog.csdn.net/qq_27381427/article/details/145269579

免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!