wxPython官方文档中文翻译 - 日期和时间概述

72 阅读8分钟

官方文档:docs.wxpython.org/datetime_ov…

介绍

wxPython提供了一组功能强大的类来处理日期和时间。wx.DateTime类所支持的一些功能如下:

  • 范围广泛:所支持的日期范围大约从公元前4714年到未来约4.8亿年。
  • 精度:在任何地方都不使用浮点计算,这确保了日期计算不会出现舍入误差。
  • 功能多样:不仅支持所有常见的日期计算,还支持一些更为特殊的计算,比如星期和一年中第几天的计算、工作日检测、标准天文函数,以及与严格格式或自由格式字符串之间的相互转换。
  • 效率:wx.DateTime的对象占用空间小(8字节),并且对其进行操作的速度很快。

日期/时间相关类一览

与日期和时间相关的主要有3个类:除了表示时间中某个绝对时刻的wx.DateTime类本身之外,还有两个类 ——wx.TimeSpanwx.DateSpan,它们表示时间间隔。

日期时间的特点

wx.DateTime将时间存储为自 “纪元” 以来的有符号毫秒数。按照惯例,“纪元” 固定为1970年1月1日 ——不过,该类的使用者看不到这一点(特别是,早于 “纪元” 的日期与晚于 “纪元” 的日期处理方式并无二致)。但这确实意味着使用这个类能够达到的最高时间精度是1毫秒。

wx.DateTime对象的大小为8字节,因为它是用一个64位整数来表示的。因此,所支持日期的范围大约是5.8亿年,但由于目前在支持公历方面存在限制,仅支持从公元前4714年11月24日起的日期(如果有足够多的需求,这一点可能会改变)。

最后,其内部表示是与时区无关的(始终采用格林尼治标准时间),并且只有在将日期拆分为年/月/日各个组成部分时,时区才会起作用。有关时区的更多信息,请参阅下文(见“时区相关注意事项”)。

目前,唯一支持的日历是公历(即使对于在1582年10月15日这一公历在历史上首次被采用之前的日期,也使用公历,不过一般来说,这取决于具体的国家甚至地区)。未来的版本可能也会支持儒略历,并且不排除支持其他日历(如玛雅历、犹太历、农历…… )的可能性。

DateSpan和TimeSpan的区别

虽然在时间中表示一个绝对时刻只有一种逻辑方式(因此也只有一个wx.DateTime类),但描述一个时间间隔至少有两种方法。

首先,wx.TimeSpan实现了一种直接且不言自明的方式:它仅仅是两个时刻之间以毫秒为单位的差值。对wx.DateTime加上或减去这样一个时间间隔的操作,其定义总是明确的,并且是一种快速的运算。

但在日常生活中,还会使用其他依赖于日历的时间间隔表述方式。例如,“一个月后”这种说法就很常用。然而,很明显这和wx.TimeSpan所表示的60×60×24×31秒的时间间隔并不相同,因为“2月15日一个月后” 是3月15日,而不是3月17日或3月16日(这取决于当年是否为闰年)。

这就是为什么会有另一个用于表示此类时间间隔的类,名为wx.DateSpan。它以尽可能自然的方式处理这类操作,但请注意,对这种类型的时间间隔进行操作并不总是有明确的定义。例如,考虑一下 “1月31日 + ‘1个月’” 的情况:结果会是2月28日(或29日),也就是2月的最后一天,而不是并不存在的2月31日。当然,这通常正是人们想要的结果,但你可能仍会惊讶地发现,现在从2月28日减去同样的时间间隔,得到的结果会是1月28日,而不是我们最初的1月31日!

所以,除非你打算在程序中实现某种自然语言解析功能,否则你可能应该使用wx.TimeSpan而不是wx.DateSpanwx.TimeSpan也更高效)。然而,当你确实需要理解 “一个月后” 的含义时,wx.DateSpan可能会非常有用——当然,它的含义就是:

wx.DateTime.Now() + wx.DateSpan.Month()

日期算术运算

可以对日期执行许多不同的运算,但并非所有运算都有意义。例如,用一个数字乘以一个日期是无效的操作,尽管用一个数字乘以任意一个时间间隔类(wx.TimeSpanwx.DateSpan)是完全有效的。

