python-根据给定的时间范围计算年、季、月、周的开始和结束日期

1.根据给定的日期字符串,获取当天所在年、季度、月、周的开始和结束日期

def get_first_and_last_day(date_str):
    """
    获取指定日期的开始、结束日期
    :param date_str: 字符串格式 '2020-08-21'
    :param need_key: 字符串格式 'year','quarter'
    :return:
    """
    result = {}
    struct_date = datetime.datetime.strptime(date_str, "%Y-%m-%d")
    # 获取当前月第一天和最后一天
    _, monthRange = calendar.monthrange(struct_date.year, struct_date.month)
    firstDay_month = datetime.date(year=struct_date.year, month=struct_date.month, day=1).strftime("%Y-%m-%d")
    lastDay_month = datetime.date(year=struct_date.year, month=struct_date.month, day=monthRange).strftime("%Y-%m-%d")

    # 获取当前年份第一天和最后一天
    _, last_month_of_days = calendar.monthrange(struct_date.year, 12)
    first_day_year = datetime.date(year=struct_date.year, month=1, day=1).strftime("%Y-%m-%d")
    last_day_year = datetime.date(year=struct_date.year, month=12, day=last_month_of_days).strftime("%Y-%m-%d")

    # 获取当前周第一天和最后一天
    this_week_start = (struct_date - datetime.timedelta(days=struct_date.weekday())).strftime("%Y-%m-%d")
    this_week_end = (struct_date + datetime.timedelta(days=6 - struct_date.weekday())).strftime("%Y-%m-%d")

    # 获取本季度第一天和最后一天
    month = struct_date.month
    if month in [1, 2, 3]:
        this_quarter_start = datetime.date(struct_date.year, 1, 1).strftime("%Y-%m-%d")
        this_quarter_end = (datetime.date(struct_date.year, 4, 1) - datetime.timedelta(days=1)).strftime("%Y-%m-%d")
    elif month in [4, 5, 6]:
        this_quarter_start = datetime.date(struct_date.year, 4, 1).strftime("%Y-%m-%d")
        this_quarter_end = (datetime.date(struct_date.year, 7, 1) - datetime.timedelta(days=1)).strftime("%Y-%m-%d")
    elif month in [7, 8, 9]:
        this_quarter_start = datetime.date(struct_date.year, 7, 1).strftime("%Y-%m-%d")
        this_quarter_end = (datetime.date(struct_date.year, 10, 1) - datetime.timedelta(days=1)).strftime("%Y-%m-%d")
    else:
        this_quarter_start = datetime.date(struct_date.year, 10, 1).strftime("%Y-%m-%d")
        this_quarter_end = (datetime.date(struct_date.year + 1, 1, 1) - datetime.timedelta(days=1)).strftime("%Y-%m-%d")

    result.update({
        'year': {'first_day': first_day_year, 'last_day': last_day_year},
        'month': {'first_day': firstDay_month, 'last_day': lastDay_month},
        'quarter': {'first_day': this_quarter_start, 'last_day': this_quarter_end},
        'week': {'first_day': this_week_start, 'last_day': this_week_end}, })
    return result

结果示例:
例如 date_str = '2020-08-29'

{'year': {'first_day': '2020-01-01', 'last_day': '2020-12-31'}, 
'month': {'first_day': '2020-08-01', 'last_day': '2020-08-31'}, 
'quarter': {'first_day': '2020-07-01', 'last_day': '2020-09-30'}, 
'week': {'first_day': '2020-08-24', 'last_day': '2020-08-30'}}

2. 根据给定的起止日期,获取这段范围内的日期列表

def get_date_list(start_date, end_date, format='%Y-%m-%d'):
    """
    根据开始日期、结束日期返回这段时间里所有天的集合
    :param start_date: 开始日期(日期格式或者字符串格式)
    :param end_date: 结束日期(日期格式或者字符串格式)
    :param format: 格式化字符串, 如: '%Y-%m-%d'
    :return:
    """
    date_list = []
    if isinstance(start_date, str) and isinstance(end_date, str):
        start_date = datetime.datetime.strptime(start_date, '%Y-%m-%d')
        end_date = datetime.datetime.strptime(end_date, '%Y-%m-%d')
    date_list.append(start_date.strftime(format))
    while start_date < end_date:
        start_date += datetime.timedelta(days=1)
        date_list.append(start_date.strftime(format))
        
    return date_list

