Python日期、时间处理

在数据处理以前其他一些日常工作中经常需要对时间序列进行操作,在Python中也有time、datetime等模块可以进行时间的获取、转换等操作。其中time 大多数功能是依赖系统的C语言库函数实现,因此在不同的系统环境下效果或许会有所差异[1]。如在Ubuntu19中time.gmtime()可以获取的时间区间远大于在Windows10中的时间区间。datetime与time时间处理功能相近...

在数据处理以前其他一些日常工作中经常需要对时间序列进行操作,在Python中也有time、datetime等模块可以进行时间的获取、转换等操作。其中time 大多数功能是依赖系统的C语言库函数实现,因此在不同的系统环境下效果或许会有所差异[1]。如在Ubuntu19中time.gmtime()可以获取的时间区间远大于在Windows10中的时间区间。datetimetime时间处理功能相近,但较为高级,通用性更好。

python中时间日期格式化符号:

  • %y 两位数的年份表示(00-99)
  • %Y 四位数的年份表示(000-9999)
  • %m 月份(01-12)
  • %d 月内中的一天(0-31)
  • %H 24进制小时数(0-23)
  • %I 12进制小时数(01-12)
  • %M 分钟数(00=59)
  • %S 秒(00-59)
  • %a 本地简化星期名称
  • %A 本地完整星期名称
  • %b 本地简化的月份名称
  • %B 本地完整的月份名称
  • %c 本地相应的日期表示和时间表示
  • %j 年积日(001-366)
  • %p 本地A.M.或P.M.的等价符
  • %U 一年中的星期数(00-53)星期天为星期的开始
  • %w 星期(0-6),星期天为星期的开始
  • %W 一年中的星期数(00-53)星期一为星期的开始
  • %x 本地相应的日期表示
  • %X 本地相应的时间表示
  • %Z 当前时区的名称
  • %z 当前时区与UTC/GMT的偏移量,如'+0800'
  • %% %号本身

time

很多Python函数用一个时间元组(struct_time)处理时间,其包含9组数字:

序号 字段
0 tm_year(年) 4位数年, 如: 2020
1 tm_mon(月) 1 到 12
2 tm_mday(日) 1到31
3 tm_hour(小时) 0到23
4 tm_min(分钟) 0到59
5 tm_sec(秒) 0到61 (60或61 是闰秒)
6 tm_wday(周积日) 0到6 (0是周一)
7 tm_yday(年积日) 1到366 (儒略历)
8 tm_isdst夏令时 0, 1, -1 夏令时的标识, 分别指否、是、未知(默认)

如:time.struct_time(tm_year=3001, tm_mon=1, tm_mday=19, tm_hour=21, tm_min=55, tm_sec=0, tm_wday=0, tm_yday=19, tm_isdst=0)

  1. 获取时间戳
    time.time()获取以为单位的当前时刻的时间戳, 在Unix或类Unix中时间戳是从GMT 1970-1-1 0:0:0(epoch time)开始计算的,且不包含闰秒。time.time_ns()ns为单位的时间戳。

时间戳(timestamp),一个能表示一份数据在某个特定时间之前已经存在的、 完整的、 可验证的数据,通常是一个字符序列,唯一地标识某一刻的时间。

  1. 将时间戳与时间元组转换(获取当前时间)
    time.gmtime([seconds]):将从纪元开始以秒表示的时间转换为UTC格式的时间元组,其中dst(夏时令)标志始终为零。参数为空时获取当前时刻的GMT(UTC)时间元组。 time.localtime([seconds]) :类私gmtime, 其将秒数转换为本地时刻。参数为空时获取当前时刻的本地(如: UTC +8)时间元组。 time.mktime(tuple):将时间元组(struct_time)或普通9元素元组(tuple)转换为秒数(时间戳)。

  2. 获取格式化的时间
    time.asctime([t]): 将时间元组(struct_time)或普通9元素元组(tuple)转换字符串。当参数为空时为当前时间。
    time.ctime([secs]): 将秒数转换为字符串。当参数为空时为当前时间。 time.strftime(format[, t]): 将元组或时间元组转换为指定格式的时间字符串,t为空为当前时间。 time.strptime(string[, format]): 时间字符串转换为时间元组,默认格式'%a %b %d %H:%M:%S %Y',

    time.asctime()
    # 'Thu Apr  9 01:32:22 2019'
    tt=(2319, 4, 9, 1, 32, 22, 3, 100,0)
    time.asctime(tt)
    # 'Thu Apr  9 01:32:22 2319'
       
    time.ctime()
    Thu Apr  9 01:33:22 2019'
       
    time.strftime('%Y-%m-%d')
    # 2019-4-9
       
     time.strptime('04/09/20','%x') # 会自动填充缺失的时间
     # time.struct_time(tm_year=2020, tm_mon=4, tm_mday=9, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=100, tm_isdst=-1)
    
  3. 其他
    time.sleep([secs]): 在给定的秒数内暂停调用线程的执行。
    time.perf_counter(): 返回系统运行的精准时间。
    time.process_time(): 返回进程运行的精准时间。
    time.altzone: 获取本地DST(Daylight Saving Time, 夏时令)时区偏移量,UTC以西为正。
    time.daylight: 夏时令标识,如果定义了DST时区,则为非零。
    time.timezone: 无夏时令的时区偏移量,以秒为单位, time.tzname: 时区信息二元元组,第一个为无夏时令时区,第二个是包含夏时令的时区。 时区常数

