Python学习:datetime模块

这篇博客详细介绍了Python的datetime模块,包括timedelta、date和datetime对象的创建与操作,以及时区定义。通过示例展示了如何构造和使用这些对象,如通过时间戳、日期字段创建datetime对象,以及进行日期运算和时区转换。

timedelta

一个timedelta实例对象代表了一个时间差,当两个date对象或者datetime进行减法操作时,将会返回一个timedelta对象,timedelta对象的构造函数为:

class datetime.timedelta([days[, seconds[, microseconds[, milliseconds[, minutes[, hours[, weeks]]]]]]])

所有的参数都是可选参数,且默认为0,当传递由以上某几个参数值后,输出的timedelta对象将通过days、seconds与microseconds三个参数来表示时间差值。

timedelta对象支持数学运算。

>>> t1 = datetime.timedelta(seconds=60)
>>> t2 = datetime.timedelta(seconds=30)
>>> t3 = t1 + t2
>>> t3.seconds
90
>>> t4 = t1 -t2
>>> t4.seconds
30
>>> t5 = t1 * 2
>>> t5
datetime.timedelta(0, 120)
>>> t6 = t1 * 0
>>> t6
datetime.timedelta(0)
>>> t7 = t1 / 3
>>> t7
datetime.timedelta(0, 20)
>>> t7 = t1 / 7
>>> t7
datetime.timedelta(0, 8, 571428)
>>> t7 = t1 // 7
>>> t7
datetime.timedelta(0, 8, 571428)
>>> t1 > t2
True
>>> t1 < t2
False
>>> t1 == t2
False
>>> t1 == 60
False
>>> t1 != 60
True
>>> t1 > 60
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can't compare datetime.timedelta to int

date

一个date对象代表使用年、月、日表示的时间。可以传入参数年、月、日来构造date对象。当得到date对象后,就可以直接访问date对象的年、月、日属性:

>>> today = date.today()
>>> today
datetime.date(2016, 9, 1)
>>> today.year
2016
>>> today.month
9
>>> today.day
1

date对象也支持运算与比较操作:

>>> delta = timedelta(days=7)
>>> future = today + delta
>>> future
datetime.date(2016, 9, 8)
>>> future - delta
datetime.date(2016, 9, 1)
>>> future - today
datetime.timedelta(7)
>>> future > today
True

datetime

datetime从字面意思上看是datetime的结合,而实际上也是包含了这两个对象的全部信息,我们可以手动构造datetime对象,也可以使用系统提供的静态方法,当我们手动构造的时候,必须要传入yearmonthday三个参数,他们的取值范围与上面讲到的date对象一致。

我们在处理时间问题时,始终无法回避的是时区问题,在python中,使用datetime.tzinfo来表示时区,但这是一个抽象基类,python也并没帮我们实现任意的时区,因此,我们首先来看下在不涉及时区的时候datetime都有哪些用法,然后我们会创建一个本地时区,也就是东八区,来说明datetime如何与tzinfo结合使用。

datetime对象的创建

我们可以通过指定年月日的形式来手动创建一个datetime实例。

>>> cur = datetime(year=2016, month=9, day=2)
>>> cur
datetime.datetime(2016, 9, 2, 0, 0)

也可以直接通过静态方法来获取:

>>> datetime.today()
datetime.datetime(2016, 9, 2, 17, 50, 21, 810692)
>>> datetime.now()
datetime.datetime(2016, 9, 2, 17, 50, 34, 89763)

这两个方法都会返回一个本地当前时间,也就是上面的两个写法是等效的,但是要注意的是,now()方法可以传入时区信息,我们稍后再一起讨论。

除了上面的方法,我们还可以通过时间戳来获取一个对象。

>>> datetime.fromtimestamp(time.time())
datetime.datetime(2016, 9, 2, 17, 54, 56, 65907)

除了通过时间戳获取datetime实例外,我们还可以通过一个格式化的时间字符串来获得实例,这个方法同样是不带时区信息的。

