让我们假设您是一名国际行动间谍,一生致力于保护世界人民免受危险。 您收到以下任务:
美好的一天,特工 IRIS,
我们很抱歉打扰您在巴哈马的假期,但我们刚刚收到伦敦代理的消息,一颗“定时炸弹”将在洛杉矶人口稠密的地区引爆。 我们的消息来源称,“定时炸弹”将于今天下午 3:14 触发。
快点,人们指望着你!
你赶紧站起来,准备前往洛杉矶,但你很快意识到你错过了一条关键信息; “定时炸弹”会在巴哈马时间下午 3:14 或洛杉矶时间下午 3:14 触发吗? ...或者甚至可能是伦敦时间下午 3:14。
您很快意识到,为您提供的时间(下午 3:14)并没有为您提供足够的信息来确定您何时需要到达洛杉矶。
为您提供的时间(下午 3:14)不明确。 您需要更多信息来确定准确时间。
当您思考这个问题时,您意识到有一些方法可以克服为您提供的时间的模糊性:
您的消息来源可能提供了当地时间下午 3:14 的位置。 例如,洛杉矶、巴哈马或伦敦。
您的消息来源可以使用 UTC(协调世界时)等标准来为您提供与商定位置(例如伦敦格林威治)的偏移量。
您致电消息来源并确认所提供的时间确实是洛杉矶时间下午 3:14。 您可以前往洛杉矶,在下午3:14之前解除“定时炸弹”,并迅速返回巴哈马结束您的假期。
那么,这个思维练习的意义是什么? 我怀疑我们中的任何人都会遇到上述问题,但如果您使用将数据从一个位置移动到另一个位置的应用程序或代码(特别是如果这些位置位于不同时区),您需要注意 如何处理日期时间和时区。
嗯,时区并没有那么糟糕。 夏令时和政治边界使时区变得困难。
我以为我一直理解时区的“一般”概念:地球按时区分成垂直的切片,每个时区比东部时区晚一小时。
虽然这种简化适用于许多地点,但不幸的是,这条规则有很多例外。
参考:世界时区(维基百科)
为了简化传达特定时间的语言,世界决定使用 UTC(协调世界时)。 该标准将“原点”设置为经过伦敦格林威治的 0° 经度。
以UTC为基础,所有其他时区都可以相对于UTC来定义。 这种关系称为 UTC 偏移量。
如果你有本地时间和偏移量,你就不再有模糊的时间(如上面我们的间谍示例所示);你有一个明确且具体的时间,没有任何含糊之处。
用于显示 UTC 偏移量的典型格式是 ±HHMM[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 中使用日期时间/时区?
***注意:我相信以下所有关于 ObjectScript 的陈述都是正确的,但如果我错误地表述了 ObjectScript 如何处理时区和偏移量,请告诉我。
如果您需要在运行 IRIS 的进程的系统时区内的各种格式之间转换时间戳,ObjectScript 的内置功能应该足够了。 以下是 ObjectScript 中各种与时间相关的变量/函数的简要列表:
$ZTIMESTAMP / $ZTS
$NOW(tzmins)
$HOROLOG
$ZTIMEZONE
$ZDATETIME() / $ZDT()
$ZDATETIMEH() / $ZDTH()
据我所知,这些函数只能使用本地系统的时区来操作日期时间。 似乎没有办法在 ObjectScript 中处理任意时区。
为了适应任意时区之间的转换,我创建了 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 时区转换库,如果您有任何问题(或者对我所说的内容进行更正/澄清),请告诉我。
谢谢!
以上是时区、偏移量和 ObjectScript,天哪!的详细内容。更多信息请关注PHP中文网其他相关文章!