[python]cook_book 第三章:数字日期和时间

发布时间:2024年01月21日

3.1 数字的四舍五入

问题: 对浮点数执行指定精度的舍入计算


round(1.234,1)
1.2

传给 round() 函数的 ndigits 参数可以是负数

a=1677731
round(a,-1)
1677730
round(a,-2)
1677700

只是简单的输出一定宽度的数,你不需要使用 round() 函数

x=1.234567
format(x,'0.2f')
'1.23'

不要试着去舍入浮点值来”修正”表面上看起来正确的问题

a=2.1
b=4.2
c=a+b
print(c)
c=round(c,2)
print(c)
6.300000000000001
6.3

3.2 执行精确的浮点数运算

3.1末尾的错误是因为:错误是由底层CPU和IEEE 754标准通过自己的浮点单位去执行算术时的特征
decimal 可以解决精度问题

from decimal import Decimal
a=Decimal('4.2')
b=Decimal('2.1')
print(a+b)
print((a+b)==Decimal('6.3'))
6.3
True

decimal 模块的一个主要特征是允许你控制计算的每一方面,包括数字位数和四舍五入运算。 为了这样做,你先得创建一个本地上下文并更改它的设置

from decimal import localcontext

a=Decimal('1.3')
b=Decimal('1.7')
print(a/b)
0.7647058823529411764705882353
with localcontext() as ctx:
    ctx.prec=3
    print(a/b)
0.765
with localcontext() as ctx:
    ctx.prec=50
    print(a/b)
0.76470588235294117647058823529411764705882352941176

注意下减法删除以及大数和小数的加分运算所带来的影响

减法删除以及大数和小数的加分运算所带来的影响。

nums = [1.23e+18, 1, -1.23e+18]
print(sum(nums))

import math
math.fsum(nums)
0.0





1.0

3.3 数字的格式化输出

x = 1234.56789
format(x,'0.2f')

'1234.57'
format(x,'>10.1f')
'    1234.6'
format(x,'')
'1234.56789'
format(x,'0,.1f')
'1,234.6'

需要根据地区来显示千位符,你需要自己去调查下 locale 模块中的函数了。 你同样也可以使用字符串的 translate() 方法来交换千位符

print(x)
swap_separator = {ord(','):',',ord(','):','}
format(x,',').translate(swap_separator)
1234.56789





'1,234.56789'

Python代码中会看到使用%来格式化数字的

print('%0.2f'%x)
print('%10.1f'%x)
print('%-10.1f'%x)
1234.57
    1234.6
1234.6    

3.4 二八十六进制整数

转换或者输出使用二进制,八进制或十六进制表示的整数

x=1234
print(bin(x))
print(oct(x))
print(hex(x))
0b10011010010
0o2322
0x4d2

使用format

print(format(x,'b'))
print(format(x,'o'))
print(format(x,'x'))


10011010010
2322
4d2

如果你想产生一个无符号值,你需要增加一个指示最大位长度的值。比如为了显示32位的值,可以像下面这样写

x=-1234
format(2**32+x,'b')
'11111111111111111111101100101110'
format(2**32+x,'x')
'fffffb2e'

为了以不同的进制转换整数字符串,简单的使用带有进制的 int() 函数即可

print(int('4d2',16))
1234
int('10011010010', 2)
1234

需确保八进制数的前缀是 0o ,就像下面这样

import os 
os.chmod('03.数字日期和时间.ipynb',0o755)

3.5 字节到大整数的打包与解包

你有一个字节字符串并想将它解压成一个整数。或者,你需要将一个大整数转换为一个字节字符串。

data = b'\x00\x124V\x00x\x90\xab\x00\xcd\xef\x01\x00#\x004'
print(len(data))

print(int.from_bytes(data,'little'))

print(int.from_bytes(data,'big'))

16
69120565665751139577663547927094891008
94522842520747284487117727783387188

struct 模块来解压字节,利用 struct 模块来解压对于整数的大小是有限制的

import struct
hi,lo =struct.unpack('>QQ',data)
print((hi << 64)+lo)
94522842520747284487117727783387188

