Main Content

指定时区

在 MATLAB® 中,您可以为 datetime 数组指定时区。此示例说明如何创建和使用包含时区的日期时间数组。

时区是遵守统一标准时间的地理区域。时区包含了协调世界时 (UTC) 的时间偏移量、夏令时 (DST) 的时间偏移量以及对这些偏移量的一系列历史调整。为了设置时区和计算时区偏移量,datetime 数据类型使用由互联网号码分配局 (IANA) 在 IANA Time Zone Database 中提供的代码和数据。

显示和搜索时区表

要查看对 MATLAB 已知的完整时区表,请使用 timezones 函数。表中的每行都显示一个时区的名称、其地理区域、相对于 UTC 的偏移量以及相对于 DST 的偏移量。对于实行 DST 的时区,则根据这些时区的当前和历史规则应用 DST 偏移量。

AllTimeZones = timezones
AllTimeZones=457×4 table
             Name              Area     UTCOffset    DSTOffset
    ______________________    ______    _________    _________

    {'Africa/Abidjan'    }    Africa        0            0    
    {'Africa/Accra'      }    Africa        0            0    
    {'Africa/Addis_Ababa'}    Africa        3            0    
    {'Africa/Algiers'    }    Africa        1            0    
    {'Africa/Asmera'     }    Africa        3            0    
    {'Africa/Bamako'     }    Africa        0            0    
    {'Africa/Bangui'     }    Africa        1            0    
    {'Africa/Banjul'     }    Africa        0            0    
    {'Africa/Bissau'     }    Africa        0            0    
    {'Africa/Blantyre'   }    Africa        2            0    
    {'Africa/Brazzaville'}    Africa        1            0    
    {'Africa/Bujumbura'  }    Africa        2            0    
    {'Africa/Cairo'      }    Africa        2            1    
    {'Africa/Casablanca' }    Africa        0            1    
    {'Africa/Ceuta'      }    Africa        1            1    
    {'Africa/Conakry'    }    Africa        0            0    
      ⋮

要查看 MATLAB 使用的 IANA 时区数据库的版本,请返回 timezones 的第二个输出。

[~,DBversion] = timezones
DBversion = 
'2023c'

要查找时区的名称,您可以搜索时区表的 Name 变量。要在知道部分名称的情况下查找完整名称,可以使用 contains 函数。例如,查找与纽约对应的时区名称。在搜索字符串中用下划线替换空白字符。

TFindex = contains(AllTimeZones.Name,"New_York");
NewYorkZone = AllTimeZones.Name(TFindex)
NewYorkZone = 1x1 cell array
    {'America/New_York'}

显示时区表中对应的行。要匹配时区的确切名称,请使用 matches 函数。

TFindex = matches(AllTimeZones.Name,NewYorkZone);
AllTimeZones(TFindex,:)
ans=1×4 table
            Name             Area      UTCOffset    DSTOffset
    ____________________    _______    _________    _________

    {'America/New_York'}    America       -5            1    

创建带有时区的 datetime

每个 datetime 数组都有时区属性。默认情况下不设置此属性,这意味着生成的 datetime 数组未设置时区。您可以使用未设置时区的 datetime 数组进行本地时间计算,在这种情况下,您不需要考虑 DST 或其他时区的本地时间。

例如,为当前时间创建一个 datetime 值,并显示其 TimeZone 属性。当前日期和时间值来自您的系统时钟。如果没有时区,datetime 值就无法计算相对于 UTC 的时区偏移量。

D = datetime("now")
D = datetime
   07-Mar-2024 15:46:55

D.TimeZone
ans =

  0x0 empty char array

有两种方法可以设置 datetime 数组的时区。第一种方法是在创建 datetime 数组时指定 datetime 函数的 TimeZone 名称-值参量。指定此参量将设置 TimeZone 属性的值。

D = datetime("now",TimeZone="America/New_York")
D = datetime
   07-Mar-2024 15:46:55

D.TimeZone
ans = 
'America/New_York'

第二种方法是在创建 datetime 数组后为 TimeZone 属性赋值。

D = datetime("now")
D = datetime
   07-Mar-2024 15:46:55

