python的时间及相互转换

前几天搞了下时间各种格式之间的转换,记录一下。

Python表示时间主要有两个库,分别是time和datetime。time模块更接近于操作系统,所以其属性也是和Unix timestamp相关比较多。比如其能表示的年份为1970-2038。因为时间戳含义就是从1970-1-1到现在的秒数,用int类型表示,int类型为32bit,表示范围是[-2^31+1 ~2^31-1],即[-2147483648, 2147483648],换成成年大概68年,所以最大有效期为1970+68=2038。

如果想用更大的年份,最好用datetime。其最大年份可以用datetime.MAXYEAR查看,为9999。

time模块介绍

1. struct_time类。此类就是一个完整时间的元组,共有9个元素。如果调用time模块的其他函数,如gmtime(),localtime()和strptime(),那么返回的就是一个struct_time对象,9个元素分别为:

属性
tm_year(年)如2019
tm_mon(月)如11
tm_mday(日)如31,每个月的日有区别
tm_hour(小时)0-23
tm_min(分)0-59
tm_sec(秒)0-59
tm_wday(周几)0-6(0为周日)
tm_yday(一年中的第几天)1-365
tm_isdst(是否夏令时)默认为-1

2. time.time() 获取当前时间的时间戳

3. time.localtime() 将时间戳转化为struct_time格式,时区为当前时区

4. time.gmtime() 将时间戳转化为UTC时间的struct_time

5. time.mktime() 将struck_time转化为时间戳

6. time.sleep() 睡眠时间,单位是秒

7.time.asctime() 将struct_time表示为这种形式"Fri Nov 08 14:47:02 2019"。默认以time.localtime()为参数

8. print time.ctime() 将时间戳表示为这种形式"Fri Nov 08 14:47:02 2019"。默认以time.time()为参数

9. time.strftime(format[,t]) 将时间元组struct_time转化为format格式的字符串, 如果t没有指定,那么默认以time.localtime()为时间。时间格式为:

时间格式含义
%a本地(locale)简化星期名称
%A本地完整星期名称
%b本地简化月份名称
%B本地完整月份名称
%c本地相应的日期和时间表示
%d一个月中的第几天(01 - 31)
%H一天中的第几个小时(24小时制,00 - 23)
%I第几个小时(12小时制,01 - 12)
%j一年中的第几天(001 - 366)
%m月份(01 - 12)
%M分钟数(00 - 59)
%p本地am或者pm的相应符
%S秒(01 - 61)
%U一年中的星期数。(00 - 53星期天是一个星期的开始。)第一个星期天之前的所有天数都放在第0周。
%w一个星期中的第几天(0 - 6,0是星期天)
%W和%U基本相同,不同的是%W以星期一为一个星期的开始。
%x本地相应日期
%X本地相应时间
%y去掉世纪的年份(00 - 99)
%Y完整的年份
%Z时区的名字(如果不存在为空字符)
%%‘%’字符

如:time.strptime('%Y-%m-%d %H:%M:%S', time.localtime())

注:

“%p”只有与“%I”配合使用才有效果。

当使用strptime()函数时,只有当在这年中的周数和天数被确定的时候%U和%W才会被计算。

10. time.strptime() 于time.strftime()相反,这个函数将字符串时间转化为时间元组struct_time。

如: time.strptime('2019-10-18 16:04:36', '%Y-%m-%d %H:%M:%S')

三者关系如图:

datetime模块介绍

datetime功能相比time更加丰富,模块下又包含了几个类:

类名功能说明
date日期对象
time时间对象
datetime日期时间对象
datetime_CAPI日期时间对象C语言接口
timedelta时间间隔,即两个时间点之间的长度
tzinfo时区信息对象

1. date

date类基本元素由年月日组成。可以通过datetime.date.max和datetime.date.min查看其表示的范围

1) 构造函数datetime。可以这样搞

d = datetime.date(2019,8,7)
print d

打印2019-08-07,注意的是这个2019-08-07并不是字符串,而是datetime类的对象

2) datetime.date.today() 返回当前日期,如:

datetime.date.today()
Out[217]: datetime.date(2019, 11, 8)

3)datetime.date.fromtimestamp() 根据给定的时间戳,返回一个date对象, 如:

datetime.date.fromtimestamp(1569895835)
Out[218]: datetime.date(2019, 10, 1)

4) datetime.date.weekday() 参数是一个datetime对象,返回今天是一周的第几天,从周一(0)开始算

t = datetime.date.today()  //今天是周五
datetime.date.weekday(t)
Out[221]: 4

5) datetime.date.isoweekday() 以date对象为参数,返回今天是周几,周一返回1,周二返回2...

t = datetime.date.today()  //今天是周五
datetime.date.isoweekday(t)
Out[223]: 5

