首页 > 后端开发 > Python教程 > 时区、偏移量和 ObjectScript,天哪!

时区、偏移量和 ObjectScript,天哪!

Patricia Arquette
发布: 2025-01-01 13:06:13
原创
785 人浏览过

您的使命

让我们假设您是一名国际行动间谍,一生致力于保护世界人民免受危险。 您收到以下任务:

美好的一天,特工 IRIS,

我们很抱歉打扰您在巴哈马的假期,但我们刚刚收到伦敦代理的消息,一颗“定时炸弹”将在洛杉矶人口稠密的地区引爆。 我们的消息来源称,“定时炸弹”将于今天下午 3:14 触发。

快点,人们指望着你!

问题

你赶紧站起来,准备前往洛杉矶,但你很快意识到你错过了一条关键信息; “定时炸弹”会在巴哈马时间下午 3:14 或洛杉矶时间下午 3:14 触发吗? ...或者甚至可能是伦敦时间下午 3:14。

您很快意识到,为您提供的时间(下午 3:14)并没有为您提供足够的信息来确定您何时需要到达洛杉矶。

为您提供的时间(下午 3:14)不明确。 您需要更多信息来确定准确时间。

一些解决方案

当您思考这个问题时,您意识到有一些方法可以克服为您提供的时间的模糊性:

  1. 您的消息来源可能提供了当地时间下午 3:14 的位置。 例如,洛杉矶、巴哈马或伦敦。

  2. 您的消息来源可以使用 UTC(协调世界时)等标准来为您提供与商定位置(例如伦敦格林威治)的偏移量。

幸福的结局

您致电消息来源并确认所提供的时间确实是洛杉矶时间下午 3:14。 您可以前往洛杉矶,在下午3:14之前解除“定时炸弹”,并迅速返回巴哈马结束您的假期。

要点

那么,这个思维练习的意义是什么? 我怀疑我们中的任何人都会遇到上述问题,但如果您使用将数据从一个位置移动到另一个位置的应用程序或代码(特别是如果这些位置位于不同时区),您需要注意 如何处理日期时间和时区。

时区很难!

嗯,时区并没有那么糟糕。 夏令时和政治边界使时区变得困难。

我以为我一直理解时区的“一般”概念:地球按时区分成垂直的切片,每个时区比东部时区晚一小时。

Time Zones and Offsets and ObjectScript, Oh My!

虽然这种简化适用于许多地点,但不幸的是,这条规则有很多例外。

Time Zones and Offsets and ObjectScript, Oh My!
参考:世界时区(维基百科)

使用 UTC(“起源”)进行标准化

为了简化传达特定时间的语言,世界决定使用 UTC(协调世界时)。 该标准将“原点”设置为经过伦敦格林威治的 0° 经度。

定义“偏移”

以UTC为基础,所有其他时区都可以相对于UTC来定义。 这种关系称为 UTC 偏移量

如果你有本地时间和偏移量,你就不再有模糊的时间(如上面我们的间谍示例所示);你有一个明确且具体的时间,没有任何含糊之处。

用于显示 UTC 偏移量的典型格式是 ±HHMM[SS[.ffffff]]。

  • 减号表示向 UTC 西边的偏移。
  • 加号表示向 UTC 东部的偏移。
  • HH 表示小时(以零填充)
  • MM 表示分钟(零填充)
  • SS 表示秒(以零填充)
  • .ffffff 表示秒小数

例如,在美国,东部标准 Zime 区域 (EST) 定义为 -0500 UTC。 这意味着 EST 中的所有地点均比 UTC 晚 5 小时。 如果 UTC 时间为晚上 9:00,则 EST 当地时间为下午 4:00。

在澳大利亚中西部标准时区 (ACWST),偏移量定义为 0845 UTC。 如果 UTC 时间为凌晨 1:00,则 ACWST 当地时间为上午 9:45。

夏令时

那么,回到上面的时区地图。 从图像中,您可以看到许多时区遵循国家和地区的政治边界。 这会使时区计算稍微复杂一些,但很容易理解。

不幸的是,在处理时间和时区时还需要考虑一个因素。

让我们看看洛杉矶。

在地图上,洛杉矶的 UTC 偏移量在标准时间中为 -8。 冬季通常采用标准时间,而夏季通常采用夏令时

夏令时 (DST) 将给定时区的时钟提前(通常在夏季月份提前一小时)。 政治区域选择遵循夏令时的原因有多种(例如节能、更好地利用日光等)。 夏令时的困难和复杂性在于,世界各地并未一致遵循夏令时。 根据您所在的位置,您所在的地区可能遵循也可能不遵循夏令时。

时区数据库

由于政治边界和夏令时的结合大大增加了确定特定时间的复杂性,因此需要时区数据库来将当地时间正确映射到相对于 UTC 的特定时间。 互联网号码分配机构 (IANA) 时区数据库是操作系统和编程语言使用的时区信息的常见来源。

数据库包含所有时区的名称和别名、偏移量信息、夏令时使用信息、时区缩写以及各种规则适用的日期范围。

有关时区数据库的副本和信息可以在 IANA 网站上找到。

大多数 UNIX 系统都有一个数据库副本,该副本通过操作系统的包管理器(通常安装在 /usr/share/zoneinfo 中)进行更新。 一些编程语言内置了数据库。 其他人通过图书馆提供它或可以读取系统的数据库副本。

时区名称/标识符

时区数据库包含许多特定时区的名称和别名。 许多条目的名称中都包含国家(或大陆)和主要城市。 例如:

  • 美国/纽约
  • 美国/洛杉矶
  • 欧洲/罗马
  • 澳大利亚/墨尔本

