ZetCode

PyQt5 日期和时间

最后修改于 2023 年 10 月 18 日

PyQt5 教程的这一部分展示了如何在 PyQt5 中使用日期和时间。

QDate, QTime, QDateTime

PyQt5 有 QDate, QDateTime, QTime 类来处理日期和时间。QDate 是一个用于处理公历日期的类。它有用于确定日期、比较或操作日期的方法。QTime 类用于处理时钟时间。它提供了用于比较时间、确定时间和各种其他时间操作的方法。QDateTime 是一个将 QDateQTime 对象组合成一个对象的类。

当前日期和时间

PyQt5 有 currentDate, currentTimecurrentDateTime 方法来确定当前日期和时间。

current_date_time.py
#!/usr/bin/python

from PyQt5.QtCore import QDate, QTime, QDateTime, Qt

now = QDate.currentDate()

print(now.toString(Qt.ISODate))
print(now.toString(Qt.DefaultLocaleLongDate))

datetime = QDateTime.currentDateTime()

print(datetime.toString())

time = QTime.currentTime()

print(time.toString(Qt.DefaultLocaleLongDate))

该示例以各种格式打印当前日期、日期和时间以及时间。

now = QDate.currentDate()

currentDate 方法返回当前日期。

print(now.toString(Qt.ISODate))
print(now.toString(Qt.DefaultLocaleLongDate))

通过将值 Qt.ISODateQt.DefaultLocaleLongDate 传递给 toString 方法,以两种不同的格式打印日期。

datetime = QDateTime.currentDateTime()

currentDateTime 返回当前日期和时间。

time = QTime.currentTime()

最后,currentTime 方法返回当前时间。

$ ./current_date_time.py 
2020-05-16
Saturday, May 16, 2020
Sat May 16 09:53:37 2020
9:53:37 AM CEST

这是输出。

UTC 时间

我们的星球是一个球体;它围绕其轴旋转。地球向东旋转,因此太阳在不同地点以不同时间升起。地球大约 24 小时旋转一圈。因此,世界被划分为 24 个时区。在每个时区,都有不同的当地时间。这种当地时间通常会因夏令时而进一步修改。

有一个全球时间的实际需要。一个全球时间有助于避免关于时区和夏令时的混淆。UTC(协调世界时)被选为主要的时间标准。UTC 用于航空、天气预报、飞行计划、空中交通管制许可和地图。与当地时间不同,UTC 不会随季节变化而变化。

utc_local.py
#!/usr/bin/python

from PyQt5.QtCore import QDateTime, Qt

now = QDateTime.currentDateTime()

print('Local datetime: ', now.toString(Qt.ISODate))
print('Universal datetime: ', now.toUTC().toString(Qt.ISODate))

print(f'The offset from UTC is: {now.offsetFromUtc()} seconds')

该示例确定当前的通用时间和当地日期和时间。

print('Local datetime: ', now.toString(Qt.ISODate))

currentDateTime 方法返回以当地时间表示的当前日期和时间。我们可以使用 toLocalTime 将通用时间转换为当地时间。

print('Universal datetime: ', now.toUTC().toString(Qt.ISODate))

我们使用日期时间对象的 toUTC 方法获取通用时间。

print(f'The offset from UTC is: {now.offsetFromUtc()} seconds')

offsetFromUtc 给出了通用时间和当地时间之间的时间差,以秒为单位。

$ ./utc_local.py 
Local datetime:  2020-05-16T09:56:23
Universal datetime:  2020-05-16T07:56:23Z
The offset from UTC is: 7200 seconds

这是输出。

天数

特定月份的天数由 daysInMonth 方法返回,一年中的天数由 daysInYear 方法返回。

n_of_days.py
#!/usr/bin/python

from PyQt5.QtCore import QDate, Qt

now = QDate.currentDate()

d = QDate(1945, 5, 7)

print(f'Days in month: {d.daysInMonth()}')
print(f'Days in year: {d.daysInYear()}')

该示例打印所选日期月份和年份中的天数。

$ ./n_of_days.py 
Days in month: 31
Days in year: 365

这是输出。

天数差

daysTo 方法返回从一个日期到另一个日期的天数。

xmas.py
#!/usr/bin/python

from PyQt5.QtCore import QDate

xmas1 = QDate(2019, 12, 24)
xmas2 = QDate(2020, 12, 24)

now = QDate.currentDate()

dayspassed = xmas1.daysTo(now)
print(f'{dayspassed} days have passed since last XMas')

nofdays = now.daysTo(xmas2)
print(f'There are {nofdays} days until next XMas')

该示例计算自上一个圣诞节以来经过的天数以及到下一个圣诞节的天数。

$ ./xmas.py 
144 days have passed since last XMas
There are 222 days until next XMas

这是输出。

日期时间算术

我们经常需要向日期时间值添加或减去天、秒或年。

arithmetic.py
#!/usr/bin/python

from PyQt5.QtCore import QDateTime, Qt

now = QDateTime.currentDateTime()

print(f'Today:', now.toString(Qt.ISODate))
print(f'Adding 12 days: {now.addDays(12).toString(Qt.ISODate)}')
print(f'Subtracting 22 days: {now.addDays(-22).toString(Qt.ISODate)}')

print(f'Adding 50 seconds: {now.addSecs(50).toString(Qt.ISODate)}')
print(f'Adding 3 months: {now.addMonths(3).toString(Qt.ISODate)}')
print(f'Adding 12 years: {now.addYears(12).toString(Qt.ISODate)}')

该示例确定当前日期时间并添加或减去天、秒、月和年。

