Understanding DateTime, tzinfo, timedelta & TimeZone Conversions in python

上一篇 / 下一篇  2010-05-11 15:40:04 / 个人分类:Python

Python官方文档中关于datetime模块,尤其是tzinfo部分的描述,以我的智商实在是难以理解,直到找到如题那篇文章,才恍然大悟.

原文出处:by RAMA VADAKATTU ,第一次翻译,贱笑了

在这篇文章中我们将讨论日期和时间的常用操作,以 及将一个日期时间从一个时区转换到另一个时区.

怎样表达datetime对象?

In [189]: cdatetime = datetime.now()
In [190]: cdatetime
Out[190]: datetime.datetime(2009, 2, 17, 17, 34, 58, 407806)

以上代码返回的是当前的本地日期和时间,变量cdatetime将输出一个包含九个元素的元组(2009=year, 2=month, 17=day, 17=hour, 34=minutes, 58=seconds, 407806=microseconds, tzinfo is None and is not printed),像这样的9-元组是Python中datetime对象的基本表示法,如dt = datetime(2009, 2, 17, 17, 34, 58, 407806)

如何将datetime对象转变为格式化的字符串表示?

In [194]:curdate.strftime("%d %b %Y %I:%M:%S %p")
Out[194]: '17 Feb 2009 05:18:27 PM'

将日期直接用元组的形式呈现给人看是很不靠谱的,因为大多数人无法直观的理解.所以我们需要将它转换为一种通用易读的字符串形式,实现这个功能需要 的是strftime()函数,"%d %b %Y %I:%M:%S %p"是用来格式化的字符串,每个百分号(%)后面的字符指示datetime对象的相应部分如何呈现,比如%M以当前语言环境下月份名的简写形式表示相 应的月份.(英语中即Feb表示元组中的2).%I表示用12小时制显示小时.更多格式化的指令可以在http://docs.python.org/library/datetime.html找 到.

怎样将字符串转换成datetime对象?

In [195]: dt = datetime.strptime('17 Feb 2009 04:22:11 PM','%d %b %Y %I:%M:%S %p')
In [196]: dt
Out[196]: datetime.datetime(2009, 2, 17, 16, 22, 11)
In [197]: dt.strftime("%d %b %Y %I:%M:%S %p")
Out[197]: '17 Feb 2009 04:22:11 PM'

大多数时候我们接受到的日期是像( ‘17 Feb 2009 04:22:11 PM’)这种字符串形式,我们需要将这种字符串转换成datetime对象,strptime()函数可以用来完成这个功能,格式化字符串"%d %b %Y %I:%M:%S %p"用来指定日期时间字符串中各个部分的组成形式和出现顺序(比如第一个十进制表示的是月份日期,第二个月份是作为区域设置的缩写月份名称显示 等...)

怎样将一个元组转换成datetime对象?

Out[87]: k = (2009, 2, 17, 16, 22, 11)
In [89]: dt = datetime.datetime(k[0:6])
In [206]:dt
Out[206]:datetime.datetime(2009, 2, 17, 16, 22, 11)
In [207]:dt.strftime("%d %b %Y %I:%M:%S %p")
Out[207]: '17 Feb 2009 04:22:11 PM'

许多时候你会遇到一种像上面那样你要通过元组(2009, 2, 17, 16, 22, 11)来构建datetime的情况,比如Universal feed parser获取的博客订阅中的日期就是9-元组的形式.我们可以使用这样的代码来转换dt = datetime.datetime(k[0:6])

如何调整现在的时间表示到两天之前/之后?

In [3]: curdate = datetime.now()
In [5]: curdate.strftime("%d %b %Y %I:%M:%S %p")
Out[5]: '18 Feb 2009 09:56:59 AM'
#gives you the two days back date
In [14]: curdate = curdate-timedelta(days=2)
In [15]: curdate.strftime("%d %b %Y %I:%M:%S %p")
Out[15]: '16 Feb 2009 09:56:59 AM'
#gives you the date after 3 days etc..
In [17]: curdate = curdate+timedelta(days=3,hours=5,minutes=5,milliseconds=1000)
In [18]: curdate.strftime("%d %b %Y %I:%M:%S %p")
Out[18]: '20 Feb 2009 03:07:51 PM'