D.TimeZone = "America/New_York"
D = datetime
   07-Mar-2024 15:46:55

您还可以将 TimeZone 属性指定为持续时间,该持续时间只是相对于 UTC 的固定时区偏移量。这种偏移不采用任何当前或历史偏移规则,例如夏令时。

例如,指定比 UTC 晚五个小时的时区偏移量。此偏移量与 America/New_York 的 UTC 偏移量相同,但不包括任何与夏令时相关的偏移量。

D = datetime("now",TimeZone="-05:00")
D = datetime
   07-Mar-2024 15:46:55

D.TimeZone
ans = 
'-05:00'

您可以将 TimeZone 指定为以下列表中的任何值:

  • "" - 没有时区

  • 时区名称 - IANA 时区数据库中的时区

  • +HH:mm-HH:mm 格式的时区偏移量 - 相对于 UTC 的固定偏移量

  • 时区偏移量为 duration 标量(从 R2024a 开始) - 相对于 UTC 的固定偏移量,使用 hoursminutessecondsduration 函数指定

  • "UTC" - 协调世界时

  • "UTCLeapSeconds" - 协调世界时,但也包含闰秒

  • "local" - 与系统时区对应的 IANA 时区

指定包含时区偏移量的格式

datetime 数组的默认格式不包括时区。但是,您可以使用 zZ 标识符在格式中包含时区偏移量。

例如,使用 z 更改格式以包括日期、时间和时区偏移量。z 标识符指定偏移量的本地化短版本。其行为取决于您的区域设置。

D = datetime("now", ...
             TimeZone="America/New_York", ...
             Format="dd-MMM-uuuu HH:mm:ss z")
D = datetime
   07-Mar-2024 15:46:55 EST

Z 标识符指定将偏移量显示为小时、分钟和秒(可选)的基本格式。

D.Format = "dd-MMM-uuuu HH:mm:ss Z"
D = datetime
   07-Mar-2024 15:46:55 -0500

您还可以指定 UTC 长格式。有关时区偏移量标识符的完整列表,请参阅datetime

D.Format = "dd-MMM-uuuu HH:mm:ss ZZZZ"
D = datetime
   07-Mar-2024 15:46:55 UTC-05:00

在不同时区对相同时间进行编码

如果您更改 datetime 值的时区,它仍会对相同的时间点进行编码。如果相对于 UTC 的偏移量发生了变化,则日期和时间值会以补偿偏移量变化的方式进行调整。

例如,在纽约时区中创建一个 datetime 值,并将其格式化为显示时区偏移量。

D = datetime("today", ...
             TimeZone="America/New_York", ...
             Format="dd-MMM-uuuu HH:mm:ss z")
D = datetime
   07-Mar-2024 00:00:00 EST

然后将其时区更改为洛杉矶时区。日期和时间值会发生变化,以便在不同时区对相同的时间点进行编码。

D.TimeZone = "America/Los_Angeles"
D = datetime
   06-Mar-2024 21:00:00 PST

比较不同时区的 datetime

如果比较具有不同时区的 datetime 值,则比较时会考虑时区偏移量。但是,您无法比较已设置时区和未设置时区的 datetime 数组,因为未设置时区的数组没有已知的时区偏移量。两个数组必须都已设置时区或都未设置时区。

例如,创建一个 datetime 值。然后复制它并更改其时区。

NYTime = datetime("today", ...
                  TimeZone="America/New_York", ...
                  Format="dd-MMM-uuuu HH:mm:ss z")
NYTime = datetime
   07-Mar-2024 00:00:00 EST

LATime = NYTime;
LATime.TimeZone = "America/Los_Angeles"
LATime = datetime
   06-Mar-2024 21:00:00 PST

使用 == 运算符比较这两个值。这些值是相等的,因为它们对相同的时间点进行编码。

AreTimesEqual = NYTime == LATime
AreTimesEqual = logical
   1

这两个时间没有实际差别。

TimeDiff = LATime - NYTime
TimeDiff = duration
   00:00:00

然后将洛杉矶时间增加两小时。

LATime = LATime + hours(2)
LATime = datetime
   06-Mar-2024 23:00:00 PST