datetime

datetime模块包含以下六个类:

说明 属性
datetime 同时具有时间、日期信息 year, month, day, hour, minute, second, microsecond, tzinfo
time 时间信息,假设每天均24*60*60秒。 hour, minute, second, microsecond, tzinfo
date 日期信息 year, month, day
timedelta 计算时间、日期差  
tzinfo 时区信息  
timezone Python3.2之后  

datetimedatetime

date类用来表示年、月、日,datetime.date(year, month, day),、 时间区间及精度由date.min, date.max, date.resolution定义。
time类用于表示时、分、秒、微秒、时区等datetime.time(hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0),时间区间及精度由time.min, time.max, time.resolution定义。time可以比较大小(时间的先后),对aware时间(具有时区tzinfo)与naive时间(没有时区tzinfo)比较大小会报错。 datetiem类包含了datetime的信息datetime.datetime(year, month, day, hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0),区间及精度由datetime.min, datetime.max, datetime.resolution定义。datetime继承了datetime的属性及方法。

创建date, time, datetime对象

# 1. 构造函数
t = datetime.time(12,3,2,tzinfo=datetime.timezone.utc)
d = datetime.date(2020,1,1)
dt = datetime.datetime(2019,2,3,12,3)

# 2. 在Python3.7之后的版本,可以根据字符串 fromisoformat(date_string), 默认本地时间
# 时间字符串格式:`HH[:MM[:SS[.fff[fff]]]][+HH:MM[:SS[.ffffff]]]`
# 日期字符串格式:``YYYY-MM-DD`
# 日期时间字符串格式:`YYYY-MM-DD[*HH[:MM[:SS[.fff[fff]]]][+HH:MM[:SS[.ffffff]]]]`
t1 = datetime.time.fromisoformat('02:02:01')
d1 = datetime.date.fromisoformat('2019-12-01')
td1 = datetime.datetime.fromisoformat('2019-12-01 02:02+08:00')

# 3. date, datetime还可以使用today(),fromtimestamp(),fromordinal(),fromisocalendar()方法
d2 = datetime.date.today() #返回本地时间
td2 = datetime.datetime.today()
# fromtimestamp(timestamp) 返回给定时间戳对应的本地时间
ts=time.time()
d3 = datetime.date.fromtimestamp(ts) #仅保留日期
td3 = datetime.datetime.fromtimestamp(ts)
# fromordinal(ordinal)  ordinal指从1年1日起的累积天数,1年1日为第1天
d4 = datetime.date.fromordinal(5000)
dt4 = datetime.datetime.fromordinal(5000) # 时、分为0,其后的值为None
# dt4 = datetime.datetime(14, 9, 9, 0, 0)
# fromisocalendar(year, week, day) # 类似fromordinal,其参数为年,年内周数,周内天数,**Python3.8新增**
d5 = datetime.date.fromisocalendar(1,2,3)
dt5 = datetime.datetime.fromisocalendar(1,2,3)

# 4. datetime独有的方法
# datetime.now(tz=None) 返回当前时刻本地的日期时间,tz=None时,同today(),否则
# datetime.utcnow()
# datetime.utcfromtimestamp(timestamp)
datetime.combine(date, time, tzinfo=self.tzinfo) # tzinfo参数Python3.6之后可用
datetime.strptime(date_string, format)