字节顺序规则(little或big)仅仅指定了构建整数时的字节的低位高位排列方式。 我们从下面精心构造的16进制数的表示中可以很容易的看出来

x=0x01020304

a=x.to_bytes(4,'big')
print(a)
b=x.to_bytes(4,'little')
print(b)

b'\x01\x02\x03\x04'
b'\x04\x03\x02\x01'

使用 int.bit_length() 方法来决定需要多少字节位来存储这个值

x=523**25
print(x)
# print(x.to_bytes(16,'little')) 错误

print(x.bit_length())
nbytes,rem=divmod(x.bit_length(),8)
if rem:
    nbytes+=1
print(x.to_bytes(nbytes,'little'))

91736511638789819036289447786012918412485922047847900593029222702443
226
b'k\x1d?\xbf%\x146\xbbc-\xdaM\x05\xf1U\x0cLj\xd6\x87d*\xf6\xb9X\x1b\x17g\x03'

3.6 复数的数学运算

用使用函数 complex(real, imag) 或者是带有后缀j的浮点数来指定

a=complex(2,4)
b=3-5j
print(a)
print(b)
print(a.real)
print(a.conjugate()) # 复数的共轭

(2+4j)
(3-5j)
2.0
(2-4j)
print(a+b)
print(a*b)
print(a/b)
print(abs(a))
(5-1j)
(26+2j)
(-0.4117647058823529+0.6470588235294118j)
4.47213595499958

如果要执行其他的复数函数比如正弦、余弦或平方根,使用 cmath 模块

import numpy as np
a = np.array([2+3j, 4+5j, 6-7j, 8+9j])
print(a)

print(a+2)
print(np.sin(a))
[2.+3.j 4.+5.j 6.-7.j 8.+9.j]
[ 4.+3.j  6.+5.j  8.-7.j 10.+9.j]
[   9.15449915  -4.16890696j  -56.16227422 -48.50245524j
 -153.20827755-526.47684926j 4008.42651446-589.49948373j]
import math
print(math.sqrt(-1))
---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

/Users/allen/python/python_learn/book/python_cook/03第三章:数字日期和时间/03.数字日期和时间.ipynb Cell 59 line 2
      <a href='vscode-notebook-cell:/Users/allen/python/python_learn/book/python_cook/03%E7%AC%AC%E4%B8%89%E7%AB%A0%EF%BC%9A%E6%95%B0%E5%AD%97%E6%97%A5%E6%9C%9F%E5%92%8C%E6%97%B6%E9%97%B4/03.%E6%95%B0%E5%AD%97%E6%97%A5%E6%9C%9F%E5%92%8C%E6%97%B6%E9%97%B4.ipynb#Y112sZmlsZQ%3D%3D?line=0'>1</a> import math
----> <a href='vscode-notebook-cell:/Users/allen/python/python_learn/book/python_cook/03%E7%AC%AC%E4%B8%89%E7%AB%A0%EF%BC%9A%E6%95%B0%E5%AD%97%E6%97%A5%E6%9C%9F%E5%92%8C%E6%97%B6%E9%97%B4/03.%E6%95%B0%E5%AD%97%E6%97%A5%E6%9C%9F%E5%92%8C%E6%97%B6%E9%97%B4.ipynb#Y112sZmlsZQ%3D%3D?line=1'>2</a> print(math.sqrt(-1))


ValueError: math domain error
import cmath
cmath.sqrt(-1)
1j

3.7 无穷大与NaN

创建或测试正无穷、负无穷或NaN(非数字)的浮点数
Python并没有特殊的语法来表示这些特殊的浮点值,但是可以使用 float() 来创建它们

a=float('inf')
b=float('-inf')
c=float('nan')
print(a)
print(b)
print(c)
inf
-inf
nan

print(math.isinf(a))
print(math.isnan(c))
True
True

无穷大数在执行数学计算的时候会传播

a=float('inf')
print(a*10)
print(10/a)
inf
0.0

但是有些操作时未定义的并会返回一个NaN结果

