JS 在几小时内得到两个时间不同的 GMT 问题

Posted

技术标签:

【中文标题】JS 在几小时内得到两个时间不同的 GMT 问题【英文标题】:JS Get Two Time Different problem with GMT in hours 【发布时间】:2020-09-05 22:56:45 【问题描述】:

我面临着在全球范围内获得两次不同的问题。我需要差异时间格式天:小时:分钟:秒。 一切正常,但 小时 内出现问题。对于此示例,小时应为 0 小时,但返回 6 小时。

function getTimeDiff(join, lastSeen) 

  let t1 = new Date(join).getTime(),
    t2 = new Date(lastSeen).getTime(),
    milliseconds = 0,
    time = '';
  if (isNaN(t1) || isNaN(t2)) return '';
  if (t1 < t2) milliseconds = t2 - t1;
  else milliseconds = t1 - t2;
  var days = Math.floor(milliseconds / 1000 / 60 / (60 * 24));
  var date_diff = new Date(milliseconds);
  if (days > 0) time += days + 'd ';
  console.log('join: ', join, ' - ', 'lastseen:', lastSeen);
  console.log('Diff = ', milliseconds);
  console.log('Standard Time : ', date_diff);
  console.log('Hours: ', date_diff.getHours());
  console.log('Minutes: ', date_diff.getMinutes());
  console.log('Secounds: ', date_diff.getSeconds());
  if (date_diff.getHours() > 0) time += date_diff.getHours() + 'h ';
  if (date_diff.getMinutes() > 0) time += date_diff.getMinutes() + 'm ';
  if (date_diff.getSeconds() > 0) time += date_diff.getSeconds() + 's ';
  console.log('Result: ', time);
  return time;



console.log(getTimeDiff(1589911275699, 1589911365116));

输出结果:

**

1589911275699 " -- " 1589911365116
join:  1589911275699  -  lastseen: 1589911365116
Diff =  89417
Standard Time :  Thu Jan 01 1970 06:01:29 GMT+0600 (Bangladesh Standard Time)
Hours:  6 // Result should be 0
Minutes:  1
Secounds:  29
Result:  6h 1m 29s // 0h 1m 29s

**

这里已经有一些帖子但同样的问题 https://***.com/a/18103175

【问题讨论】:

为什么要转换为 Date 对象?只需减去两个时间值并将差值转换为天、小时、分钟等。 【参考方案1】:

您不需要转换为 Date 对象,您拥有的时间值就足够了。例如

function getTimeDiff(t0, t1) 
  let z = n => (n<10?'0':'')+n;
  let diff = t1 - t0;
  let sign = diff < 0? '-':'+';
  diff = Math.abs(diff);
  let h = diff / 3.6e6 | 0;
  let m = (diff % 3.6e6) / 6e4 | 0;
  let s = (diff % 6e4) / 1e3 | 0;
  
  return `$sign$h:$z(m):$z(s)`; 


let join = 1589911275699;
let lastseen = 1589911365116;
console.log(`The time difference between 
$new Date(join) and
$new Date(lastseen) is
$getTimeDiff(join, lastseen)`);

请注意,生成时间戳的差异与时间值的差异不同,因为转换为时间戳会截断毫秒(十进制秒)。

转换为 Date 对象没有任何用处,因为:

new Date(join).getTime() === join

其中join 是±8.64e15 范围内的数字。这给出了 1970 年 1 月 1 日前后 1 亿天的范围。

【讨论】:

你是对的。 “转换为 Date 对象没有任何用处”【参考方案2】:

当您构建日期对象 (new Date(milliseconds)) 时,它会在您的时区创建日期对象(我认为您有 +6 GMT),因此您可以获得 +6 小时。

简单的解决方法是应用时区偏移:

var hours = date_diff.getHours() + new Date().getTimezoneOffset()/60; if (hours > 0) time += hours + 'h ';

但这不会涵盖偏移半小时的时区 https://en.wikipedia.org/wiki/Time_zone#/media/File:Solar_time_vs_standard_time.png 例如澳大利亚有 +9:30 偏移时区

最好手动获取时间差异:

var milliseconds = 89417;
var hours = Math.floor(milliseconds/1000/60/60);
var minutes = Math.floor((milliseconds - hours*1000*60*60)/1000/60);
var seconds = Math.floor((milliseconds - hours*1000*60*60 - minutes*1000*60)/1000);

console.log(hours, minutes, seconds);

PS:

我建议使用 moment.js 来计算时间差异, 检查这个https://***.com/a/18624295/676611

【讨论】:

如何在全球范围内进行?不依赖于时区 @ShaponPal 非常糟糕的解决方案,当毫秒 + new Date().getTimezoneOffset()*60*1000 小于 0 时将不起作用,我会尽快更新 当你构建日期对象(新日期(毫秒))时,它会在你的时区创建日期对象”不正确,该值被视为 UTC。 ECMAScript 日期对象没有时区,它们实际上始终是 UTC,通过 get* 和各种 to*String 方法转换为本地值。【参考方案3】:

这是@RobG

的修改代码sn-p

 function getTimeDiff(t0, t1) 
        var s,m,h,d,tDiff="";
        let z = n => (10 > n?'0':'')+n;
        let diff = t1 - t0;
        if(diff < 0) return "0s";
        diff = Math.abs(diff);
        d = Math.floor(diff / 86.4e6 | 0);
        h = Math.floor(diff / 3.6e6 | 0);
        if(d > 0)
            tDiff += d + "d ";
            h -= (d * 24);
        
        m = Math.floor((diff % 3.6e6) / 6e4 | 0);
        s = Math.floor((diff % 6e4) / 1e3 | 0);
        if(h > 0) tDiff += h + "h ";
        if(m > 0) tDiff += m + "m ";
        tDiff += s + "s";
        return tDiff;
    

let join = 1589645159314;
//let join = new Date(Date.now() - (1 * 22 * 60 * 60 * 1000)).getTime();
//let lastseen = 1589911365116;
let lastseen = Date.now();
console.log(`The time difference between 
$new Date(join) and
$new Date(lastseen) is
$getTimeDiff(join, lastseen)`);

function getTimeDiff(t0, t1) 
  let z = n => (n<10?'0':'')+n;
  let diff = t1 - t0;
  let sign = diff < 0? '-':'+';
  diff = Math.abs(diff);
  let h = diff / 3.6e6 | 0;
  let m = (diff % 3.6e6) / 6e4 | 0;
  let s = (diff % 6e4) / 1e3 | 0;
  
  return `$sign$h:$z(m):$z(s)`; 


let join = 1589911275699;
let lastseen = 1589911365116;
console.log(`The time difference between 
$new Date(join) and
$new Date(lastseen) is
$getTimeDiff(join, lastseen)`);

【讨论】:

以上是关于JS 在几小时内得到两个时间不同的 GMT 问题的主要内容,如果未能解决你的问题,请参考以下文章

日期将 GMT 添加到小时

MongoDB - 在几个小时的时间范围内查询

new java.util.Date() 得到的时间与系统时间不一样,为啥?

Kafka 连接器记录写入器因缺少要分配的内存而卡在 S3OutputStream 中,但在几个小时内保持空闲状态并没有失败

js Date.parse()时区问题

在几秒钟内多次调用 Healthkit 后台交付