修改date, time, datetime对象 使用replace()方法,传入对应参数即可,三种类型可接收的参数如下:

time.replace(hour=self.hour, minute=self.minute, second=self.second, microsecond=self.microsecond, tzinfo=self.tzinfo, * fold=0)
date.replace(year=self.year, month=self.month, day=self.day)
datetime.replace(year=self.year, month=self.month, day=self.day, hour=self.hour, minute=self.minute, second=self.second, microsecond=self.microsecond, tzinfo=self.tzinfo, * fold=0)

转换为字符串

# 转换为格式化字符串isoformat(),strftime(format),三种类型均支持
t = datetime.time(12, 3, 2, tzinfo=datetime.timezone.utc)
d = datetime.date(2019, 9, 9)
dt = datetime.datetime(2019, 2, 3, 12, 3)
# 转换为 ISO 8601格式
# `YYYY-MM-DD[*HH[:MM[:SS[.fff[fff]]]][+HH:MM[:SS[.ffffff]]]]`
t.isoformat()  # '12:03:02+00:00'
d.isoformat()  # '2019-09-09'
dt.isoformat() # '2019-02-03T12:03:00'
# 转换为指定字符串,如
dt.strftime('%Y年%M月%d日') # '2019年03月03日' 
#在win系统上可能会出现中文编码问题。

# date, datetime还可以通过ctime()方法转换为本地化的字符串
dt.ctime() # 'Sun Feb  3 12:03:00 2019'
d.ctime()  # 'Mon Sep  9 00:00:00 2019'

中文编码问题解决方法

其他形式转换date,datetime支持

# 转换为时间元组
d.timetuple()
# time.struct_time(tm_year=2019, tm_mon=9, tm_mday=9, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=0, tm_yday=252, tm_isdst=-1)
dt.timetuple()
# time.struct_time(tm_year=2019, tm_mon=2, tm_mday=3, tm_hour=12, tm_min=3, tm_sec=0, tm_wday=6, tm_yday=34, tm_isdst=-1)


# toordinal() 转换为自1年1日起的天数
# weekday()   以整数形式返回星期几,其中星期一为0,星期日为6。
# isoweekday() 以整数形式返回星期几,其中星期一为1,星期日为7。
# isocalendar() 返回一个3元素元组(年, 年内周数, 星期几)(ISO year, ISO week number, ISO weekday)

# datetime转为时间戳
datetime.timestamp()

tzinfotimezone

tzinfo是一个抽象基类,用于秒数时区信息,timezone类是tzinfo的一个子类。 实例化timezone类(设置时区信息)

offset = datetime.timedelta(hours=3)
tz=datetime.timezone(offset,name='test') # UTC+3,名为test的时区
dt = datetime.datetime.now(tz=tz)
# dt = datetime.datetime(2018, 9, 11, 15, 8, 52, 467755, tzinfo=datetime.timezone(datetime.timedelta(seconds=10800), 'test'))
dt.utcoffset() # datetime.timedelta(seconds=10800) 
dt.astimezone() # 将dt转换为本地时间, 如果指定tz参数,转换到指定时区的时间
# datetime.datetime(2020, 4, 10, 20, 8, 52, 467755, tzinfo=datetime.timezone(datetime.timedelta(seconds=28800), '中国标准时间'))
dt.date() # 返回dt的日期
dt.time() # 返回dt的时间,没有tzinfo
dt.timetz() # 返回dt的时间,有tzinfo

时间差timedelta

timedelta对象表示持续时间datetime.timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0)

# 最小值
datetime.timedelta.min
# datetime.timedelta(days=-999999999)
# 最大值
datetime.timedelta.max
# datetime.timedelta(days=999999999, seconds=86399, microseconds=999999)
# 精度
datetime.timedelta.resolution
datetime.timedelta(microseconds=1)
dur=datetime.timedelta(hours=2)
dur.total_seconds() # dur的秒数

支持+, -, *, /, //, %, divmod, abs()运算以及str()

其他时间相关模块:
locale: 时间格式设置等功能
calendar: 日历相关功能

参考Python3 日期和时间 | 菜鸟教程
time — Time access and conversions — Python 3.8.2 documentation
datetime — Basic date and time types — Python 3.8.2 documentation