a = float('inf')
print(a/a)
b=float('-inf')
print(b/b)
nan
nan

NaN值会在所有操作中传播,而不会产生异常

c=float('inf')
print(c+10)
print(c/2)
print(c*2)
print(math.sqrt(c))
inf
inf
inf
inf

NaN值的一个特别的地方时它们之间的比较操作总是返回False

c=float('inf')
d=float('inf')
print(c==d)
print(c is d)
True
False

3.8 分数运算

fractions 模块可以被用来执行包含分数的数学运算

from fractions import Fraction

a=Fraction(5,4)
b=Fraction(7,16)
print(a+b)
print(a*b)

c=a*b
print(c.numerator)
print(c.denominator)
# 分母不大于 8 的有理数
print(c.limit_denominator(8))
27/16
35/64
35
64
4/7
x = 3.75
y=Fraction(*x.as_integer_ratio())
print(y)
15/4

3.9 大型数组运算

x = [1, 2, 3, 4]
y = [5, 6, 7, 8]
print(x*2)
[1, 2, 3, 4, 1, 2, 3, 4]
print(x+10)
---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

/Users/allen/python/python_learn/book/python_cook/03第三章:数字日期和时间/03.数字日期和时间.ipynb Cell 79 line 1
----> <a href='vscode-notebook-cell:/Users/allen/python/python_learn/book/python_cook/03%E7%AC%AC%E4%B8%89%E7%AB%A0%EF%BC%9A%E6%95%B0%E5%AD%97%E6%97%A5%E6%9C%9F%E5%92%8C%E6%97%B6%E9%97%B4/03.%E6%95%B0%E5%AD%97%E6%97%A5%E6%9C%9F%E5%92%8C%E6%97%B6%E9%97%B4.ipynb#Y142sZmlsZQ%3D%3D?line=0'>1</a> print(x+10)


TypeError: can only concatenate list (not "int") to list

使用numpy

import numpy as np
ax = np.array([1, 2, 3, 4])
ay = np.array([5, 6, 7, 8])
print(ax * 2)
[2 4 6 8]
print(ax + 10)
[11 12 13 14]
ax + ay
array([ 6,  8, 10, 12])
ax * ay
array([ 5, 12, 21, 32])

NumPy 中的标量运算(比如 ax * 2 或 ax + 10 )会作用在每一个元素上
当两个操作数都是数组的时候执行元素对等位置计算,并最终生成一个新的数组

def f(x):
    return 3*x**2 - 2*x + 7

f(ax)
array([ 8, 15, 28, 47])

NumPy 还为数组操作提供了大量的通用函数

print(np.sqrt(ax))
print(np.cos(ax))
[1.         1.41421356 1.73205081 2.        ]
[ 0.54030231 -0.41614684 -0.9899925  -0.65364362]

NumPy 数组使用了C或者Fortran语言的机制分配内存。 也就是说,它们是一个非常大的连续的并由同类型数据组成的内存区域。 所以,你可以构造一个比普通Python列表大的多的数组

grid = np.zeros(shape=(10000,10000), dtype=float)
                
print(grid)
[[0. 0. 0. ... 0. 0. 0.]
 [0. 0. 0. ... 0. 0. 0.]
 [0. 0. 0. ... 0. 0. 0.]
 ...
 [0. 0. 0. ... 0. 0. 0.]
 [0. 0. 0. ... 0. 0. 0.]
 [0. 0. 0. ... 0. 0. 0.]]
print(grid+10)
[[10. 10. 10. ... 10. 10. 10.]
 [10. 10. 10. ... 10. 10. 10.]
 [10. 10. 10. ... 10. 10. 10.]
 ...
 [10. 10. 10. ... 10. 10. 10.]
 [10. 10. 10. ... 10. 10. 10.]
 [10. 10. 10. ... 10. 10. 10.]]
print(np.sin(grid))
[[0. 0. 0. ... 0. 0. 0.]
 [0. 0. 0. ... 0. 0. 0.]
 [0. 0. 0. ... 0. 0. 0.]
 ...
 [0. 0. 0. ... 0. 0. 0.]
 [0. 0. 0. ... 0. 0. 0.]
 [0. 0. 0. ... 0. 0. 0.]]