1)timedelta对象是用来表示时间间隔的,请看in[14],in[17]初始化timedelta的不同方法.详细:http://docs.python.org/library/datetime.html#datetime.timedelta 
2)use this timedelta object in airthmetic wih datetime (in[14]) to get the datetime before and after specified duration.) (airthmetic不知道什么意思)

 使用timedelta对象你就可以回答怎样调整日期对象到45天之前或者一个月之后等这些问题了.

怎样检查datetime对象表示时间所在的时区?

Python中的时区是通过一个叫tzinfo的抽象基类表示,为了给datetime对象分配一个时区,我们需要创建一个tzinfo的子类,并 且把这个子类对象传递给datetime.tzinfo属性,如下所示:

In [211]:curdate = datetime.now()
In [212]:print curdate.tzinfo
None

像上面那样tzinfo属性为null或者None,这种datetime对象称作"天真的"(naive) datetime对象,我们无法对这种naive datetime objects执行与时区有关的操作.如果tzinfo不是null/None,这种datetime对象叫做Timezone aware objects,这种datetime对象可以执行与时区相关的操作,下面我将用一个例子来清楚的阐述整个过程

In [162]: class GMT5(tzinfo)
.....: def utcoffset(self,dt):
#51/2 hours ahead of GMT
.....: return timedelta(hours=5,minutes=30)
.....: def tzname(self,dt):
.....: return "GMT +5"
.....: def dst(self,dt):
.....: return timedelta(0)
In [171]: gmt5 = GMT5()
In [220]: curdate = datetime(2009,2,17,19,10,2,tzinfo=gmt5)
In [221]: curdate.tzinfo
Out[221]: <main.GMT5 object at 0x8a4b7cc>
In [222]:

请按照上面的代码将tzinfo属性分配给datetime对象:
1)创建一个tzinfo的子类
2)重载 tzname,utoffset,dst(Daylight Saving Time) 方法来提供该时区相对标准时区(GMT)的偏移量和dst(夏令时).由于curdate的tzinfo属性不为空,所以它是一个 timezone aware object,我们可以对它执行与时区有关的操作.下面是另一种给datetime对象分配时区的方法:

In [172]: curdate = datetime.now()
In [173]: curdate = curdate.replace(tzinfo=gmt5)
In [174]: curdate
Out[174]: datetime.datetime(2009, 2, 17, 17, 18, 27, 593447,tzinfo=<main.GMT5 object at 0x8a4b7cc>)
In [176]: curdate.utcoffset()
Out[176]: datetime.timedelta(0, 19800)

curdate.utcoffset这个方法返回的是时区与标准时区之间相差的秒数,这个方法一般用来初始化表示本地日期时间的naive datetime对象的当前时区.

从一个时区转换到另一个时区

假设我们要将GMT+5:30(印度)的时区的datetime转换到GMT-3:30的另一个时区对应的datetime,下面是转换的代码:

In [162]: class GMT5(tzinfo):
.....: def utcoffset(self,dt):
#51/2 hours ahead of GMT
.....: return timedelta(hours=5,minutes=30)
.....: def tzname(self,dt):
.....: return "GMT +5"
.....: def dst(self,dt):
.....: return timedelta(0)
In [171]: gmt5 = GMT5()
In [220]: curdate = datetime(2009,2,18,10,21,58,tzinfo=gmt5)
In [69]: curdate.strftime("%d %b %Y %I:%M:%S %p %Z")
Out[69]: '18 Feb 2009 10:21:58 AM GMT +5'
In [57]: class GMT3(tzinfo):
def utcoffset(self,dt):
#31/2 hours behind GMT
return timedelta(hours=-3,minutes=30)
def tzname(self,dt):
return "GMT -3"
def dst(self,dt):
return timedelta(0)
In [66]: gmt3 = GMT3()
In [67]: newdate = curdate.astimezone(gmt
3)
In [70]: newdate.strftime("%d %b %Y %I:%M:%S %p %Z")
Out[70]: '18 Feb 2009 02:21:58 AM GMT -3'

1.创建一个tzinfo对象表示GMT-3:30的时区
2.利用astimezome()函数将当前时区的 datetime(GMT+5:30)转换到(GMT+3:30)的时区对应的datetime 


TAG:

 

评分:0

我来说两句

日历

« 2024-03-28  
     12
3456789
10111213141516
17181920212223
24252627282930
31      

数据统计

  • 访问量: 142697
  • 日志数: 180
  • 图片数: 2
  • 文件数: 2
  • 书签数: 15
  • 建立时间: 2008-03-15
  • 更新时间: 2012-04-17

RSS订阅

Open Toolbar