Python Note 500 - Datetime#

:date: 2017-02-13
:modified: 2022-06-14
:slug: python-note-500-datetime
:tags: python, note, datetime
:category: Development
:author: Dormouse Young
:summary: Python note series 500 - datetime
[1]:
import datetime
import locale
import time

获取当前时间#

Python 标准库中的 datetime 模块提供了各种对日期和时间的处理方法。

[2]:
datetime.datetime.now()
[2]:
datetime.datetime(2022, 6, 14, 14, 52, 38, 957696)

时间与字符串互相转换#

[3]:
now = datetime.datetime.now()
print(now.strftime("%Y-%m-%d %H:%M:%S"))
str = 'Fri, 19 May 2017 10:50:42'
print(datetime.datetime.strptime(str, '%a, %d %b %Y %H:%M:%S'))
2022-06-14 14:52:39
2017-05-19 10:50:42

修改时间#

[4]:
now = datetime.datetime.now()
print(now)
print(now.replace(hour=0,minute=0,second=0))
2022-06-14 14:52:39.471768
2022-06-14 00:00:00.471768
[5]:
now - datetime.timedelta(days=1)
[5]:
datetime.datetime(2022, 6, 13, 14, 52, 39, 471768)

mktime#

[6]:
help(time.mktime)
Help on built-in function mktime in module time:

mktime(...)
    mktime(tuple) -> floating point number

    Convert a time tuple in local time to seconds since the Epoch.
    Note that mktime(gmtime(0)) will not generally return zero for most
    time zones; instead the returned value will either be equal to that
    of the timezone or altzone attributes on the time module.

[7]:
t = (2022, 6, 14, 14, 6, 38, 1, 48, 0)
secs = time.mktime(t)
print(secs)
1655186798.0
[8]:
time.localtime(secs)
[8]:
time.struct_time(tm_year=2022, tm_mon=6, tm_mday=14, tm_hour=14, tm_min=6, tm_sec=38, tm_wday=1, tm_yday=165, tm_isdst=0)
[9]:
time.asctime(time.localtime(secs))
[9]:
'Tue Jun 14 14:06:38 2022'

转义符说明:#

转义符

说明

%a

本地简化星期名称

%A

本地完整星期名称

%b

本地简化的月份名称

%B

本地完整的月份名称

%c

本地相应的日期表示和时间表示

%d

月内中的一天(0-31)

%H

24小时制小时数(0-23)

%I

12小时制小时数(01-12)

%j

年内的一天(001-366)

%m

月份(01-12)

%M

分钟数(00-59)

%p

本地A.M.或P.M.的等价符

%S

秒(00-59)

%U

一年中的星期数(00-53)星期天为星期的开始

%w

星期(0-6),星期天为星期的开始

%W

一年中的星期数(00-53)星期一为星期的开始

%x

本地相应的日期表示

%X

本地相应的时间表示

%y

两位数的年份表示(00-99)

%Y

四位数的年份表示(000-9999)

%Z

当前时区的名称

%%

%号本身

Locale 的问题#

在使用 strftime 和 strptime 时要注意 locale ,不同的 locale 打出来的是不一样的。同理,在使用 strptime 的时候也是如此,否则就会出错:

[10]:
now = datetime.datetime.now()
format_str = '%a, %d %b %Y %H:%M:%S'
locale.setlocale(locale.LC_ALL, ('zh_CN', 'UTF-8'))
[10]:
'zh_CN.UTF-8'
[11]:
now.strftime(format_str)
[11]:
'二, 14 6月 2022 14:52:41'
[12]:
locale.setlocale(locale.LC_ALL, ('en_US', 'UTF-8'))
[12]:
'en_US.UTF-8'
[13]:
now.strftime(format_str)
[13]:
'Tue, 14 Jun 2022 14:52:41'
[14]:
datetime.datetime.strptime('Fri, 19 May 2017 14:25:18', format_str)
[14]:
datetime.datetime(2017, 5, 19, 14, 25, 18)
[15]:
locale.setlocale(locale.LC_ALL, ('zh_CN', 'UTF-8'))
[15]:
'zh_CN.UTF-8'
[16]:
# datetime.datetime.strptime('Fri, 19 May 2017 14:25:18', format_str)
# 这句出错信息如下:
# ValueError: time data 'Fri, 19 May 2017 14:25:18' does not match format '%a, %d %b %Y %H:%M:%S'

时区转换#

[17]:
from pytz import timezone
[18]:
# 首先使用 datetime 中提供的 utcnow() 方法获取到当前UTC时间
utc_now = datetime.datetime.utcnow()
utc_now
[18]:
datetime.datetime(2022, 6, 14, 6, 52, 43, 36732)
[19]:
# 此时 tzinfo 为 None
print(utc_now.tzinfo)
None
[20]:
tzchina = timezone('Asia/Shanghai')
tzchina
[20]:
<DstTzInfo 'Asia/Shanghai' LMT+8:06:00 STD>
[21]:
utc = timezone('UTC')
utc_now.replace(tzinfo=utc).astimezone(tzchina)
[21]:
datetime.datetime(2022, 6, 14, 14, 52, 43, 36732, tzinfo=<DstTzInfo 'Asia/Shanghai' CST+8:00:00 STD>)

在 Django 中转换时区:

In [1]: from django.utils.timezone import utc

In [2]: from django.utils.timezone import localtime

In [3]: from datetime import datetime

In [4]: now = datetime.utcnow().replace(tzinfo=utc)

In [5]: now
Out[5]: datetime.datetime(2015, 5, 30, 3, 16, 57, 362481, tzinfo=<UTC>)

In [6]: localtime(now)
Out[7]: datetime.datetime(2015, 5, 30, 11, 16, 57, 362481, tzinfo=<DstTzInfo 'Asia/Shanghai' CST+8:00:00 STD>)

程序暂停#

函数原型: time.sleep(secs) ,secs 参数代表暂停的秒数。示例:

[22]:
import random
import time
random.seed()
time.sleep(random.random()*2)