NumPy 有一点需要特别的主意,那就是它扩展Python列表的索引功能

a = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
print(a)
[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]
print(a[1])
[5 6 7 8]
print(a[:,1])
[ 2  6 10]
print(a[1:3,1:3])
[[ 6  7]
 [10 11]]
a[1:3,1:3]+=10
print(a)
[[ 1  2  3  4]
 [ 5 16 17  8]
 [ 9 20 21 12]]
 a + [100, 101, 102, 103]
array([[101, 103, 105, 107],
       [105, 117, 119, 111],
       [109, 121, 123, 115]])
a
array([[ 1,  2,  3,  4],
       [ 5, 16, 17,  8],
       [ 9, 20, 21, 12]])
np.where(a<10,a,10)
array([[ 1,  2,  3,  4],
       [ 5, 10, 10,  8],
       [ 9, 10, 10, 10]])

3.10 矩阵与线性代数运算

矩阵乘法、寻找行列式、求解线性方程组

import numpy as np

m = np.matrix([[1,-2,3],[0,4,5],[7,8,-9]])
print(m)
[[ 1 -2  3]
 [ 0  4  5]
 [ 7  8 -9]]

Return transpose 转秩矩阵

print(m.T)
[[ 1  0  7]
 [-2  4  8]
 [ 3  5 -9]]

Return inverse 逆矩阵

m.I
matrix([[ 0.33043478, -0.02608696,  0.09565217],
        [-0.15217391,  0.13043478,  0.02173913],
        [ 0.12173913,  0.09565217, -0.0173913 ]])
v = np.matrix([[2],[3],[4]])
v
matrix([[2],
        [3],
        [4]])
m*v
matrix([[ 8],
        [32],
        [ 2]])

numpy.linalg 子包中找到更多的操作函数

import numpy.linalg

在 NumPy 中,numpy.linalg.det(m) 是用于计算矩阵的行列式(determinant)的函数。行列式是一个与方阵相关的数值,它在线性代数中有重要的应用

numpy.linalg.det(m)
-229.99999999999983

numpy.linalg.eigvals(m) 是 NumPy 中用于计算矩阵的特征值(eigenvalues)的函数

numpy.linalg.eigvals(m)
array([-13.11474312,   2.75956154,   6.35518158])

3.11 随机选择

你想从一个序列中随机抽取若干元素,或者想生成几个随机数
random 模块有大量的函数用来产生随机数和随机选择元素

import random
values = [1, 2, 3, 4, 5, 6]
print(random.choice(values))
print(random.choice(values))
print(random.choice(values))
print(random.choice(values))

6
2
1
1

提取出N个不同元素的样本用来做进一步的操作,可以使用 random.sample()

random.sample(values,2)
[6, 4]

如果你仅仅只是想打乱序列中元素的顺序,可以使用 random.shuffle()

random.shuffle(values)
values
[5, 2, 3, 1, 6, 4]

生成随机整数,请使用 random.randint()

random.randint(0,10)
3

如果要获取N位随机位(二进制)的整数,使用 random.getrandbits()

random.getrandbits(200)
1177222575426771010267243972712940670953299157370511395411586

random.seed() 函数修改初始化种子

random.seed() # Seed based on system time or os.urandom()
random.seed(12345) # Seed based on integer given
random.seed(b'bytedata') # Seed based on byte data

3.12 基本的日期与时间转换

你需要执行简单的时间转换,比如天到秒,小时到分钟等的转换

timedelta 是 Python 中用于表示时间差的类。timedelta(days=2, hours=6) 创建了一个时间差对象 a,表示 2 天 6 小时的时间间隔。

timedelta(hours=4.5) 创建了另一个时间差对象 b,表示 4.5 小时的时间间隔。

通过将 a 和 b 相加,即 c = a + b,可以得到时间差的总和。在这种情况下,c 表示 a 和 b 的总时间间隔。
c.days 属性来获取。它返回 c 的天数部分,即整数值