6) datetime.date.isocalendar() 以date对象为参数,返回一个元组,包括年,今天是本年第几周,今天是星期几

t = datetime.date.today()  //今天是2019.11.8
datetime.date.isocalendar(t)
Out[224]: (2019, 45, 5)

7) datetime.date.strftime(format) 参数为格式化的字符串,比如'%Y-%m-%d %H:%M:%S',返回值是一个字符串

d = datetime.date(2019,8,7)
format = '%Y-%m-%d %H:%M:%S'
print d.strftime(format)

8)datetime.date.replace() 参数为要替换的新值,返回替换后的datetime对象

d = datetime.date(2019,8,7)
format = '%Y-%m-%d %H:%M:%S'
d1 = d.replace(2018)
print d1.strftime(format)  //2018-08-07 00:00:00
d1 = d.replace(month=5)
print d1.strftime(format)  //2019-05-07 00:00:00 

9) datetime.date.year month day 输出当前datatime对象的年月日

d = datetime.date(2019,8,7)
print d.year, d.month, d.day  //2019 8 7

也可以通过getattribute方法来获取属性值:

d = datetime.date(2019,1,1)
print d.__getattribute__('year'), d.__getattribute__('month'), d.__getattribute__('day')

10) datetime.date.isoformat() 返回yyyy-mm-dd格式的字符串

print datetime.date(2019,8,7).isoformat()  //2019-08-07

11) datetime.date.timetuple()  返回time模块的struct_time格式元组

d = datetime.date(2019,8,7)
print d.timetuple() // time.struct_time(tm_year=2019, tm_mon=8, tm_mday=7, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=2, tm_yday=219, tm_isdst=-1)

12) datetime.date.toordinal() 返回公元元历(1年1月1日)开始到现在的天数。

d = datetime.date(2019,1,1)
print d.toordinal()  //737060。不知道它怎么算的,如果1年1月1日是1,那么2019.1.1和这个日期相差了2018 * 365 天,结果应该是736570而不是737060,理解有问题

13) datetime.date.fromordinal() toordinal的相反操作,传入一个天数,返回日期

d = datetime.date(2019,1,1)
a = d.toordinal()
print datetime.date.fromordinal(a)

14)日期的比较,例子如下:

d1 = datetime.date(2019,1,1)
d2 = datetime.date(2019,1,2)
d3 = datetime.date(2019,1,1)
print d1.__ge__(d3)  //True
print d1.__gt__(d2)  //False
print d1.__eq__(d2)  //False
print d1.__eq__(d3)  //True
print d1.__le__(d2)  //True 
print d2.__lt__(d3)  //False

15) 能表示的最大和最小值min(),max()

print datetime.date.min  //0001-01-01
print datetime.date.max  //9999-12-31

16) 能表示的最小单位datetime.date.resolution

print datetime.date.resolution  //1 day, 0:00:00

2. time

datetime.date类最小单位为天,datetime.time类为毫秒

time类由小时,分钟,秒,微妙和tzinfo组成。类似的,其构造函数为:

time([hour[, minute[, second[, microsecond[, tzinfo]]]]])

1) datetime.time(15,23,45,368) 返回值为time类的对象

datetime.time(hour=15,minute=23,second=45,microsecond=36800) //结果为15:23:45.036800

2) 获取time对象的属性值

d = datetime.time(hour=15,minute=23,second=45,microsecond=36800)
print d.hour,d.minute,d.second,d.microsecond,d.tzname() //输出结果为15 23 45 36800 None

与datetime.date类似,也可以通过getattribute方法获取, 如:

d = datetime.time(hour=15,minute=23,second=45,microsecond=36800)
print d.__getattribute__('hour'), d.__getattribute__('minute'), d.__getattribute__('second'), d.__getattribute__('microsecond')

3) 按照格式转为为字符串对象datetime.time.strftime('%H:%M:%S')

d = datetime.time(hour=15,minute=23,second=45,microsecond=36800)
print d.strftime('%H:%M:%S')

4)查看时区信息d.tzname()

d.tzname()

5) 替换某个时间datetime.time.replace(),与date类似

d = datetime.time(hour=15,minute=23,second=45,microsecond=36800)
print d.strftime('%H:%M:%S')
d1 = d.replace(hour=19)  
print d1  //19:23:45.036800
d1 = d.replace(minute=35)  
print d1  //15:35:45.036800
d1 = d.replace(second=36)
print d1  //15:23:36.036800
d1 = d.replace(microsecond=66000)
print d1  //15:23:45.066000

6) datetime.date.isoformat() 返回'%H:%M:%S'格式的字符串

d = datetime.time(hour=15,minute=23,second=45,microsecond=36800)
print d.isoformat()  //15:23:45.036800

7) 最大最小值min, max

print datetime.time.min  //00:00:00
print datetime.time.max  //23:59:59.999999