$ ./arithmetic.py 
Today: 2020-05-16T10:11:56
Adding 12 days: 2020-05-28T10:11:56
Subtracting 22 days: 2020-04-24T10:11:56
Adding 50 seconds: 2020-05-16T10:12:46
Adding 3 months: 2020-08-16T10:11:56
Adding 12 years: 2032-05-16T10:11:56

这是示例输出。

夏令时

夏令时(DST)是在夏季将时钟拨快,以便傍晚日照时间更长的做法。在春季开始时时间向前调整一小时,在秋季向后调整为标准时间。

daylight_saving.py
#!/usr/bin/python

from PyQt5.QtCore import QDateTime, QTimeZone, Qt

now = QDateTime.currentDateTime()

print(f'Time zone: {now.timeZoneAbbreviation()}')

if now.isDaylightTime():
    print(f'The current date falls into DST time')
else:
    print(f'The current date does not fall into DST time')

该示例检查日期时间是否在夏令时。

print(f'Time zone: {now.timeZoneAbbreviation()}')

timeZoneAbbreviation 方法返回日期时间的时区缩写。

if now.isDaylightTime():
...

isDaylightTime 返回日期时间是否属于夏令时。

$ ./daylight_saving.py 
Time zone: CEST
The current date falls into DST time

当前日期属于夏令时 程序在布拉迪斯拉发执行,布拉迪斯拉发是中欧的一个城市,在夏季。中欧夏季时间 (CEST) 比通用时间早 2 小时。该时区是夏令时时区,用于欧洲和南极洲。标准时间,用于冬季,是中欧时间 (CET)。

Unix 纪元

纪元是选择作为特定时代起点的某个时刻。例如,在西方基督教国家,时间纪元从耶稣诞生的第 0 天开始。另一个例子是法国共和历,使用了十二年。纪元是共和时代的开始,该时代于 1792 年 9 月 22 日宣布,即第一共和国成立和君主制被废除的那天。

计算机也有它们的纪元。最流行的一个是 Unix 纪元。Unix 纪元是 1970 年 1 月 1 日(或 1970-01-01T00:00:00Z ISO 8601)的 UTC 时间 00:00:00。计算机中的日期和时间是根据自该计算机或平台定义的纪元以来经过的秒数或时钟滴答数来确定的。

Unix 时间 是自 Unix 纪元以来经过的秒数。

$ date +%s
1589617100

Unix date 命令可用于获取 Unix 时间。在这一刻,自 Unix 纪元以来已经过去了 1589617100 秒。

unix_time.py
#!/usr/bin/python3

from PyQt5.QtCore import QDateTime, Qt

now = QDateTime.currentDateTime()

unix_time = now.toSecsSinceEpoch() 
print(unix_time)

d = QDateTime.fromSecsSinceEpoch(unix_time)
print(d.toString(Qt.ISODate))

该示例打印 Unix 时间并将其转换回 QDateTime

now = QDateTime.currentDateTime()

首先,我们检索当前日期和时间。

unix_time = now.toSecsSinceEpoch() 

toSecsSinceEpoch 返回 Unix 时间。

d = QDateTime.fromSecsSinceEpoch(unix_time)

使用 fromSecsSinceEpoch 我们将 Unix 时间转换为 QDateTime

$ ./unix_time.py 
1589617144
2020-05-16T10:19:04

这是输出。

儒略日

儒略日是指自儒略期开始以来连续计算的天数。它主要由天文学家使用。它不应与儒略历混淆。儒略期始于公元前 4713 年。儒略日编号 0 被分配给公元前 4713 年 1 月 1 日中午开始的那一天。

儒略日 (JDN) 是自该时期开始以来经过的天数。任何时刻的儒略日期 (JD) 是前一个中午的儒略日编号加上自该时刻以来的一天中的分数。(Qt 不计算此分数。)除了天文学之外,儒略日期也经常被军事和大型机程序使用。

julian_day.py
#!/usr/bin/python

from PyQt5.QtCore import QDate, Qt

now = QDate.currentDate()

print('Gregorian date for today:', now.toString(Qt.ISODate))
print('Julian day for today:', now.toJulianDay()) 

在该示例中,我们计算今天的公历日期和儒略日。

print('Julian day for today:', now.toJulianDay())

使用 toJulianDay 方法返回儒略日。

$ ./julian_day.py 
Gregorian date for today: 2020-05-16
Julian day for today: 2458986

这是输出。

历史战役

使用儒略日可以进行跨越数个世纪的计算。

battles.py
#!/usr/bin/python

from PyQt5.QtCore import QDate, Qt

borodino_battle = QDate(1812, 9, 7)
slavkov_battle = QDate(1805, 12, 2)

now = QDate.currentDate()

j_today = now.toJulianDay()
j_borodino = borodino_battle.toJulianDay()
j_slavkov = slavkov_battle.toJulianDay()

d1 = j_today - j_slavkov
d2 = j_today - j_borodino

print(f'Days since Slavkov battle: {d1}')
print(f'Days since Borodino battle: {d2}')

该示例计算自两个历史事件以来经过的天数。

borodino_battle = QDate(1812, 9, 7)
slavkov_battle = QDate(1805, 12, 2)

我们有两个拿破仑时代的战役日期。

j_today = now.toJulianDay()
j_borodino = borodino_battle.toJulianDay()
j_slavkov = slavkov_battle.toJulianDay()

我们计算今天和斯劳科夫战役和博罗迪诺战役的儒略日。

d1 = j_today - j_slavkov
d2 = j_today - j_borodino

我们计算自这两场战役以来经过的天数。

$ ./battles.py 
Days since Slavkov battle: 78328
Days since Borodino battle: 75857

当我们运行此脚本时,自斯拉夫科夫战役以来已经过去了 78328 天,自博罗迪诺战役以来已经过去了 75857 天。

在本 PyQt5 教程中,我们使用了日期和时间。