美文网首页
【2017-09-19】数字日期与时间(二)

【2017-09-19】数字日期与时间(二)

作者: 小蜗牛的成长 | 来源:发表于2017-09-19 11:53 被阅读0次

    日期与时间

    • 简单的日期转化与计算
      执行不同时间的转换与计算,通常用到datetime模块,不可忽略的是其中timedelta。顺便插播一段,时间的处理在日常工作中经常用到,记得最开始的时候,都是自定义一个方法通过时间戳来进行时间计算,直到最近给男朋友写爬虫时,结合之前了解到的datetime模块,才发现timedelta的好处。
    >>> a=timedelta(days=2, hours=6)
    >>> b = timedelta(hours=4.5)
    >>> c=a+b
    >>> c.days
    2
    >>> c.seconds
    37800
    >>> c.total_seconds()
    210600.0
    >>> 
    

       上述提到的爬虫,需求:有一个网站,需要输入起始时间和结束时间以及其他信息,点击下一页、下一页...,提取出每页的内容。
       上述需求暂仅考虑时间部分,为了实现最大自动化,用户可决定下载几天数据。‘几天’就需要用到时间的计算,给出一个当前日期,向前或者向后进行推送。

    >>> start_time=datetime(2012, 3, 1)
    >>> start_time
    datetime.datetime(2012, 3, 1, 0, 0)
    >>> next_time=start_time+timedelta(days=1)
    >>> next_time
    datetime.datetime(2012, 3, 2, 0, 0)
    >>> 
    

       在进行计算时,datetime 会自动处理闰年

    >>> a = datetime(2012, 3, 1)
    >>> b = datetime(2012, 2, 28)
    >>> a-b
    datetime.timedelta(2)
    >>> (a-b).days
    2
    >>> c = datetime(2013, 3, 1)
    >>> d = datetime(2013, 2, 28)
    >>> (c - d).days
    1
    >>> 
    

      使用timedelta可以很方便的在日期上做days,hours,seconds等时间计算,如果要计算月份则需要另外的办法。
      更加复杂的日期处理,可使用dateutil模块,许多类似的时间计算可以使用 dateutil.relativedelta()函数代替

    • 计算最后一个周五的日期
      你需要查找星期中某一天最后出现的日期,比如星期五
      示例:求出指定星期几最后出现的日期
        先将开始日期和目标日期映射到星期数组的位置上 (星期一索引为 0),然后通过模运算计算出目标日期要经过多少天才能到达开始日期。然后用开始日期减去那个时间差即得到结果日期。
    >>> weekdays = ['Monday', 'Tuesday', 'Wednesday', 'Thursday',
    'Friday', 'Saturday', 'Sunday']
    >>> def get_previous_byday(dayname, start_date=None):
        if start_date is None:
            start_date = datetime.today()
            day_num = start_date.weekday()
            day_num_target = weekdays.index(dayname)
            days_ago = (7 + day_num - day_num_target) % 7
            if days_ago == 0:
                days_ago = 7
            target_date = start_date - timedelta(days=days_ago)
            return target_date
    
        
    >>> get_previous_byday('Monday')
    datetime.datetime(2017, 9, 18, 11, 6, 2, 863482)
    >>> get_previous_byday('Tuesday')
    datetime.datetime(2017, 9, 12, 11, 6, 24, 398482)
    >>> 
    
    • 计算当前月份的日期范围
      问题:在当前月份中循环每一天,想找到一个计算这个日期范围的高效方法。
      解决方案:
        在这样的日期上循环并需要事先构造一个包含所有日期的列表。关键是先计算出开始日期和结束日期,然后在你步进的时候使用 datetime.timedelta 对象递增这个日期变量即可。
    >>> import calendar
    >>> def get_month_range(start_date=None):
        if start_date is None:
            start_date = date.today().replace(day=1)
            _, days_in_month = calendar.monthrange(start_date.year, start_date.month)
        end_date = start_date + timedelta(days=days_in_month)
        return (start_date, end_date)
    
    >>> first_day, last_day = get_month_range()
    >>> first_day
    datetime.date(2017, 9, 1)
    >>> last_day
    datetime.date(2017, 10, 1)
    

      使用 calendar.monthrange() 函数来找出该月的总天数。任何时候只要你想获得日历信息,那么 calendar 模块就非常有用了。 monthrange() 函数会返回包含星期和该月天数的元组。

    >>> calendar.monthrange(start_date.year, start_date.month)
    (4, 30)
    >>> 
    

      一旦该月的天数已知了,那么结束日期就可以通过在开始日期上面加上这个天数获得。值得注意的是结束日期并不包含在这个日期范围内 (事实上它是下个月的开始日期)。这个和 Python 的 slice 与 range 操作行为保持一致,同样也不包含结尾。可以创建类似内置range()的函数。

    >>> for d in date_range(datetime(2012, 9, 1), datetime(2012,10,1),
    timedelta(hours=6)):
        print(d)
    
        
    2012-09-01 00:00:00
    2012-09-01 06:00:00
    2012-09-01 12:00:00
    2012-09-01 18:00:00
    2012-09-02 00:00:00
    2012-09-02 06:00:00
    ...
    
    • 字符串转换为日期
      执行 datetime 对象转化成日期字符串或者日期字符串转化成datetime对象
      datetime模块提供了strptime()和strftime()方法供使用,但是考虑到性能,当涉及到处理大量日期的时候,strptime()不建议使用,因为它是使用纯 Python 实现,并且必须处理所有的系统本地设置,性能比想象中差很多。可自定义一个方法代替,比如:
    from datetime import datetime
    def parse_ymd(s):
    year_s, mon_s, day_s = s.split('-')
    return datetime(int(year_s), int(mon_s), int(day_s))
    
    • 结合时区的日期处理
      示例:
    >>> d = datetime(2012, 12, 21, 9, 30, 0)
    >>> central = timezone('US/Central')
    >>> loc_d = central.localize(d)
    >>> d
    datetime.datetime(2012, 12, 21, 9, 30)
    >>> loc_d
    datetime.datetime(2012, 12, 21, 9, 30, tzinfo=<DstTzInfo 'US/Central' CST-1 day, 18:00:00 STD>)
    >>> 
    

    上述关键是类似US/Central怎么得到?
    为了查找,可以使用 ISO 3166 国家代码作为关键字去查阅字典pytz.country timezones

    >>> import pytz
    >>> pytz.country_timezones['IN']
    ['Asia/Kolkata']
    >>> pytz.country_timezones['AE']
    ['Asia/Dubai']
    >>> 
    

    相关文章

      网友评论

          本文标题:【2017-09-19】数字日期与时间(二)

          本文链接:https://www.haomeiwen.com/subject/cjcwsxtx.html