以下是可以进行的操作:

  • 加法运算:可以将wx.TimeSpanwx.DateSpan加到wx.DateTime上,从而得到一个新的wx.DateTime对象。并且,两个相同间隔类(wx.TimeSpanwx.DateSpan)的对象也可以相加,得到另一个相同类的对象。
  • 减法运算:允许进行与上述加法类似类型的操作。此外,还可以计算两个wx.DateTime对象之间的差值,这将得到一个wx.TimeSpan对象。
  • 乘法运算wx.TimeSpanwx.DateSpan对象可以与一个整数相乘,得到一个相同类型的对象。
  • 一元取负运算:最后,wx.TimeSpanwx.DateSpan对象可以进行取负操作,得到一个大小相同但时间方向相反的时间间隔。

对于所有这些运算,都有相应的全局(重载)运算符,同时也有与之同义的成员函数:Add()Subtract()Multiply() 。一元取负运算以及复合赋值运算(如+=)仅作为成员函数实现,而Neg() 是一元取负运算的同义函数。

时区相关注意事项

尽管时间在内部总是以格林尼治标准时间(GMT)存储,但你通常会在本地时区进行操作。正因如此,所有接受拆分后日期值的wx.DateTime构造函数和设置函数都假定这些值是属于本地时区的。因此:

wx.DateTimeFromDMY(1, wx.DateTime.Jan, 1970)

以上示例,除非你恰好住在英国,否则它将与wx.DateTime的纪元时间不对应。所有返回日期组成部分(年、月、日、时、分、秒……)的方法,默认情况下也会返回本地时区的正确值。所以,一般来说,按常规方式操作会得到自然且正确的结果。

如果你只想做到这一点,那么你可以放心地跳过本节的其余内容。不过,如果你想处理不同的时区问题,那你应该把这部分内容读完。

在这种(罕见的)情况下,在构造wx.DateTime对象时,你仍然局限于本地时区,也就是说,没有办法构造出一个对应于(比如说)太平洋标准时间下给定日期的wx.DateTime对象。要做到这一点,你将需要调用wx.DateTime.ToTimezonewx.DateTime.MakeTimezone方法,以便针对目标时区来调整日期。对于最常见的情况(即需要在协调世界时(UTC)下构造日期),也有这些函数的特殊版本,即wx.DateTime.ToUTCwx.DateTime.MakeUTC

你也可以直接检索某个时区的值,而无需先将对象转换为该时区的值。为此,你可以将“时区”参数传递给任何受时区影响的方法(例如,所有获取日期组成部分的方法以及日期格式化方法)。特别是,Format() 系列方法接受一个“时区”参数,这使得可以轻松地以任何时区来打印时间。

要了解如何做到这一点,最后需要解决的问题是如何构造一个必须传递给所有这些方法的时区(TimeZone)对象。首先,你可以通过指定与格林尼治标准时间(GMT)相差的秒数来手动构造它,但通常你只需使用日期和时间相关的方法之一,然后让转换构造函数来完成这项工作。

也就是说,你只需这样写:

dt = wx.DateTimeFromDMY(8, wx.DateTime.May, 1977)
print("The time is %s in local time zone" % dt.FormatTime())
print("The time is %s in GMT" % dt.FormatTime(wx.DateTime.GMT))

夏令时(DST)

夏令时(也称为“夏季时间”)的处理一直是一项棘手的任务,最好将其交给操作系统来处理,因为操作系统应由管理员进行正确配置。不幸的是,当在标准库所支持的范围之外对日期进行计算时,我们就不得不自己来处理这些问题了。

系统提供了几个函数,用于计算给定年份中夏令时的开始和结束时间,以及判断在给定时刻夏令时是否生效。但这些函数不应被视为绝对正确,因为首先,它们仅仅针对少数几个国家而言,或多或少能正确运行(非常欢迎提供关于其他国家的任何信息!),并且即使对于这些国家,相关规则在未来也极有可能发生变化。

时区处理方法(请参阅“时区相关注意事项”)也会使用这些函数,所以它们也存在同样的局限性。

日期时间与节假日

TODO:编写此文档段落。