from datetime import timedelta
a = timedelta(days=2, hours=6)
b = timedelta(hours=4.5)
c=a+b
print(c.days)
print(c.seconds)
print(c.seconds / 3600)
print( c.total_seconds() / 3600)
2
37800
10.5
58.5

表示指定的日期和时间,先创建一个 datetime 实例然后使用标准的数学运算来操作它们

from datetime import datetime
a=datetime(2012, 9, 23)
print(a)
print(a+timedelta(days=10))
2023-09-23 00:00:00
2023-10-03 00:00:00
a = datetime(2012, 9, 23)
b = datetime(2012, 12, 21)
d=b-a
print(d.days)
89
now = datetime.today()
print(now)
print(print(now + timedelta(minutes=10)))
2024-01-21 16:50:53.575745
2024-01-21 17:00:53.575745
None

datetime 会自动处理闰年

a=datetime(2021,3,1)
b=datetime(2021,2,28)
print(a-b)
print((a-b).days)
1 day, 0:00:00
1

如果你需要执行更加复杂的日期操作,比如处理时区,模糊时间范围,节假日计算等等, 可以考虑使用 dateutil模块
许多类似的时间计算可以使用 dateutil.relativedelta() 函数代替

a = datetime(2012, 9, 23)
print(a + timedelta(months=1))
---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

/Users/allen/python/python_learn/book/python_cook/03第三章:数字日期和时间/03.数字日期和时间.ipynb Cell 141 line 2
      <a href='vscode-notebook-cell:/Users/allen/python/python_learn/book/python_cook/03%E7%AC%AC%E4%B8%89%E7%AB%A0%EF%BC%9A%E6%95%B0%E5%AD%97%E6%97%A5%E6%9C%9F%E5%92%8C%E6%97%B6%E9%97%B4/03.%E6%95%B0%E5%AD%97%E6%97%A5%E6%9C%9F%E5%92%8C%E6%97%B6%E9%97%B4.ipynb#Y262sZmlsZQ%3D%3D?line=0'>1</a> a = datetime(2012, 9, 23)
----> <a href='vscode-notebook-cell:/Users/allen/python/python_learn/book/python_cook/03%E7%AC%AC%E4%B8%89%E7%AB%A0%EF%BC%9A%E6%95%B0%E5%AD%97%E6%97%A5%E6%9C%9F%E5%92%8C%E6%97%B6%E9%97%B4/03.%E6%95%B0%E5%AD%97%E6%97%A5%E6%9C%9F%E5%92%8C%E6%97%B6%E9%97%B4.ipynb#Y262sZmlsZQ%3D%3D?line=1'>2</a> print(a + timedelta(months=1))


TypeError: 'months' is an invalid keyword argument for __new__()
from datetime import datetime
from dateutil.relativedelta import relativedelta

a = datetime(2012, 9, 23)

print(a + relativedelta(month=+2))
print(a + relativedelta(months=+4))
2012-02-23 00:00:00
2013-01-23 00:00:00
b = datetime(2012, 12, 21)
print(b-a)
89 days, 0:00:00
d = relativedelta(b, a)
print(d)
d.months
d.days
relativedelta(months=+2, days=+28)





28

3.13 计算上一个周五的日期

通用方法来计算一周中某一天上一次出现的日期,例如上一个周五的日期

from datetime import datetime, timedelta

weekdays = ['Monday', 'Tuesday', 'Wednesday', 'Thursday',
            'Friday', 'Saturday', 'Sunday']

def get_previous_byday(dayname,start_date=None):
    if start_date is None:
        start_date=datetime.today()
    day_num=start_date.weekday()
    day_num_target=weekdays.index(dayname)
    days_ago=(7 + day_num - day_num_target) % 7
    if days_ago==0:  
        days_ago=7
    target_date=start_date-timedelta(days=days_ago)
    return target_date