结果示例: ('2020-08-04', '2020-08-29', '%Y-%m-%d')

['2020-08-04', '2020-08-05', '2020-08-06', '2020-08-07', '2020-08-08', '2020-08-09',
'2020-08-10', '2020-08-11', '2020-08-12', '2020-08-13', '2020-08-14', '2020-08-15',
'2020-08-16', '2020-08-17', '2020-08-18', '2020-08-19', '2020-08-20', '2020-08-21',
'2020-08-22', '2020-08-23', '2020-08-24', '2020-08-25', '2020-08-26', '2020-08-27',
'2020-08-28', '2020-08-29']

3. 获取指定年、月的起止日期

def get_month_start_and_end_date(year, month):
    """
    获取指定年月的开始结束日期
    :param year: '2020'
    :param month: '08'
    :return:第一天日期/最后一天日期
    """
    year, month = int(year), int(month)
    end = calendar.monthrange(year, month)[1]
    start_date = datetime.date(year=year, month=month, day=1).strftime("%Y-%m-%d")
    end_date = datetime.date(year=year, month=month, day=end).strftime("%Y-%m-%d")
    return start_date, end_date

结果示例: ('2020', '08')

('2020-08-01', '2020-08-31')

4.根据给定的起止时间,获取起止时间范围内的每个月的月初和月末时间

def get_month_start_and_end_by_date_interval(start_date, end_date):
    """
    获取指定时间段内每个月的起止时间参数列表
    :param start_date: 起始时间 --> str
    :param end_date: 结束时间 --> str
    :return: date_range_list -->list [{'2019-10-01': ['2019-10-01', '2019-10-31']}, ...}]

    """
    date_range_list = []
    start_date = datetime.datetime.strptime(start_date, '%Y-%m-%d')
    end_date = datetime.datetime.strptime(end_date, '%Y-%m-%d')
    # 计算开始日期的当月起止日期
    start_month_first = datetime.datetime(year=start_date.year, month=start_date.month, day=1).date()
    start_month_last = datetime.datetime(year=start_date.year, month=start_date.month,
                                         day=calendar.monthrange(start_date.year, start_date.month)[1]).date()
    date_range_list.append({start_month_first.strftime('%Y-%m-%d'): [start_month_first.strftime('%Y-%m-%d'),
                                                                     start_month_last.strftime('%Y-%m-%d')]})

    # 计算结束日期的当月起止日期
    end_month_first = datetime.datetime(year=end_date.year, month=end_date.month, day=1).date()
    end_month_last = datetime.datetime(year=end_date.year, month=end_date.month,
                                       day=calendar.monthrange(end_date.year, end_date.month)[1]).date()

    while True:
        # 下个月开始日期
        next_month_start = datetime.datetime(year=start_date.year, month=start_date.month,
                                             day=calendar.monthrange(start_date.year, start_date.month)[
                                                 1]).date() + datetime.timedelta(days=1)
        next_month_end = datetime.datetime(year=next_month_start.year, month=next_month_start.month,
                                           day=calendar.monthrange(next_month_start.year, next_month_start.month)[
                                               1]).date()
        if next_month_start < end_month_first:
            date_range_list.append({next_month_start.strftime('%Y-%m-%d'): [next_month_start.strftime('%Y-%m-%d'),
                                                                            next_month_end.strftime('%Y-%m-%d')]})
            start_date = next_month_start
        else:
            break
    # 避免传入的起止日期在同一月导致数据重复
    temp_dict = {end_month_first.strftime('%Y-%m-%d'): [end_month_first.strftime('%Y-%m-%d'),
                                                        end_month_last.strftime('%Y-%m-%d')]}
    if temp_dict not in date_range_list:
        date_range_list.append(temp_dict)
    return date_range_list

结果示例:('2020-05-31','2020-08-01')

[{'2020-05-01': ['2020-05-01', '2020-05-31']}, 
{'2020-06-01': ['2020-06-01', '2020-06-30']}, 
{'2020-07-01': ['2020-07-01', '2020-07-31']}, 
{'2020-08-01': ['2020-08-01', '2020-08-31']}]

