首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >鲁迅:得到一系列的偏移和不连续(就像我们可以在瞬间-时区)

鲁迅:得到一系列的偏移和不连续(就像我们可以在瞬间-时区)
EN

Stack Overflow用户
提问于 2021-12-14 13:58:39
回答 1查看 193关注 0票数 1

使用moment-timezone库,我目前只是检索特定时区的原始信息,然后在下游代码中直接使用该信息。

代码语言:javascript
运行
复制
const zone = moment.tz.zone('Europe/London');

这是一个包含以下内容的对象:

代码语言:javascript
运行
复制
{
    "name":"Europe/London",
    "abbrs":["GMT","BST","GMT","BST", ...],
    "untils":[-1691964000000,-1680472800000,-1664143200000,-1650146400000, ...],
    "offsets":[0,-60,0,-60,0, ...],
    "population":10000000
}

offsetsuntils数组是我真正需要的moment.其余的我在下游代码中使用offsetsuntils数组(或者实际上只是其中的一小部分)“手动”处理.而不必依赖moment作为依赖项。

是否有一种在offsets库中提取luxonuntils数组的等效方法?

EN

回答 1

Stack Overflow用户

发布于 2021-12-14 20:09:17

基于@VincenzoC的评论,这里我简单地尝试让offsetsuntils (按moment-timezone)覆盖给定的时间范围。该方法假设偏移量只在小时内发生变化(因此我们可以通过一个小时的增量逐步完成时间范围)。

代码语言:javascript
运行
复制
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);

输出:

代码语言:javascript
运行
复制
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以外的任何东西)。

更新

下面是上述内容的一个变体,它试图提高一些效率(特别是对于较大的时间范围),方法是在整整几天内完成任务,如果偏移量发生变化,则返回时才能更准确地找到过渡:

代码语言:javascript
运行
复制
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);

输出:

代码语言:javascript
运行
复制
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
  ]
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70350134

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档