使用时区偏移获取时区名称/列表

问题描述 投票:0回答:3

我使用下面的代码获得时区偏移。 我想找出与时区偏移相关的时区名称列表。

new Date().getTimezoneOffset().toString()

javascript timezone momentjs timezone-offset
3个回答
2
投票

我认为你必须使用

moment-timezone.js
库来做到这一点。

(链接在这里:https://momentjs.com/timezone/

该方法应遵循以下原则:

  1. 导入库(注意:该库依赖于moment.js库 - 之前导入)
  2. 使用
    moment.tz.names()
    函数获取所有可用的时区位置。
  3. 使用
    moment.tz.zone(name)
    函数获取 zone 对象
  4. 使用
    zone 对象
    中的 offsets 属性来获取位置偏移
  5. 创建一个映射来保存相同的偏移名称。
  6. 循环遍历偏移量(一个位置可以共享多个偏移量)并将它们添加到地图以及每个键的位置名称。
  7. 访问具有特定偏移量的地图并获取时区列表。

代码看起来像这样:

const tzNames = moment.tz.names();
const map = new Map();

for (const name of tzNames) {
  const offsets = moment.tz.zone(name).offsets;
  
  for (const offset of offsets) {
      if (!map.has(offset)) {
          map.set(offset, new Set());
      }

      map.get(offset).add(name);
  }
}

const currentOffset = new Date().getTimezoneOffset();
const offsetList = map.get(currentOffset);

console.log('currentOffset: ' + currentOffset);
console.log('offset list size: ' + offsetList.size);
console.log('Total different offsets: ' + map.size);

console.log('List items: ');
for (const item of offsetList) {
  console.log(item);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.23/moment-timezone-with-data-2012-2022.min.js"></script>


1
投票

您可以在 vanilla js 中使用

intl
对象、本地“ia”分两步完成此操作(请参阅 https://stackoverflow.com/a/64262840/1061871)和
Intl.supportedValuesOf('timeZone')
https://developer .mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/supportedValuesOf):

const getOffset = (tz) => Intl.DateTimeFormat("ia", {
                timeZoneName: "shortOffset",
                timeZone: tz
              }) 
                .formatToParts()
                .find((i) => i.type === "timeZoneName").value // => "GMT+/-OFFSET in hh:mm"
                .slice(3); //remove the GMT to get the offset in hh:mm 

const getTZList = (offset) =>

     Intl.supportedValuesOf('timeZone').filter(tz => getOffset(tz) === offset)


console.log(getTZList("-3:30"), getTZList("")) //for list of timezone in gmt/utc use empty string, not 0

编辑,忘记了:以 +/-hh:mm 格式偏移的日期对象

const getUtcOffset = (dateObject = new Date()) => {
    
    const offset = dateObject.getTimezoneOffset(), o = Math.abs(offset);
    return  (offset === 0 ?  '' : ((offset < 0 ? "+" : "-") + ("00" + Math.floor(o / 60)).slice(-2) + ":" + ("00" + (o % 60)).slice(-2)));
 }
 console.log(getTZList(getUtcOffset(new Date()))

0
投票

要使用 Intl API 针对所有时区偏移来完成此任务,您可以在浏览器中使用以下 Vanilla JS 函数:

// Return an object with timezones in keys and UTC offset in value.

function get_all_timezones_offsets(date = null) {
    const range_hours = 18 // hours

    // Calculate the bounds for iteration
    const step_ms = 300000 // 5 minutes in milliseconds
    const max_steps = range_hours * 12

    // Calculate reference 'now' time
    const _now = date ? +date : Date.now(), now = _now - _now % step_ms

    // Initialize a Map to store the data
    const time_map = new Map()

    // Iterate from lowerBound to upperBound in steps of 15 minutes
    for (let i = -max_steps; i <= max_steps; i++) {
        const date = new Date(now + i * step_ms)

        // Construct the DDHHMM integer
        const DD = String(date.getUTCDate()).padStart(2, '0')
        const HH = String(date.getUTCHours()).padStart(2, '0')
        const MM = String(date.getUTCMinutes()).padStart(2, '0')

        // Store the key and initialize the value as [i, []]
        time_map.set(parseInt('1' + DD + HH + MM), [i, []])
    }

    // Iterate over all timezones
    for (const tz_name of Intl.supportedValuesOf('timeZone')) {
        const formatter = new Intl.DateTimeFormat('en', {
            minute: '2-digit',
            hour: '2-digit',
            hourCycle: 'h23', // Use 24-hour format
            day: '2-digit',
            timeZone: tz_name,
        })

        // Format the date to get the DDHHMM key
        const formatted_date = formatter.formatToParts(now)
        const DD = formatted_date.find(part => part.type === 'day').value
        const HH = formatted_date.find(part => part.type === 'hour').value
        const MM = formatted_date.find(part => part.type === 'minute').value
        const key = parseInt('1' + DD + HH + MM)

        // Add the timezone to the map
        if (time_map.has(key))
            time_map.get(key)[1].push(tz_name)
        else
            console.error(key, 'not found in the time_map.')
    }

    // Construct the result object
    const result = {}
    for (const [, [i, timezones]] of time_map)
        for (const timezone of timezones)
            // Manipulates 'i' to format the result accordingly to your needs
            result[timezone] = i

    return result
}
函数提供了

UTC ±HH:MM 字符串的 fotmatter :

function formatter(x) { return 'UTC ' + String.fromCharCode(43 + ((x < 0) << 1)) + String(~~((x = Math.abs(x)) / 12)).padStart(2, '0') + ':' + String((x % 4) * 5).padStart(2, '0') }
对于您的特定输入,您可以使用 

res

 数组作为答案:

const minutes = new Date().getTimezoneOffset().toString() const i = +minutes / 5 const all_timezones = get_all_timezones_offsets(), res = [] for (const tz_name in all_timezones) if (all_timezones[tz_name] === i) res.push(tz_name) console.log(minutes, res)
原始解决方案来源:

gist.github.com

// Return an object with timezones in keys and UTC offset in value. function get_all_timezones_offsets(date = null) { const range_hours = 18 // hours // Calculate the bounds for iteration const step_ms = 900000 // 15 minutes in milliseconds const max_steps = range_hours * 4 // Multiply the interval by 4 as per the instructions // Calculate reference 'now' time const _now = date ? +date : Date.now(), now = _now - _now % step_ms // Initialize a Map to store the data const time_map = new Map() // Iterate from lowerBound to upperBound in steps of 15 minutes for (let i = -max_steps; i <= max_steps; i++) { const date = new Date(now + i * step_ms) // Construct the DDHHMM integer const DD = String(date.getUTCDate()).padStart(2, '0') const HH = String(date.getUTCHours()).padStart(2, '0') const MM = String(date.getUTCMinutes()).padStart(2, '0') // Store the key and initialize the value as [i, []] time_map.set(parseInt('1' + DD + HH + MM), [i, []]) } // Iterate over all timezones for (const tz_name of Intl.supportedValuesOf('timeZone')) { const formatter = new Intl.DateTimeFormat('en', { minute: '2-digit', hour: '2-digit', hourCycle: 'h23', // Use 24-hour format day: '2-digit', timeZone: tz_name, }) // Format the date to get the DDHHMM key const formatted_date = formatter.formatToParts(now) const DD = formatted_date.find(part => part.type === 'day').value const HH = formatted_date.find(part => part.type === 'hour').value const MM = formatted_date.find(part => part.type === 'minute').value const key = parseInt('1' + DD + HH + MM) // Add the timezone to the map if (time_map.has(key)) time_map.get(key)[1].push(tz_name) else console.error(`Error: Key ${key} not found in the time_map.`) } // Construct the result object const result = {} for (const [, [i, timezones]] of time_map) for (const timezone of timezones) // Manipulates 'i' to format the result accordingly to your needs result[timezone] = i return result } const minutes = new Date().getTimezoneOffset().toString() const i = +minutes / 15 const all_timezones = get_all_timezones_offsets(), res = [ ] for(const tz_name in all_timezones) if (all_timezones[tz_name] === i) res.push(tz_name) console.log(minutes, res)

© www.soinside.com 2019 - 2024. All rights reserved.