5.根据给定的起止时间段,获取时间范围内每周的开始和结束日期

def get_week_monday_and_sunday_by_date(date_str):
    """
    给定一个日期-返回日期所在周的周一0点时间 和 周日23点59分59秒
    :param date_str: 如:"2020-05-01"
    :return: 给定一个日期-返回日期所在周的周一0点时间 和 周日23点59分59秒
    """
    now_time = datetime.datetime.strptime(date_str + " 00:00:00", "%Y-%m-%d %H:%M:%S")
    week_start_time = now_time - datetime.timedelta(days=now_time.weekday(), hours=now_time.hour,
                                                    minutes=now_time.minute, seconds=now_time.second,
                                                    microseconds=now_time.microsecond)
    week_end_time = week_start_time + datetime.timedelta(days=6, hours=23, minutes=59, seconds=59)
    return week_start_time, week_end_time


def get_week_start_and_end_by_date_interval(start_date_str, end_date_str):
    """
    给定时间(日期)区间,返回区间中所有的周起止时间列表
    :param start_date_str: "2020-01-31"
    :param end_date_str: "2020-05-08"
    :return: [{'2020-01-06': ['2020-01-06', '2020-01-12']}, {'2019-12-30': ['2019-12-30', '2020-01-05']}, ...]
    """
    date_list = list()
    # 截止时间
    end_date = datetime.datetime.strptime(end_date_str + " 00:00:00", "%Y-%m-%d %H:%M:%S")
    # 起始时间所在周 - 周一和周日
    start_week_monday, start_week_sunday = get_week_monday_and_sunday_by_date(start_date_str)

    # 截止时间所在周 - 周一和周日
    end_week_monday, end_week_sunday = get_week_monday_and_sunday_by_date(end_date_str)
    if end_week_monday <= end_date:
        # 结束日期 <= 给定的截止日期
        date_list.append(
            {end_week_monday.strftime('%Y-%m-%d'): [end_week_monday.strftime('%Y-%m-%d'),
                                                    end_week_sunday.strftime('%Y-%m-%d')]})

    count = 1
    while True:
        week_start_time = end_week_monday - datetime.timedelta(days=7 * count)  # 截止日期所在的周一,向前减7天取上一个周一
        week_end_time = week_start_time + datetime.timedelta(days=6, hours=23, minutes=59, seconds=59)  # 前一周的周日

        count += 1
        if week_start_time < start_week_monday:
            break
        date_list.append(
            {week_start_time.strftime('%Y-%m-%d'): [week_start_time.strftime('%Y-%m-%d'),
                                                    week_end_time.strftime('%Y-%m-%d')]})
    return date_list[::-1]

结果示例: ('2020-05-31','2020-08-01')

[{'2020-05-25': ['2020-05-25', '2020-05-31']}, 
{'2020-06-01': ['2020-06-01', '2020-06-07']},
 {'2020-06-08': ['2020-06-08', '2020-06-14']}, 
 {'2020-06-15': ['2020-06-15', '2020-06-21']}, 
 {'2020-06-22': ['2020-06-22', '2020-06-28']}, 
 {'2020-06-29': ['2020-06-29', '2020-07-05']}, 
 {'2020-07-06': ['2020-07-06', '2020-07-12']},
  {'2020-07-13': ['2020-07-13', '2020-07-19']},
   {'2020-07-20': ['2020-07-20', '2020-07-26']}, 
   {'2020-07-27': ['2020-07-27', '2020-08-02']}]

6. 根据给定的时间段,获取这段时间范围内所有季度的开始和结束日期

def getBetweenMonth(begin_date, end_date):
    date_list = []
    begin_date = datetime.datetime.strptime(begin_date, "%Y-%m-%d")
    end_date = datetime.datetime.strptime(end_date, '%Y-%m-%d')
    while begin_date <= end_date:
        date_str = begin_date.strftime("%Y-%m")
        date_list.append(date_str)
        begin_date = add_months(begin_date, 1)
    return date_list


def add_months(dt, months):
    month = dt.month - 1 + months
    year = int(dt.year + month / 12)
    month = month % 12 + 1
    day = min(dt.day, calendar.monthrange(year, month)[1])
    return dt.replace(year=year, month=month, day=day)


