Luxon:获取偏移量和直到的数组(就像我们可以在时刻时区中一样)
Posted
技术标签:
【中文标题】Luxon:获取偏移量和直到的数组(就像我们可以在时刻时区中一样)【英文标题】:Luxon: get an array of offsets and untils (like we can in moment-timezone) 【发布时间】:2022-01-17 20:08:11 【问题描述】:使用moment-timezone
库,我目前只是检索特定时区的原始信息,然后直接在我的下游代码中使用。
const zone = moment.tz.zone('Europe/London');
这是一个包含以下内容的对象:
"name":"Europe/London",
"abbrs":["GMT","BST","GMT","BST", ...],
"untils":[-1691964000000,-1680472800000,-1664143200000,-1650146400000, ...],
"offsets":[0,-60,0,-60,0, ...],
"population":10000000
offsets
和 untils
数组是我真正需要的 moment
... 其余的我使用 offsets
和 untils
数组在下游代码中“手动”处理自己(或者实际上只是其中的一小部分)...而不必依赖 moment
作为依赖项。
有没有等效的方法来提取luxon
库中的offsets
和untils
数组?
【问题讨论】:
您可以使用IANAZone.create("Europe/London")
获得Zone
对象(请参阅IANAZone.create 的文档),但我担心moment 的offsets
和untils
没有一对一的对应关系。也许你可以使用offset
和其他实例方法来获得你需要的东西。
@VincenzoC 所以也许唯一的方法就是通过循环我感兴趣的时间范围(通常只有几天)来确定untils
自己,每个时间增加 1 毫秒时间并传递给offset()
,并在offset
中的每次更改时存储until
。在实践中,我可以更有效率,因为我知道我的兴趣期最多只有 14 天……如果offset
在开始和结束时是相同的,那么它不会(大概)在两者之间改变。 ..如果开始/结束offset
不同,只需要确定确切的转换时间(until
)。
@VincenzoC 我发布了一个答案......也许它过于简单......有更好的想法吗?
我没有更好的想法,您的回答对我来说似乎很好,尤其是如果它满足您的需求;)
我主要担心的假设是偏移量只会在小时内发生变化。但话又说回来,在我的用例中,我找到具有毫秒精度的 untils
并不是绝对关键......我没有使用这个控制核电站或发射导弹。
【参考方案1】:
根据@VincenzoC 的评论,这是我试图让offsets
和untils
(根据moment-timezone
)覆盖给定时间范围的简单尝试。此方法假定偏移量仅在小时内发生变化(因此我们可以将时间范围按一小时递增)。
import IANAZone from 'luxon';
const getZoneInfo = function (id, startTime, endTime)
startTime = Math.floor(startTime / 36e5) * 36e5; // move to previous whole hour
endTime = Math.ceil(endTime / 36e5) * 36e5; // move to next whole hour
const increment = 36e5; // one whole hour
const zone = IANAZone.create(id);
const offsets = [];
const untils = [];
let offset, prevOffset;
for (let time = startTime; time <= endTime; time += increment)
offset = zone.offset(time);
if (prevOffset != undefined && offset != prevOffset || time == endTime)
offsets.push(-prevOffset);
untils.push(time);
prevOffset = offset;
const zoneInfo =
id: id,
offsets: offsets,
untils: untils
;
console.log('zoneInfo', zoneInfo);
return zoneInfo;
;
const startTime = 1646931245000;
const endTime = 1650473645000;
getZoneInfo('Europe/London', startTime, endTime);
getZoneInfo('Europe/Stockholm', startTime, endTime);
getZoneInfo('Asia/Tokyo', startTime, endTime);
getZoneInfo('America/New_York', startTime, endTime);
输出:
zoneInfo
id: 'Europe/London',
offsets: [ -0, -60 ],
untils: [ 1648342800000, 1650474000000 ]
zoneInfo
id: 'Europe/Stockholm',
offsets: [ -60, -120 ],
untils: [ 1648342800000, 1650474000000 ]
zoneInfo
id: 'Asia/Tokyo',
offsets: [ -540 ],
untils: [ 1650474000000 ]
zoneInfo
id: 'America/New_York',
offsets: [ 300, 240 ],
untils: [ 1647154800000, 1650474000000 ]
当然,最后的until
并不代表offset
的实际变化,但它的目的是覆盖整个感兴趣的范围(除了endTime
之外不需要任何东西)。
更新
这里是上述的一个变体,它试图通过全天步进来提高效率(特别是对于更大的时间范围),并且只有在偏移量发生变化时才返回以更准确地找到过渡:
import IANAZone from 'luxon';
const getZoneInfo = function (id, startTime, endTime)
const zone = IANAZone.create(id);
const offsets = [];
const untils = [];
startTime = Math.floor(startTime / 36e5) * 36e5; // move to previous whole hour
endTime = Math.ceil(endTime / 36e5) * 36e5; // move to next whole hour
const stepSmall = 36e5; // one whole hour
const stepLarge = 24 * 36e5; // one whole day
let step = stepLarge; // start on the larger step for speed
let offset, prevOffset, offsetChanged;
let time = startTime;
offset = prevOffset = zone.offset(time);
do
time = Math.min(time + step, endTime);
offset = zone.offset(time);
offsetChanged = (offset != prevOffset);
if (offsetChanged || time == endTime)
if (offsetChanged && step == stepLarge)
// go back a step and switch to using the smaller step to find the transition more accurately...
time = time - stepLarge;
step = stepSmall;
continue;
else
offsets.push(-prevOffset);
untils.push(time);
// go back to the larger step...
step = stepLarge;
prevOffset = offset;
while (time < endTime);
const zoneInfo =
id: id,
offsets: offsets,
untils: untils
;
console.log('zoneInfo', zoneInfo);
return zoneInfo;
;
const startTime = 1608020493000;
const endTime = 1734250893000;
getZoneInfo('Europe/London', startTime, endTime);
getZoneInfo('Europe/Stockholm', startTime, endTime);
getZoneInfo('Asia/Tokyo', startTime, endTime);
getZoneInfo('America/New_York', startTime, endTime);
输出:
zoneInfo
id: 'Europe/London',
offsets: [
-0, -60, -0, -60,
-0, -60, -0, -60,
-0
],
untils: [
1616893200000,
1635642000000,
1648342800000,
1667091600000,
1679792400000,
1698541200000,
1711846800000,
1729990800000,
1734253200000
]
zoneInfo
id: 'Europe/Stockholm',
offsets: [
-60, -120, -60,
-120, -60, -120,
-60, -120, -60
],
untils: [
1616893200000,
1635642000000,
1648342800000,
1667091600000,
1679792400000,
1698541200000,
1711846800000,
1729990800000,
1734253200000
]
zoneInfo
id: 'Asia/Tokyo',
offsets: [ -540 ],
untils: [ 1734253200000 ]
zoneInfo
id: 'America/New_York',
offsets: [
300, 240, 300,
240, 300, 240,
300, 240, 300
],
untils: [
1615705200000,
1636264800000,
1647154800000,
1667714400000,
1678604400000,
1699164000000,
1710054000000,
1730613600000,
1734253200000
]
【讨论】:
以上是关于Luxon:获取偏移量和直到的数组(就像我们可以在时刻时区中一样)的主要内容,如果未能解决你的问题,请参考以下文章
获取节点中特定时区的 UTC 偏移量和 DST 信息? [复制]