Moment js跨时区的日期值比较

时间:2019-12-13 03:27:29

标签: javascript date datetime timezone momentjs

我从外部来源获得4个日期作为下面提到的输入。

带有时间元素的日期

"InitialDate": "2019-02-19T12:03:22.129Z",
"updateDate": "2019-02-28T05:26:57.115Z",

没有时间元素的日期

"startDate": "2019-02-18",
"endDate": "2020-02-16",

我正在使用以下时刻格式从其中覆盖 InitialDate updateDate 并创建 actualInitDatE ,因为它们也都具有时间元素在里面。

我不需要时间元素,我只想要所有4个日期的日期元素。

   const actualInitDatE = moment(InitialDate).format('MM-DD-YYYY') || 
  moment(updateDate).format('MM-DD-YYYY');

现在,我要转换其中只包含日期元素(而没有时间元素)的 startDate endDate ,最后创建 actualStartDate actualEndDateW 变量,

const actualStartDateW = moment(startDate).format('MM-DD-YYYY');
const actualEndDateW = moment(endDate).format('MM-DD-YYYY');

现在,我将它们与以下逻辑进行比较,并且在IST中工作正常,

if (actualInitDatE >= actualStartDateW && actualInitDatE <= actualEndDateW) {
          console.log('Compared and True');
}

我的疑问是,这在UTC和其他时区也能正常工作吗?我有些怀疑,因为某些日期包含时间元素,而有些则仅包含日期元素。

我已经完成了这一过程并实现了该方法。这种方法是正确的还是我们需要使用任何偏移量?

javascript Date timezone issue

有人可以在这方面帮助我,让我知道这段代码在timeZones中是否有效?

2 个答案:

答案 0 :(得分:0)

我相信这里的核心问题是,您必须为startDate和endDate指定时区。如果不这样做,moment.js将采用当地时间,例如IST或假设您在美国太平洋时间。这种方法的问题是代码将给出不一致的结果(取决于计算机)。

您可以通过在浏览器中运行以下代码段(最好是Chrome)并更改计算机时区来演示这一点。您会看到,解析startDate(和endDate)将导致不同的时间,具体取决于您的时区。

因此,时间戳时区的组合为我们提供了最健壮的代码的清晰,明确的时间点。如果我们在解析开始日期和结束日期时不设置时区,则代码可能会根据运行的机器给出不同的结果。

最好的方法是指定startDate和endDate所在的时区,例如他们是在IST还是在UTC?

这样,您可以确定自己的日期将被一致地解析。

我还建议创建一个函数,例如parseDate,它接受日期字符串,格式和时区。这对所有阅读代码的人来说都是清楚的假设。

InitialDate或updateDate没问题,因为它们被指定为UTC时间(Z时区指定符),所以它们既清晰又明确。

const dates = { 
    startDate: "2019-02-18",
    endDate: "2020-02-16"
}

const startDateNoTimezoneSpecified = moment(dates.startDate);
console.log("StartDate (No Timezone Specified):", startDateNoTimezoneSpecified.toISOString());

function parseDate(dateString, format, timezone) {
    return moment.tz(dateString, format, timezone)
}

// Parse start date, assuming it is in IST (I'm assuimg IST refers to India Standard Time , if it's Israel Standard Time replace with Asia/Jerusalem!
console.log("Parse date result (IST):", parseDate(dates.startDate, "YYYY-MM-DD","Asia/Kolkata").toISOString());
console.log("Parse date result (UTC):", parseDate(dates.startDate, "YYYY-MM-DD","UTC").toISOString());


// You can also use moment.utc instead of moment.tz(date, "UTC").. it's simpler!
const startDateUTC = moment.utc(dates.startDate);
console.log("StartDate (UTC (moment.utc)):", startDateUTC.toISOString());
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
<script src="https://momentjs.com/downloads/moment-timezone-with-data-1970-2030.js"></script>

答案 1 :(得分:0)

您似乎在使事情复杂化。

您可以将UTC时间戳转换为本地日期,但是格式没有意义。 MM-DD-YYYY对于任何事情都没有用,我建议使用ISO 8601 YYYY-MM-DD。

仅日期时间戳记应视为本地时间戳记,因此后两个日期无需转换。使用ISO 8601格式,可以直接比较字符串:

let initialDate = '2019-02-19T12:03:22.129Z';
let updateDate = '2019-02-28T05:26:57.115Z';

// Get local date in required format
let actualInitDatE = moment(initialDate || updateDate).format('YYYY-MM-DD');

// Use these as they are
let startDate = '2019-02-18';
let endDate = '2020-02-16';

if (actualInitDatE >= startDate &&
    actualInitDatE <= endDate) {
  console.log('Compared and True');
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>

在将值设置为一天的开始之后,还可以将值保留为矩对象,并使用各种矩方法进行比较,但是我认为字符串版本非常简单,为什么要使其比原来更难? / p>

“这段代码是否在timeZones上有效”是否是未知的,因为您没有解释您实际上要实现的目标。