datetime.today()
get_previous_byday('Monday')
datetime.datetime(2024, 1, 15, 17, 56, 29, 618435)
get_previous_byday('Tuesday')
datetime.datetime(2024, 1, 16, 17, 58, 13, 833150)
get_previous_byday('Friday')
datetime.datetime(2024, 1, 19, 17, 58, 21, 560064)
get_previous_byday('Sunday', datetime(2012, 12, 21))
datetime.datetime(2012, 12, 16, 0, 0)
from datetime import datetime
from dateutil.relativedelta import relativedelta
from dateutil.rrule import *
d = datetime.now()
print(d)
print(d + relativedelta(weekday=FR))
print(d + relativedelta(weekday=FR(-1)))
2024-01-21 17:59:35.152470
2024-01-26 17:59:35.152470
2024-01-19 17:59:35.152470

3.14 计算当前月份的日期范围

from datetime import datetime, date, timedelta
import calendar

def get_month_range(start_date=None):
    if start_date is None:
        start_date = date.today().replace(day=1)
    _, days_in_month = calendar.monthrange(start_date.year, start_date.month)
    end_date = start_date + timedelta(days=days_in_month)
    return (start_date, end_date)
a_day = timedelta(days=1)
first_day, last_day = get_month_range()
while first_day<last_day:
    print(first_day)
    first_day+=a_day
2024-01-01
2024-01-02
2024-01-03
2024-01-04
2024-01-05
2024-01-06
2024-01-07
2024-01-08
2024-01-09
2024-01-10
2024-01-11
2024-01-12
2024-01-13
2024-01-14
2024-01-15
2024-01-16
2024-01-17
2024-01-18
2024-01-19
2024-01-20
2024-01-21
2024-01-22
2024-01-23
2024-01-24
2024-01-25
2024-01-26
2024-01-27
2024-01-28
2024-01-29
2024-01-30
2024-01-31
def date_range(start,stop,step):
    while start<stop:
        yield start
        start=start+step

for d in date_range(datetime(2012, 9, 1), datetime(2012,10,1),timedelta(hours=6)):
    print(d)
2012-09-01 00:00:00
2012-09-01 06:00:00
2012-09-01 12:00:00
2012-09-01 18:00:00
2012-09-02 00:00:00
2012-09-02 06:00:00
2012-09-02 12:00:00
2012-09-02 18:00:00
2012-09-03 00:00:00
2012-09-03 06:00:00
2012-09-03 12:00:00
2012-09-03 18:00:00
2012-09-04 00:00:00
2012-09-04 06:00:00
2012-09-04 12:00:00
2012-09-04 18:00:00
2012-09-05 00:00:00
2012-09-05 06:00:00
2012-09-05 12:00:00
2012-09-05 18:00:00
2012-09-06 00:00:00
2012-09-06 06:00:00
2012-09-06 12:00:00
2012-09-06 18:00:00
2012-09-07 00:00:00
2012-09-07 06:00:00
2012-09-07 12:00:00
2012-09-07 18:00:00
2012-09-08 00:00:00
2012-09-08 06:00:00
2012-09-08 12:00:00
2012-09-08 18:00:00
2012-09-09 00:00:00
2012-09-09 06:00:00
2012-09-09 12:00:00
2012-09-09 18:00:00
2012-09-10 00:00:00
2012-09-10 06:00:00
2012-09-10 12:00:00
2012-09-10 18:00:00
2012-09-11 00:00:00
2012-09-11 06:00:00
2012-09-11 12:00:00
2012-09-11 18:00:00
2012-09-12 00:00:00
2012-09-12 06:00:00
2012-09-12 12:00:00
2012-09-12 18:00:00
2012-09-13 00:00:00
2012-09-13 06:00:00
2012-09-13 12:00:00
2012-09-13 18:00:00
2012-09-14 00:00:00
2012-09-14 06:00:00
2012-09-14 12:00:00
2012-09-14 18:00:00
2012-09-15 00:00:00
2012-09-15 06:00:00
2012-09-15 12:00:00
2012-09-15 18:00:00
2012-09-16 00:00:00
2012-09-16 06:00:00
2012-09-16 12:00:00
2012-09-16 18:00:00
2012-09-17 00:00:00
2012-09-17 06:00:00
2012-09-17 12:00:00
2012-09-17 18:00:00
2012-09-18 00:00:00
2012-09-18 06:00:00
2012-09-18 12:00:00
2012-09-18 18:00:00
2012-09-19 00:00:00
2012-09-19 06:00:00
2012-09-19 12:00:00
2012-09-19 18:00:00
2012-09-20 00:00:00
2012-09-20 06:00:00
2012-09-20 12:00:00
2012-09-20 18:00:00
2012-09-21 00:00:00
2012-09-21 06:00:00
2012-09-21 12:00:00
2012-09-21 18:00:00
2012-09-22 00:00:00
2012-09-22 06:00:00
2012-09-22 12:00:00
2012-09-22 18:00:00
2012-09-23 00:00:00
2012-09-23 06:00:00
2012-09-23 12:00:00
2012-09-23 18:00:00
2012-09-24 00:00:00
2012-09-24 06:00:00
2012-09-24 12:00:00
2012-09-24 18:00:00
2012-09-25 00:00:00
2012-09-25 06:00:00
2012-09-25 12:00:00
2012-09-25 18:00:00
2012-09-26 00:00:00
2012-09-26 06:00:00
2012-09-26 12:00:00
2012-09-26 18:00:00
2012-09-27 00:00:00
2012-09-27 06:00:00
2012-09-27 12:00:00
2012-09-27 18:00:00
2012-09-28 00:00:00
2012-09-28 06:00:00
2012-09-28 12:00:00
2012-09-28 18:00:00
2012-09-29 00:00:00
2012-09-29 06:00:00
2012-09-29 12:00:00
2012-09-29 18:00:00
2012-09-30 00:00:00
2012-09-30 06:00:00
2012-09-30 12:00:00
2012-09-30 18:00:00