比较两个时间。尽管有日期和时间值,但洛杉矶时间比纽约时间晚。

IsLATimeLater = LATime > NYTime
IsLATimeLater = logical
   1

时差是两个小时。

TimeDiff = LATime - NYTime
TimeDiff = duration
   02:00:00

串联具有不同时区的 datetime 数组

TimeZone 属性适用于 datetime 数组中的每个元素。但是,您可以串联具有不同时区的 datetime 数组。串联数组与第一个数组具有相同的时区。您无法串联已设置时区和未设置时区的 datetime 数组,因为未设置时区的数组没有已知的时区偏移量。两个数组必须都已设置时区或都未设置时区。

例如,串联 NYTimeLATime。结果会显示纽约的时区。

combinedNYZone = [NYTime LATime]
combinedNYZone = 1x2 datetime
   07-Mar-2024 00:00:00 EST   07-Mar-2024 02:00:00 EST

然后,以相反的顺序进行串联。结果便会显示洛杉矶的时区。

combinedLAZone = [LATime NYTime]
combinedLAZone = 1x2 datetime
   06-Mar-2024 23:00:00 PST   06-Mar-2024 21:00:00 PST

使用特殊时区考虑闰秒

闰秒是对 UTC 时间应用的加减一秒钟的调整。闰秒于 1972 年引入,以解释基于原子时钟的精确时间与观测到的太阳时间之间的差异,这种差异是由地球自转速度的微小变化而导致的。这些变化不会以可预测的模式出现,因此会根据需要声明闰秒。纳入 MATLAB 的闰秒数据是由国际地球自转和参考系统服务 (IERS) 提供的。有关详细信息,请参阅 IERS Bulletins

datetime 数据类型有将闰秒考虑在内的特殊时区。对于任何涉及闰秒的计算或比较,请将时区指定为 "UTCLeapSeconds"。根据 ISO 8601 标准,使用此时区时,默认格式包括日期、时间和表示 UTC 的字母 Z

todayLS = datetime("today",TimeZone="UTCLeapSeconds")
todayLS = datetime
   2024-03-07T00:00:00.000Z

对于 datetime 数组,如果一个数组有闰秒而另一个数组没有闰秒,则无法对这两个数组进行合并或比较。

查看闰秒影响的一种方法是计算 UTCUTCLeapSeconds 时区中今天的日期与 1972 年 1 月 1 日之间的时间长度。首先计算 UTC 时区的持续时间长度。持续时间长度以 hh:mm:ss 格式显示。

durationWithoutLS = datetime("today",TimeZone="UTC") - datetime(1972,1,1,TimeZone="UTC")
durationWithoutLS = duration
   457416:00:00

然后计算 UTCLeapSeconds 时区的持续时间长度。这两个持续时间的差异是 1972 年以来声明的闰秒累积效应造成的。

durationWithLS = datetime("today",TimeZone="UTCLeapSeconds") - datetime(1972,1,1,TimeZone="UTCLeapSeconds")
durationWithLS = duration
   457416:00:27

要查看对 MATLAB 已知的所有闰秒以及为它们声明的日期,请使用 leapseconds 函数。

LS = leapseconds
LS=27×2 timetable
       Date        Type    CumulativeAdjustment
    ___________    ____    ____________________

    30-Jun-1972     +              1 sec       
    31-Dec-1972     +              2 sec       
    31-Dec-1973     +              3 sec       
    31-Dec-1974     +              4 sec       
    31-Dec-1975     +              5 sec       
    31-Dec-1976     +              6 sec       
    31-Dec-1977     +              7 sec       
    31-Dec-1978     +              8 sec       
    31-Dec-1979     +              9 sec       
    30-Jun-1981     +             10 sec       
    30-Jun-1982     +             11 sec       
    30-Jun-1983     +             12 sec       
    30-Jun-1985     +             13 sec       
    31-Dec-1987     +             14 sec       
    31-Dec-1989     +             15 sec       
    31-Dec-1990     +             16 sec       
      ⋮

第二个输出返回 MATLAB 中使用的闰秒数据的 IERS 公告 C 版本号。

[~,LSvers] = leapseconds
LSvers = 66

另请参阅

| |

相关主题