日期和时间管理
对于如何在 Gambas 中正确使用
Date 数据类型 ,所有用户(不仅仅是新手)都存在很多困惑。
此页面将尝试弄清它。
日期不是字符串
混乱主要来自这样一个事实:您正在通过使用区域设置字符串表示形式来考虑日期,就好像日期数据类型代表区域设置日期一样。在这里就错了!
内部表达方式
在内部,Gambas 使用两个 32 位整数存储日期值:
-
第一个整数是自起点以来的天数,起点为过去的特定时刻。这是 日期 部分。一天应该正好是 86,400 秒,这是一个近似值。
-
第二个整数是与该天数相加的毫秒数。这是 时间 部分。
换句话说,Gambas 日期/时间 值是一个完完全全的时间戳。
绝对时间的概念是一种实用的计算选择。
Gambas 在内部如何存储其日期数据类型并不重要
您必须清楚地记住重要的事情: Gambas Dates不是通常意义上的日期,而是瞬间,即~时间点~。
但是Gambas中没有办法直接写一个Date常量。您始终必须使用
Date
构建日期的函数或使用
CStr
,
CDate
,
Str$
或
Val
转换字符串表示的日期形式。
因此,每次您操作日期表达式时,Gambas 都必须决定您的日期表示是 U.T.C.时间还是本地时间。换句话说,与日期表示关联的时区是隐式的。
这有点像字符串字符集的问题:字符串的字符集是隐式的。它不与字符串一起存储。
Gambas 函数假设日期表示为:
-
在 U.T.C.中,使用美式日期格式
-
在本地时中,时区由 System.TimeZone 属性指定,该时区直接来自当前系统配置。日期格式为本地日期格式。
时区取决于系统中的配置和你将日期转换为字符串时的实际时间(时区可能会在一年中发生变化,或者由于突然的政治决定而变化)。日期格式取决于
System.Language 属性指定的当前语言。
自从 3.18
从Gambas 3.18,时区可以在日期字符串表示中明确指定。
语法为:
<Old date string representation> <space> [ UTC | GMT ] [ + | - ] HH [ :MM ]
以下是与日期相关的函数列表,以及它们是否涉及U.T.C.或当地时间。
处理 U.T.C. 和美式日期格式的函数
解释器在进行隐式数据类型转换时使用这些函数。
处理当地时间的函数
隐式转换
当心日期和字符串之间的隐式转换!
CStr
和
CDate
是互逆操作. 意味着
CStr(CDate(SomeString)) = SomeString
and
CDate(CStr(SomeDate)) = SomeDate
永远为真。
日期是数字
日期和时间值隐式转换为浮点数,其整数部分是内部日期部分(自起点以来的天数),小数部分是内部时间部分。
因此,您可以使用标准
+
和
-
运算符轻松地在日期之间进行日算术运算。
目前,起始时刻是 UTC 时间的午夜。
因此,如果您的时区不为空,
CFloat(Date(Now))
则不会返回整数!
空日期和仅时间日期
仅时间日期是日期和时间值,其中仅日期部分为零。在这种特殊情况下,不考虑时区。当您想要对时间进行算术运算时,这非常有用。
空日期是日期和时间部分均为零的日期和时间值。它们相当于常数NULL。使用空日期进行算术会引发错误。
日期存储
以可靠的方式存储日期的唯一方法是使用 UTC 表示形式。切勿用本地时间表示形式存储日期!或者至少始终使用相同的时区。
将日期存储在二进制文件中
您必须使用
WRITE 和
READ 指令与
As Date
语法一起使用。
这样您就可以将日期值的 UTC 内部表示直接写入文件中。
请注意,内部表示可能会发生变化,因此您通常不应假设二进制值将来具有相同的含义。
但如果内部表示发生变化,READ 和 WRITE 将被修改为向后兼容,因此您最终可以假设 READ 读取出的二进制值将保持不变。
在文本文件中存储日期
您必须使用
CStr
和
CDate
函数写入和读取日期值的 UTC 字符串表示形式。
您也可以使用
CFloat
日期值,将内部日期时间戳存储为浮点值。它也可以工作,但可读性较差。
否则,您可以使用任何自定义表示(例如 Unix 时间戳),前提是它是相对 UTC 绝对时间的恒定偏移。
日期和日历
对于仅日期表示的具体问题,请参阅
日期和日历.