使用 ObjectScript 进行转换和格式化

所以,现在我们知道:

  • 当地时间(没有偏移量或位置的模糊时间)
  • UTC 偏移量(时间戳或位置相对于伦敦格林威治的 UTC“原点”的相对偏移量)
  • 夏令时(以时区偏移为代价来帮助文明的尝试)
  • 时区数据库(其中包括有关许多地点和地区的时区和夏令时遵守情况的信息)

了解了这一点,我们如何在 ObjectScript 中使用日期时间/时区?

***注意:我相信以下所有关于 ObjectScript 的陈述都是正确的,但如果我错误地表述了 ObjectScript 如何处理时区和偏移量,请告诉我。

内置变量和函数

如果您需要在运行 IRIS 的进程的系统时区内的各种格式之间转换时间戳,ObjectScript 的内置功能应该足够了。 以下是 ObjectScript 中各种与时间相关的变量/函数的简要列表:

  • $ZTIMESTAMP / $ZTS

    • IRIS 内部格式为 UTC 值(偏移量 0000)。
    • 格式:ddddd,sssss.ffffffff
  • $NOW(tzmins)

    • 当前系统本地时间以及给定的 tzmins 与 UTC 的偏移量。
    • 不考虑夏令时。
    • 默认情况下,tzmins 基于 $ZTIMEZONE 变量。
    • 格式:ddddd,sssss.ffffffff
  • $HOROLOG

    • 当前系统本地时间(基于 $ZTIMEZONE),考虑夏令时。
    • 格式:ddddd,sssss.ffffffff
  • $ZTIMEZONE

    • 返回或设置系统本地 UTC 偏移量(以分钟为单位)。
  • $ZDATETIME() / $ZDT()

    • 将 $HOROLOG 格式转换为特定的显示格式。
    • 可用于将系统本地时间转换为 UTC ( 0000)。
  • $ZDATETIMEH() / $ZDTH()

    • 将日期时间字符串转换为内部 $HOROLOG 格式。
    • 可用于从 UTC ( 0000) 转换为系统本地时间。

据我所知,这些函数只能使用本地系统的时区来操作日期时间。 似乎没有办法在 ObjectScript 中处理任意时区。

进入 Open Exchange 上的 tz 图书馆

为了适应任意时区之间的转换,我创建了 tz - ObjectScript 时区转换库。

该库访问系统上安装的时区数据库,为时区和格式之间的时间戳转换提供支持。

例如,如果您有洛杉矶本地时间(美国/洛杉矶),您可以将其转换为巴哈马使用的时区(美国/纽约)或伦敦使用的时区(欧洲/伦敦):

USER>zw ##class(tz.Ens).TZ("2024-12-20 3:14 PM", "America/Los_Angeles", "America/New_York")
"2024-12-20 06:14 PM"

USER>zw ##class(tz.Ens).TZ("2024-12-20 3:14 PM", "America/Los_Angeles", "Europe/London")
"2024-12-20 11:14 PM"
登录后复制

如果给您一个带有偏移量的时间戳,您可以将其转换为澳大利亚尤克拉 (Australia/Eucla) 的当地时间,即使您不知道原始时区:

USER>zw ##class(tz.Ens).TZ("2024-12-20 08:00 PM -0500", "Australia/Eucla")
"2024-12-21 09:45 AM +0845"
登录后复制

如果您使用 HL7 消息,tz 库有多种暴露于互操作性规则和 DTL 的方法,可帮助您轻松在时区、本地时间、带偏移量的时间等之间进行转换:

// Convert local time from one time zone to another      
set datetime = "20240102033045"
set newDatetime = ##class(tz.Ens).TZ(datetime,"America/New_York","America/Chicago")

// Convert local time to offset      
set datetime = "20240102033045"
set newDatetime = ##class(tz.Ens).TZOffset(datetime,"America/Chicago","America/New_York")

// Convert offset to local time      
set datetime = "20240102033045-0500"
set newDatetime = ##class(tz.Ens).TZLocal(datetime,"America/Chicago")

// Convert to a non-HL7 format   
set datetime = "20240102033045-0500"
set newDatetime = ##class(tz.Ens).TZ(datetime,"America/Chicago",,"%m/%d/%Y %H:%M:%S %z")
登录后复制

概括

感谢您跟随我踏上这次“国际之旅”,我们遇到了时区、夏令时、世界地图和“定时炸弹”。 希望这能够阐明(并简化)处理日期时间和时区的许多复杂性。

查看 tz - ObjectScript 时区转换库,如果您有任何问题(或者对我所说的内容进行更正/澄清),请告诉我。

谢谢!

参考资料/有趣的链接

  • https://en.wikipedia.org/wiki/Cooperative_Universal_Time
  • https://en.wikipedia.org/wiki/Time_zone
  • https://en.wikipedia.org/wiki/Daylight_ saving_time
  • https://www.worldtimeserver.com/learn/unusual-time-zones/
  • https://www.worldtimeserver.com/learn/history-of-time-zones/
  • https://www.worldtimeserver.com/learn/what-is-a-time-zone/
  • https://en.wikipedia.org/wiki/Tz_database
  • https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
  • https://en.wikipedia.org/wiki/Internet_Assigned_Numbers_Authority
  • https://www.iana.org/time-zones
  • https://www.gnu.org/software/libc/manual/html_node/Calendar-Time.html

以上是时区、偏移量和 ObjectScript,天哪!的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板