typescript 如何根据时区获取时差?

4c8rllxm  于 2023-11-20  发布在  TypeScript
关注(0)|答案(2)|浏览(213)

我需要得到的其他用户谁是在another国家位于小时和分钟的时差。这里是我所做的。

const timeZone = "Asia/tokyo"; // Time zone can be changed

let arr: any = new Date().toLocaleString("en-US", {
  timeZone: timeZone,
  dateStyle: "full",
  timeStyle: "full",
});

let currentTime = new Date();

字符串
需要获取currentHour和currentHour之间的差异

pod7payv

pod7payv1#

像Jaromanda X(下面使用 Intl.DateTimeFormat.formatToParts 复制)这样的解决方案是可以的,但是最好传递一个实际的 Date 对象,而不是日期和时间值。
我认为获取实际偏移量之间的差异更优雅(见下文)。

function msToHMS(ms) {
  let sign = ms < 0? '-' : '+';
  ms = Math.abs(ms);
  let z = n => (n < 10? '0':'') + n;
  let hr = (ms / 3.6e6) | 0;
  let min = ((ms % 3.6e6) / 6e4) | 0;
  let sec = ((ms % 6e4) / 1e3) | 0;
  return `${sign}${z(hr)}:${z(min)}:${z(sec)}`;
}

function getTZDiff(tz, d = new Date()) {
  let tv = d - (d % 1e3);
  let {year, month, day, hour, minute, second} = new Intl.DateTimeFormat('en', {
    year:'numeric', month:'numeric', day:'numeric',
    hour:'numeric', minute:'numeric', second:'numeric',
    timeZone: tz,
    hour12: false
  }).formatToParts(d).reduce((acc,part) => {
      acc[part.type] = part.value;
      return acc;
    }, Object.create(null)
  );
  return msToHMS(new Date(year, month-1, day, hour, minute, second) - tv);
}

console.log(getTZDiff('America/New_York', new Date(2023,3,2,1,30)));

字符串
使用时区偏移:

/* Return offset at loc for date
 * @param {string} loc - IANA representative location
 * @param {Date} date to get offset for
 * @returns {string} offset as ±hh:mm
 */
function getOffsetForLoc(loc, d = new Date()) {
  let offset = d.toLocaleString('en',{
    timeZoneName:'longOffset', timeZone: loc
  }).match(/[+|-][^+-]+$/); 
  return offset[0];
}

/* Convert offset in ±hh:mm:ss format to seconds
 * @param {string} offset - ±hh:mm:ss format
 * @returns {number} offset in seconds
 */
function offsetToSecs(offset) {
  let sign = offset[0] == '-' ? -1 : 1;
  let [hr, min, sec] = offset.match(/\d+/g);
  return sign * (hr*3600 + min*60 + (sec||0)*1); 
}

/* Convert secons to time in ±hh:mm:ss format
 * @param {number} secs - seconds to convert
 * @returns {string} equivalent in ±hh:mm:ss format
 */
function secsToHMS(secs) {
  let sign = secs < 0? '-' : '+';
  secs = Math.abs(secs);
  let z = n => (n < 10? '0':'') + n;
  let hr = (secs / 3600) | 0;
  let min = ((secs % 3600) / 60) | 0;
  let sec = secs % 60;
  return `${sign}${z(hr)}:${z(min)}:${z(sec)}`;
}

// Get diference in offset between two locations.
// Add difference to loc1 to get time in loc2
function getOffsetDifference(loc1, loc2, d = new Date()) {
  let off1 = offsetToSecs(getOffsetForLoc(loc1, d));
  let off2 = offsetToSecs(getOffsetForLoc(loc2, d));
  return secsToHMS(off2 - off1);
}

// Examples
let yourLoc = new Intl.DateTimeFormat().resolvedOptions().timeZone;
let cha = 'Pacific/Chatham';

console.log(
    `You  : ${yourLoc} ${getOffsetForLoc(yourLoc)}` +
  `\nOther: ${cha} ${getOffsetForLoc(cha)}` +
  `\nDiff : ${getOffsetDifference(yourLoc, cha)}` +
  ` (i.e. You + Diff == Other)` +
  `\nRev  : ${getOffsetDifference(cha, yourLoc)}` +
  ` (i.e. Other + Rev == You)`
);

6bc51xsx

6bc51xsx2#

首先,使用en-CA locale进行“计算”.它输出yyyy-mm-dd hh:mm:ss,这使得操作变得简单
其次,添加hour12: false,因为你想要24小时的时间
然后你可以

const minutesToHHMM = (m) => {
  const s = m < 0 ? '-' : '';
  m = Math.abs(m);
  const mm = (m % 60).toString().padStart(2, 0);
  const hh = Math.floor(m / 60);
  return `${s}${hh}:${mm}`;
}
const timeZone = 'Australia/Eucla'; // odd timezone to always show minutes in difference
const date = new Date();
date.setMilliseconds(0); // remove millisecond since we are not creating the "other" time with milliseconds
const other = new Date(...date
  .toLocaleString('en-CA', {
    timeZone,
    hour12: false,
  })
  .replaceAll('-',':') // convert yyyy-mm-dd to yyyy:mm:dd
  .replaceAll(', ', ':') // add ':' between date and time
  .split(':') // split all the values
  .map((v,i) => v - (i===1)) // subtract one from month
);

console.log("other time", other.toLocaleString());
console.log("local time", date.toLocaleString());
console.log("difference", minutesToHHMM((other-date)/60000));

字符串
我的 typescript 很不雅...但是

const minutesToHHMM = (m:number) => {
  const s = m < 0 ? '-' : '';
  m = Math.abs(m);
  const mm = (m % 60).toString().padStart(2, "0");
  const hh = Math.floor(m / 60);
  return `${s}${hh}:${mm}`;
}
const timeZone = 'Australia/Eucla'; // odd timezone to always show minutes in difference
const date = new Date();
date.setMilliseconds(0); // remove millisecond since we are not creating the "other" time with milliseconds

const other = new Date(...(date
  .toLocaleString('en-CA', {
      timeZone,
      hour12: false,
  })
  .replaceAll('-',':') // convert yyyy-mm-dd to yyyy:mm:dd
  .replaceAll(', ', ':') // add ':' between date and time
  .split(':') // split all the values
  .map(Number)
  .map((v:number, i:number) => v - ((i===1) ? 1 : 0)) as []) // subtract 1 from month
);

console.log("other time", other.toLocaleString());
console.log("local time", date.toLocaleString());
console.log("difference", minutesToHHMM((+other - +date)/60000));


在TSPlayground上试过了,似乎有效

相关问题