Iterable Datetime - 如何在Python中使用日期名称获取continuos datetime对象?

时间:2018-01-07 09:20:13

标签: python datetime dictionary

我想用datetime对象创建一周中每天的映射。因此,我的字典应该是键和#34;星期一","星期二",...(等等)以便我可以在下一天获得datetime对象的每一天(!)周。

目前我有一个包含这些值的字典:

DAYS_DATETIME_RELATIONS = {
    "today": datetime.datetime.now(),
    "tomorrow": datetime.datetime.now() + datetime.timedelta(days=1),
    "after_tomorrow": datetime.datetime.now() + datetime.timedelta(days=2)
}

不幸的是我找不到任何算法解决方案,希望你们中的任何人都可以帮助我。

4 个答案:

答案 0 :(得分:2)

这可以通过以下方式使用2个词典来实现:

import calendar
import datetime

days = {i: calendar.day_name[i-1] for i in range(7)}

today = datetime.datetime.now()

# using i % 7 so an arbitrary range can be used, for example
# range(7, 15) to get the week after the next week 
next_week = {days[i % 7]: (today + datetime.timedelta(days=i)).date()
             for i in range(7)}

print(next_week)
#  {'Tuesday': datetime.date(2018, 1, 9), 'Sunday': datetime.date(2018, 1, 7), 
#   'Monday': datetime.date(2018, 1, 8), 'Thursday': datetime.date(2018, 1, 11), 
#   'Wednesday': datetime.date(2018, 1, 10), 'Friday': datetime.date(2018, 1, 12), 
#   'Saturday': datetime.date(2018, 1, 13)}

print(next_week['Saturday'])
# 2018-01-13

答案 1 :(得分:1)

一种非常通用的方法是创建一个自定义迭代器,以便将连续的datetime对象返回为:

from datetime import datetime, timedelta

class RepetetiveDate(object):
    def __init__(self, day_range=7, datetime_obj=datetime.now(), jump_days=1):
        self.day_range = day_range
        self.day_counter = 0
        self.datetime_obj = datetime_obj
        self.jump_days = jump_days
        self.time_deltadiff = timedelta(days=self.jump_days)

    def __iter__(self):
        return self

    # If you are on Python 2.7
    #    define this function as `next(self)`
    def __next__(self):

        if self.day_counter >= self.day_range:
            raise StopIteration

        if self.day_counter != 0:  # don't update for the first iteration
            self.datetime_obj += self.time_deltadiff

        self.day_counter += 1
        return self.datetime_obj

此处, 此迭代器从您最初传递的datetime对象 开始返回continuos datetime对象(默认从当前日期开始) 。

它使用3个可选参数,您可以根据需要自定义:

  • day_range RepetetiveDate迭代器的最大允许迭代次数。 默认值为7

  • jump_days :在下一次迭代中跳过datetime对象的天数的整数值。这意味着,如果jump_days等于"2",则会返回每个备用日期的日期时间对象。要获取过去的datetime对象,请将此值作为否定传递。 默认值为1

  • datetime_obj :接受您希望开始迭代的datetime日期。 默认值为当前日期

如果您不熟悉迭代器,请查看:

即将到来的日期示例运行

>>> x = RepetetiveDate()
>>> next(x)
datetime.datetime(2018, 1, 8, 15, 55, 39, 124654)
>>> next(x)
datetime.datetime(2018, 1, 9, 15, 55, 39, 124654)
>>> next(x)
datetime.datetime(2018, 1, 10, 15, 55, 39, 124654)

以前日期的示例运行

>>> x = RepetetiveDate(jump_days=-1)
>>> next(x)
datetime.datetime(2018, 1, 6, 15, 55, 39, 124654)
>>> next(x)
datetime.datetime(2018, 1, 5, 15, 55, 39, 124654)
>>> next(x)
datetime.datetime(2018, 1, 4, 15, 55, 39, 124654)

如何获得所需的字典?

