【问题标题】:Converting JavaScript timestamp formatted as Sat Dec 30 1899 HH:MM:SS to today?将格式为 Sat Dec 30 1899 HH:MM:SS 的 JavaScript 时间戳转换为今天?
【发布时间】:2020-12-15 00:31:32
【问题描述】:

我有一个应用程序,它将轮班开始和结束时间显示为 javascript 日期,其中日期设置为 1899 年 12 月 30 日星期六,并具有适当的开始/结束时间:

const start = new Date(-2209139100000); // Sat Dec 30 1899 06:15:00 GMT+0000 (Greenwich Mean Time)
const finish = new Date(-2209095900000); // Sat Dec 30 1899 18:15:00 GMT+0000 (Greenwich Mean Time)

这些时间我的应用程序作为 json 对象的一部分动态发送。我无权访问时间来自的主服务器,因此我无法从源头纠正它们。

我要做的是将班次开始时间转换为今天的日期(以及适当的班次开始时间),然后将完成时间转换为将来的适当时间。当我的申请收到轮班开始时间总是过去的时间时(在前 12 小时内)。轮班可以超过午夜(夜班),但轮班时长可能会有所不同(6、8、10 和 12 小时),但轮班总是会在开始时间的 24 小时内结束。

有人可以给我一些指导或起点吗?

【问题讨论】:

  • 所以你只想要时间?
  • 我需要一个完整的日期时间,因为我需要执行比较(即轮班是否已完成)。例如,上面的开始时间需要是 2020 年 12 月 15 日星期二 06:15:00 GMT+0000(格林威治标准时间),然后返回的结束时间将是未来的适当时间。
  • 那么从 12 月 30 日到 15 日你是怎么过的?
  • @Rojo 因为今天是今天?
  • 我相信 1899 年 12 月 30 日星期六是某种微软的基准日期。

标签: javascript date datetime time


【解决方案1】:

您可以使用Date 方法setUTCFullYear() 仅更改Date 实例的日期部分。然后只需将原始时差添加到新的开始日期即可获得新的结束日期。

const start = new Date(-2209095900000);
const finish = new Date(-2209052700000);
console.log("Original start:", start.toISOString())
console.log("Original finish:", finish.toISOString())

const diff = finish - start
const now = new Date()

// Clone start
const newStart = new Date(start)

// Set date part to today
newStart.setUTCFullYear(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate())

// Set finish to be the same diff from newStart
const newFinish = new Date(newStart.valueOf() + diff)

console.log("Start:", newStart.toISOString())
console.log("Finish:", newFinish.toISOString())

【讨论】:

  • 完美,这看起来像我可以使用的东西。
  • @JonathanAdams 我用我认为更好的方法改变了我的答案
  • 感谢。我无法弄清楚如何让它在午夜过后的班次中工作。例如,如果您使用时间 start = -2209095900000 和 finish = -2209139100000 它返回 Start: 2020-12-15T18:15:00.000Z Finish: 2020-12-15T06:15:00.000Z 其中完成应该是 2020-12-16T06:15:00.000Z
  • @JonathanAdams 我的答案中的代码使用了一个夜班示例,它按预期工作
  • @JonathanAdams 22091391000001899-12-30T06:15:00.000Z 在您的开始之前
【解决方案2】:

这是我已经解决的问题,似乎正在工作:

const now = new Date();
const start = new Date(-2209095900000);
const finish = new Date(-2209139100000);

const newStart = new Date(start);
newStart.setUTCFullYear(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate());

const newFinish = new Date(finish);
newFinish.setUTCFullYear(now.getUTCFullYear(), now.getUTCMonth(), (start > finish) ? now.getUTCDate() + 1 : now.getUTCDate());

console.log("Original Start:", start.toISOString())
console.log("Original Finish:", finish.toISOString())
console.log("New Start:", newStart.toISOString())
console.log("New Finish:", newFinish.toISOString())

【讨论】:

  • 做得很好。鉴于您的初始数据状态,我会说这是最好的前进方式
【解决方案3】:

您可以通过从原始start 日期与Date.now() 与该日期之间的天数差的总和创建一个新日期来算术地执行此操作。然后可以通过将原始 startfinish 日期之间的差异添加到新的开始日期来创建新的完成日期。

const 
  start = new Date(-2209095900000),  // 1899-12-30T18:15:00.000Z
  finish = new Date(-2209139100000); // 1899-12-30T06:15:00.000Z
  
let
  shiftTime = finish-start;
  // if start is later than finish add a day
  if (shiftTime < 0) shiftTime += 8.64e7;
 
const  
  startVal = start.valueOf(),
  dayDiff = (Math.floor(Date.now()/8.64e7)-Math.floor(startVal/8.64e7))*8.64e7,
  newStartVal = startVal + dayDiff;
   
const
  newStart = new Date(newStartVal),
  newFinish = new Date(newStartVal+shiftTime);
  
console.log('Start');
console.log('old: ', start);
console.log('new: ', newStart);  
console.log('Finish');
console.log('old: ', finish);
console.log('new: ', newFinish);
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

    【解决方案4】:

    解决这个问题的一种方法是计算从开始到现在的天数,并在开始和结束时加上那么多天,例如

    function fixDates(start, finish) {
      // Start of current UTC day
      let now = new Date().setUTCHours(0,0,0,0);
      // Start of start UTC day
      let s = new Date(start).setUTCHours(0,0,0,0);
    
      // Whole UTC days difference
      let diff = (now - s) / 8.64e7;
      // Add to start and finish
      start.setUTCDate(start.getUTCDate() + diff);
      finish.setUTCDate(finish.getUTCDate() + diff); 
      return [start, finish];
    }
    
    // Examples
    [[-2209139100000, -2209095900000],
     [-2209095900000, -2209139100000]].forEach(arr => {
       let s = new Date(arr[0]);
       let f = new Date(arr[1]);
       console.log('Start : ' + s.toLocaleString());
       console.log('Finish: ' + f.toLocaleString());
       console.log('Fixed');
       let [sf, ff] = fixDates(s, f);   
       console.log('New start : ' + sf.toLocaleString());
       console.log('New finish: ' + ff.toLocaleString());
     })

    ECMAScript UTC 日总是正好有 8.64e7 毫秒,因此夏令时无效。通过添加日期来添加天数也可以避免 DST 影响。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-09-08
      • 2011-06-20
      • 1970-01-01
      • 2012-12-30
      • 1970-01-01
      • 2011-06-17
      相关资源
      最近更新 更多