8) 能表示的最小单位datetime.time.resolution

print datetime.time.resolution  //0:00:00.000001

3. datetime

datetime.datetime类是date类和time类的合体,函数的类型和含义都很类似,只是相较于date或者time进行了扩充。比如说datetime类的构造函数:

datetime(self, year, month, day, hour=None, minute=None, second=None, microsecond=None, tzinfo=None)

1) datetime.resolution 能表示的最小时间单位

d = datetime.datetime(2019,11,11,16,33,24,666000,)
print d.resolution  //0:00:00.000001

2) datetime.date() 获取表示日期的部分

d = datetime.datetime(2019,11,11,16,33,24,666000,)
print d.date() //2019-11-11

3) datetime.time() 获取表示时间的部分:

d = datetime.datetime(2019,11,11,16,33,24,666000,)
print d.time()

4)datetime.isoformat() 返回iso格式时间串

d = datetime.datetime(2019,11,11,16,33,24,666000,)
print d.isoformat()  //2019-11-11T16:33:24.666000

5) datetime.utcfromtimestamp(timestamp) 参数为时间戳,返回值为datetime对象

print datetime.utcfromtimestamp(time.time()) //返回utc时间2019-11-12 08:04:54.660000,当前时间为2019-11-12 16:04:54

6)datetime.replace 用法date和time

7)datetime.strftime() 将datetime时间格式化为字符串

d = datetime.datetime(2019,11,11,16,33,24,666000,)
print d.strftime('%Y-%m-%d %H:%M:%S') //2019-11-11 16:33:24

8) datetime.strptime() 参数为时间字符串,和时间格式,返回datetime对象

print datetime.datetime.strptime('2019-3-26 7:18:16', format) //2019-03-26 07:18:16

9) datetime.timetuple() 将datetime对象转化为time模块的struct_time

d = datetime.datetime(2019,11,11,16,33,24,666000,)
print d.timetuple() //time.struct_time(tm_year=2019, tm_mon=11, tm_mday=11, tm_hour=16, tm_min=33, tm_sec=24, tm_wday=0, tm_yday=315, tm_isdst=-1)

10) datetime.today() 获取今天的时间,返回值为datetime对象

print datetime.datetime.today() //2019-11-12 11:43:35.904000

11) datetime.weekday(),fromordinal(), toordinal(), isoweekday(), isocalendar() 同date

12) datetime.utcnow() 返回当前标准时区的时间对象

print datetime.datetime.utcnow() //返回值为2019-11-12 03:52:00.943000;当前北京时间为2019-11-12 11:52:00.943000

13)可以通过datetime.year/month/day/hour/minute/second/microsecond 来获取datetime对象的具体某个时间值:

d = datetime.datetime(2019,11,11,16,33,24,666000,)
print d.month, d.hour, d.second

14) datetime.fromtimestamp() 参数为timestamp, 返回datetime对象

datetime.datetime.fromtimestamp(time.time()) //返回2019-11-12 16:06:16.437000,即当前时间

15)datetime.ctime() 同date类

16)datetime.astimezone() 传入参数是一个timezone,根据时区设置,返回datetime对象。需要注意的是,转化前的datetime是需要有时区信息才可以的。

d = datetime.datetime(2019,11,11,16,33,24,666000,tzinfo=UTC(8))
print d.astimezone(UTC(7)) //2019-11-11 15:33:24.666000+07:00, 此处UTC是一个自己创建的类,详见tzinfo章节

17)datetime.combine() 将date和time组合成datetime对象

a1 = datetime.date(2019,1,1)
d1 = datetime.time(hour=15,minute=23,second=45,microsecond=36800)
datetime.datetime.combine(a1, d1) //2019-01-01 15:23:45.036800

18) datetime.now() 返回当前时间的datetime对象(带时区)

print datetime.datetime.now() //2019-11-12 17:22:00.501000

19) datetime.tzname(),datetime.utcoffset, datetime.dst() 见tzinfo

20) datetime.utctimetuple() 创建utc时间的time模块的struct_time结构

d = datetime.datetime(2019,11,11,16,33,24,666000,tzinfo=UTC(8))
print d.utctimetuple()

21) 类似于date模块,datetime模块也可以用__gt__等进行比较

d = datetime.datetime(2019,11,11,16,33,24,666000,tzinfo=UTC(8))
d1 = datetime.datetime(2019,11,12,16,33,24,666000,tzinfo=UTC(8))
print d1.__gt__(d)  //返回True

3. timedelta类

timedelta类用来进行日期时间的运算,最大单位是天,最小单位是微妙。其构造函数为:

datetime.timedelta(days=0, seconds=0, microseconds=0,milliseconds=0, minutes=0, hours=0, weeks=0)

1) timedelta的使用