3.15 字符串转换为日期

但是你想将它们转换为 datetime 对象以便在上面执行非字符串操作

from datetime import datetime
text = '2012-09-20'
y = datetime.strptime(text, '%Y-%m-%d')
z = datetime.now()
diff = z - y
diff
datetime.timedelta(days=4140, seconds=66629, microseconds=767044)

datetime.strptime() 方法支持很多的格式化代码, 比如 %Y 代表4位数年份, %m 代表两位数月份

nice_z = datetime.strftime(z, '%A %B %d, %Y')
nice_z
'Sunday January 21, 2024'

下边的这个函数比 datetime.strptime() 快7倍多

from datetime import datetime
def parse_ymd(s):
    year_s, mon_s, day_s = s.split('-')
    return datetime(int(year_s), int(mon_s), int(day_s))

3.16 结合时区的日期操作

from datetime import datetime

from pytz import timezone


d = datetime(2012, 12, 21, 9, 30, 0)
print(d)

central = timezone('US/Central')
loc_d = central.localize(d)
print(loc_d)
2012-12-21 09:30:00
2012-12-21 09:30:00-06:00

日期被本地化了, 它就可以转换为其他时区的时间

bang_d = loc_d.astimezone(timezone('Asia/Kolkata'))
print(bang_d)
2012-12-21 21:00:00+05:30
d = datetime(2013, 3, 10, 1, 45)
loc_d = central.localize(d)
print(loc_d)
later = loc_d + timedelta(minutes=30)
print(later)
2013-03-10 01:45:00-06:00
2013-03-10 02:15:00-06:00
from datetime import timedelta
later = central.normalize(loc_d + timedelta(minutes=30))
print(later)
2013-03-10 03:15:00-05:00
import pytz
print(loc_d)
utc_d = loc_d.astimezone(pytz.utc)
print(utc_d)
2013-03-10 01:45:00-06:00
2013-03-10 07:45:00+00:00
later_utc = utc_d + timedelta(minutes=30)
print(later_utc.astimezone(central))
2013-03-10 03:15:00-05:00
pytz.country_timezones['IN']
['Asia/Kolkata']
文章来源:https://blog.csdn.net/weixin_38805083/article/details/135733163
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。