使用此功能,您可以使用 dict comprehension 创建词典:

  • 一周中所有日子的词典

    >>> {d.strftime("%A"): d for d in RepetetiveDate(day_range=7)}
    { 
        'Monday': datetime.datetime(2018, 1, 8, 15, 23, 16, 926364),
        'Tuesday': datetime.datetime(2018, 1, 9, 15, 23, 16, 926364), 
        'Wednesday': datetime.datetime(2018, 1, 10, 15, 23, 16, 926364), 
        'Thursday': datetime.datetime(2018, 1, 11, 15, 23, 16, 926364),
        'Friday': datetime.datetime(2018, 1, 12, 15, 23, 16, 926364), 
        'Saturday': datetime.datetime(2018, 1, 13, 15, 23, 16, 926364), 
        'Sunday': datetime.datetime(2018, 1, 14, 15, 23, 16, 926364)
    }
    

    我在这里使用d.strftime("%A")datetime对象中提取日期名称。

  • 接下来4周的当前日期列表

    >>> [d for d in RepetetiveDate(jump_days=7, day_range=4))]
    [
        datetime.datetime(2018, 1, 7, 16, 17, 45, 45005), 
        datetime.datetime(2018, 1, 14, 16, 17, 45, 45005), 
        datetime.datetime(2018, 1, 21, 16, 17, 45, 45005),
        datetime.datetime(2018, 1, 28, 16, 17, 45, 45005)
    ]
    

答案 2 :(得分:1)

以下是使用datetime模块中的timedeltadatetime解决问题的另一种方法:

from datetime import datetime, timedelta

def generate_dict_relation(_time, _days=0):
    keys = {'Yesterday': -1, 'Today': 0, 'Tomorow': 1, 'After_tomorrow': 2}

    if not _days:
        return {key: _time + timedelta(days=keys.get(key, 0)) for key in keys}
    else:
        return {(_time + timedelta(days=_days+k)).strftime('%A'): _time + timedelta(days=_days+k)
                    for k in range(0, 7)}

_date_now = datetime.now()
DAYS_DATETIME_RELATIONS = {}
# get dates: yesterday, today, tomorrow and after tomorrow
DAYS_DATETIME_RELATIONS.update(generate_dict_relation(_date_now, 0))
# get dates after 7 days = 1 week
DAYS_DATETIME_RELATIONS.update(generate_dict_relation(_date_now, 7))

next_tuesday = DAYS_DATETIME_RELATIONS.get('Tuesday')
next_monday = DAYS_DATETIME_RELATIONS.get('Monday')
yesterday = DAYS_DATETIME_RELATIONS.get('Yesterday')

print('{0:%d/%m/%Y %H:%M:%S:%s} \t {1}'.format(next_tuesday, repr(next_tuesday)))
print('{0:%d/%m/%Y %H:%M:%S:%s} \t {1}'.format(next_monday, repr(next_monday)))
print('{0:%d/%m/%Y %H:%M:%S:%s} \t {1}'.format(yesterday, repr(yesterday)))

输出:

16/01/2018 10:56:26:1516096586   datetime.datetime(2018, 1, 16, 10, 56, 26, 659949)
15/01/2018 10:56:26:1516010186   datetime.datetime(2018, 1, 15, 10, 56, 26, 659949)
06/01/2018 10:56:26:1515232586   datetime.datetime(2018, 1, 6, 10, 56, 26, 659949)

答案 3 :(得分:1)

实现此目的的一种非常简洁的方法是使用dateutil库中的rrule。例如:

>>> from dateutil.rrule import rrule, DAILY
>>> from datetime import datetime
>>> start_date = datetime.now()

>>> {d.strftime("%A"): d for d in rrule(freq=DAILY, count=7, dtstart=start_date)}

将返回您想要的dict对象:

{  
     'Sunday': datetime.datetime(2018, 1, 7, 17, 2, 30),
     'Monday': datetime.datetime(2018, 1, 8, 17, 2, 30), 
     'Tuesday': datetime.datetime(2018, 1, 9, 17, 2, 30), 
     'Wednesday': datetime.datetime(2018, 1, 10, 17, 2, 30),
     'Thursday': datetime.datetime(2018, 1, 11, 17, 2, 30),
     'Friday': datetime.datetime(2018, 1, 12, 17, 2, 30), 
     'Saturday': datetime.datetime(2018, 1, 13, 17, 2, 30)
}

(特别感谢Jon Clements告诉我rrule