>>> datetime.strptime('2016-09-02 18:00:00', '%Y-%m-%d %H:%M:%S')
datetime.datetime(2016, 9, 2, 18, 0)

既然一个datetime对象包含了datetime的所有信息,那么能不能通过这两对象来生成一个datetime实例呢,答案是肯定的。

>>> d = date(year=2016, month=9, day=2)
>>> d
datetime.date(2016, 9, 2)
>>> t = time(hour=18, minute=14)
>>> t
datetime.time(18, 14)
>>> datetime.combine(d, t)
datetime.datetime(2016, 9, 2, 18, 14)

常用方法

有了datetime对象之后,我们就可以获得对应的datetime对象了:

>>> today = datetime.today()
>>> today.date()
datetime.date(2016, 9, 2)
>>> today.time()
datetime.time(18, 30, 10, 304536)

那如果我希望得到下个月的今天,该怎么做呢?方法有多种,但是最方便的是直接把月份进行加一操作(不考虑跨年和日期超过月份最大值的情况),这个时候replace函数就派上用场:

>>> next_month = today.replace(month=today.month+1)
>>> next_month
datetime.datetime(2016, 10, 2, 18, 30, 10, 304536)

replace()方法允许我们对datetime的任意字段进行替换,并返回一个新的datetime对象,这个新的对象在其他字段上与原有对象保持一致。

除此之外,还有一个比较常用的方法strftime(),通过它可以格式化成我们希望的样式:

>>> next_month.strftime('%Y-%m-%d %H:%M:%S')
'2016-10-02 18:30:10'

还有一种情况,是我们希望将一个datetime对象转成时间戳,很遗憾的是python并没直接提供这个方法,但是提供了一个timetuple()方法,它返回一个time.struct_time对象,通过它我们可以构造出时间戳:

>>> dd = datetime.today()
>>> tt = time.mktime(dd.timetuple())
>>> print int(tt)
1472816083

时区的定义

python中给我们提供了datetime.tzinfo这一抽象的基类,如果我们想使用时区,则必须继承这个类来实现自己的时区定义。需要我们实现的方法包括:

  1. tzinto.utcoffset(self, dt) 这个方法返回本地时间与UTC时间的时差,我们知道,我们国家使用的是东八区,也就是比世界协调时间(UTC)/格林尼治时间(GMT)快8小时的时区,因此我们可以如下实现这个方法:
def utcoffset(self, dt):
    return timedelta(hours=8)
  1. tzinfo.dst(self, dt) 这个方法主要是考虑到一些采用夏令时的国家,在固定月份来调整时间,而我们国家是没有采用夏令时,所以直接返回0:
def dst(self, dt):
    return timedelta(0)

而对于采纳了夏令时的国家,则需要把夏令时考虑进去:

def dst(self, dt):
    # Code to set dston and dstoff to the time zone's DST
    # transition times based on the input dt.year, and expressed
    # in standard local time.  Then
 
    if dston <= dt.replace(tzinfo=None) < dstoff:
        return timedelta(hours=1)
    else:
        return timedelta(0)

对于这些国家,我还要修改utcoffset函数,将夏令时的偏移量考虑进去:

def utcoffset(self, dt):
    return timedelta(hours=N) + self.dst(dt)
  1. tzinfo.tzname(self, dt) 这个方法用来返回时区的名称。

一般情况下,我们只要实现上面三个方法就可以了,例如我们可以这样定义一个UTC时区和我们所在的东八区。

ZERO = timedelta(0)
HOUR = timedelta(hours=1)
 
class UTC(tzinfo):
    """UTC"""
 
    def utcoffset(self, dt):
        return ZERO
 
    def tzname(self, dt):
        return "UTC"
 
    def dst(self, dt):
        return ZERO
 
 
class GMT8(tzinfo):
    """东八区"""
    
    def utcoffset(self, dt):
        return HOUR * 8
    def tzname(self, dt):
        return 'GMT-8'
    def dst(self, dt):
        return ZERO
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值