def getBetweenQuarter(begin_date, end_date):
    # 加上每季度的起始日期、结束日期
    quarter_list = {}
    month_list = getBetweenMonth(begin_date, end_date)
    for value in month_list:
        tempvalue = value.split("-")
        year = tempvalue[0]
        if tempvalue[1] in ['01', '02', '03']:
            quarter_list[year + "-01-01"] = ['%s-01-01' % year, '%s-03-31' % year]
        elif tempvalue[1] in ['04', '05', '06']:
            quarter_list[year + "-04-01"] = ['%s-04-01' % year, '%s-06-30' % year]
        elif tempvalue[1] in ['07', '08', '09']:
            quarter_list[year + "-07-01"] = ['%s-07-31' % year, '%s-09-30' % year]
        elif tempvalue[1] in ['10', '11', '12']:
            quarter_list[year + "-10-01"] = ['%s-10-01' % year, '%s-12-31' % year]

    return quarter_list

结果示例: (‘2020-04-25’, ‘2020-10-01’)

{'2020-04-01': ['2020-04-01', '2020-06-30'], 
'2020-07-01': ['2020-07-31', '2020-09-30'], 
'2020-10-01': ['2020-10-01', '2020-12-31']}

7.根据给定的时间段,获取这段时间范围内所有年份的开始和结束日期

def get_between_year(begin_date, end_date):
    """
    获取年份区间
    :param begin_date: '2017-04-25', str类型
    :param end_date: '2020-08-01', str类型
    :return:  ['2017-01-01 00:00:00', '2018-01-01 00:00:00', '2019-01-01 00:00:00', '2020-01-01 00:00:00']
    """
    year_list = []
    begin_date = datetime.datetime.strptime(begin_date, '%Y-%m-%d')
    end_date = datetime.datetime.strptime(end_date, '%Y-%m-%d')
    while begin_date <= end_date:
        date_str = datetime.datetime(year=begin_date.year, month=begin_date.month, day=1).strftime("%Y-%m-%d %H:%M:%S")
        year_list.append(date_str)
        # 开始日期当年最后一天 + 1即下一年的开始时间
        begin_date = datetime.datetime(year=begin_date.year, month=12, day=31) + datetime.timedelta(days=1)
    return year_list


def get_year_start_and_end_by_date_interval(begin_date, end_date):
    """
    根据给定的时间段范围,获取期间每个年份的开始和结束日期
    :param begin_date: '2019-04-25', str类型
    :param end_date: '2020-08-01', str类型
    :return: {'2019-01-01': ['2019-01-01', '2019-12-31'], '2020-01-01': ['2020-01-01', '2020-12-31']}
    """
    year_dict = dict()
    year_list = get_between_year(begin_date, end_date)  # 如: ['2019-01-01 00:00:00', '2020-01-01 00:00:00']
    for value in year_list:
        date_str, time_str = value.split(" ")
        year, month, day = date_str.split('-')
        year_dict[date_str] = [date_str, '%s-12-31' % year]

    return year_dict

结果示例: (‘2017-04-25’, ‘2020-10-01’)

{
'2017-01-01': ['2017-01-01', '2017-12-31'], 
'2018-01-01': ['2018-01-01', '2018-12-31'], 
'2019-01-01': ['2019-01-01', '2019-12-31'], 
'2020-01-01': ['2020-01-01', '2020-12-31']
}

8.获取当前时间前N周的开始时间和结束时间

def last_first_date_and_last_date(n):
    """
    获取前n周开始时间和结束时间,参数n:代表前n周
    :param n: int类型 数字:1,2,3,4,5
    :return: 返回前n周的周一0点时间  和 周日23点59分59秒
    """
    now = datetime.datetime.now()
    before_n_week_start = now - datetime.timedelta(days=now.weekday() + 7 * n, hours=now.hour, minutes=now.minute, seconds=now.second, microseconds=now.microsecond)
    before_n_week_end = before_n_week_start + datetime.timedelta(days=6, hours=23, minutes=59, seconds=59)
    return before_n_week_start.strftime('%Y-%m-%d'), before_n_week_end.strftime('%Y-%m-%d')

结果示例: n=2,ps.今天为2020-08-29

('2020-08-10', '2020-08-16')
  • 6
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值