日期/时间类型输入都是使用下列过程进行解码的。
把输入字符串分解为一个个记号,然后把每个记号分成字符串、时间、时区、数字几类:
如果一个数字记号包含一个冒号(:),那么这是一个时间字符串。包括随后所有的数据位和冒号。
如果这个数字记号包含一个划线(-)、斜杠(/)、多个点(.),那么它就是一个日期字符串,可能有一个文本月份。如果一个日期记号已经看过,那么将被解析为时区名(比如 America/New_York)。
如果这个记号只是数字,那么它要么是一个单独的字段,要么是一个 ISO8601 连接的日期(比如 19990113 是 1999 年 1 月 13 日)或者是连接的时间(比如 141516 是 14:15:16)。
如果记号以一个加号(+)或减号(-)开头,那么它要么是一个时区,要么就是一个特殊的字段。
如果记号是一个文本字符串,那么和可能的字符串进行匹配:
把这个记号当作时区缩写进行二分查找。
如果没有找到,再做一次二分表查找,看看这个记号是特殊字符串(比如 today)、日期(比如 Thursday)、月份(比如 January),还是一个无关痛痒的字(比如 at, on)。
如果还没有找到,抛出一个错误。
如果记号是一个数字或者数字字段:
如果有八位或者六位数字,而且前面也没有读到其它日期字段,那么就解释成一个"连接的日期"(比如 19990118 或 990118)。这里的解析是 YYYYMMDD 或 YYMMDD 。
如果记号是三位数字,并且已经解码了一个年份,那么解释成年日。
如果已经读取了四和六位数字,并且已经读取了一个年份,那么就解析成时间(HHMM 或 HHMMSS)。
如果是三位或更多位并且还没有找到日期字段,则解析成一个年份(这个解析强制剩余的日期字段的顺序为 yy-mm-dd)。
那么解析成某一天。否则,日期字段的顺序被认为是尊循 DateStyle 设置:mm-dd-yy, dd-mm-yy, yy-mm-dd 之一。如果发现月份或者日期字段超出范围,则抛出一个错误。
如果声明了 BC 则对年份取其负数并加一,用于内部保存。因为在格里高利历法里没有零年,所以数字上的 1BC 是公元零年。
如果没有声明 BC 并且年份字段有两个数据位的长度,那么把年份调整为 4 位。如果该字段小于 70 那么加 2000 ;否则加 1900 。
【提示】格里高利年份 AD 1-99 可以用前导零的方式使用 4 位数字(也就是说 0099 是 AD 99)。