timedelta中参数的值分为正负,正值为加,负值为减。比如先创建了一个datetime对象d

d = datetime.datetime(2019,11,11,16,33,24,666000,tzinfo=UTC(8))

如果要计算时间d之后一天,一小时,一分钟,一秒,一毫秒和一微妙后的时间是多少就可以这么做:

d = datetime.datetime(2019,11,11,16,33,24,666000,tzinfo=UTC(8))
print d + datetime.timedelta(days=-1,hours=1,minutes=1,seconds=1,microseconds=1,milliseconds=1) //2019-11-10 17:34:25.667001+08:00

2) timedelta.days 返回timedelta有多少整天,不包含小时和分钟, 如:

td = datetime.timedelta(days=13,hours=2,minutes=3,seconds=1,microseconds=1,milliseconds=1)
print td.days //返回13

4. tzinfo

tzinfo类是一个虚拟类,如果要使用的话,需要创建一个子类,并实现相关方法。需要重写的方法有name(),utcoffset(),dst()这三个方法。

class UTC(tzinfo):
    """UTC"""
    def __init__(self,offset = 0):
        self._offset = offset

    def utcoffset(self, dt):
        return timedelta(hours=self._offset)

    def tzname(self, dt):
        return "UTC+%s" % self._offset

    def dst(self, dt):
        return timedelta(hours=self._offset)

创建一个北京时间的datetime

d = datetime.datetime(2019,11,11,16,33,24,666000,tzinfo=UTC(8))
print d.tzname(), d.utcoffset(), d.dst()  #打印结果:UTC+8 8:00:00 8:00:00

需要注意的是,tzinfo是要和datetime一起使用的,如果直接创建一个UTC对象,打印tzname需要同时传入一个datetime对象才可以,看定义就比较明白了。

如果不想自己实现tzinfo,可以用现成的库pytz

pytz中可以直接通过pytz.timezone()获取一个对象,比如要获取上海的,可以是:

pytz.timezone('Asia/Shanghai')

5. 实用举例

1. 获取Linux时间戳

1) 获取当前时间的时间戳

print time.time()

2)获取特定时间的时间戳

d = datetime.datetime(2019,11,11,16,33,24,666000,tzinfo=pytz.UTC)
print time.mktime(d.timetuple())  #1573461204.0

或者这样

timeStr = '2019-10-01 10:10:35'  //指定一个时间
timearray = time.strptime(timeStr, '%Y-%m-%d %H:%M:%S') //将时间按照格式转化为time.struct_time格式
print timestemp = time.mktime(timearray)  //生成时间戳1569895835.0

廖雪峰老师的网站上有一种方法是调用

>>> dt = datetime(2015, 4, 19, 12, 20) # 用指定日期时间创建datetime
>>> dt.timestamp() # 把datetime转换为timestamp

但是这种方法我这边没有不成功,可能是库不对

2. 获取时间字符串

1) 利用time模块获取当前时间字符串

format = '%Y-%m-%d %H:%M:%S'
print time.strftime(format)

这种方法利用了strftime默认以time.localtime()为第二个参数,获取当前时间

2) 利用datetime模块获取当前时间字符串

format = '%Y-%m-%d %H:%M:%S'
dt = datetime.datetime.now()
print dt.strftime(format)

datetime.now()返回的是datetime对象,再利用strftime转化为字符串

3)将timestamp转化为时间字符串

print datetime.datetime.fromtimestamp(timestamp)

也可以利用time模块转化为字符串格式

format = '%Y-%m-%d %H:%M:%S'
timestamp = 1573461204
print time.strftime(format, time.localtime(timestamp))

4)时区转化

有一点需要明确,就是timestamp是和时区没有关系的,就是说,无论哪个时区,时间确定了,那么时间戳就是固定的。

首先定义一下epoch time,对于格林威治时间,epoch time就是1970年01月01日00时00分00秒,对于北京时间就是1970年01月01日08时00分00秒

如果现在是北京时间2019-11-29 15:00:00,北京时间属于UTC+8时区,那么此时,UTC+0时区的时间就是2019-11-29 07:00:00。此时北京时间的时间戳为2019-11-29 15:00:00 - 1970-1-1 08:00:00的秒数,UTC+0时间的时间戳为2019-11-29 07:00:00 - 1970-1-1 07:00:00的秒数,二者是相等的

反过来,对于一个给定的timestamp,对于不同的时区,就是不同的时间,因为不同的时间epoch time就是不同的了

a. 可以通过datetime的函数astimezone转化

dt = datetime.datetime.now().replace(tzinfo=pytz.timezone('Asia/Shanghai'))
print dt   #print 2019-11-29 15:34:49.802000+08:06
print dt.astimezone(pytz.timezone('UTC')) #print 2019-11-29 07:28:49.802000+00:00
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值