比较 ISO 格式的日期范围
Compare date ranges in ISO format
我有两个日期范围,一个来自 API,另一个来自用户输入。两者都是ISO格式。
日期范围从 API:
dateStart 2019-04-01T03:04:00Z
dateStop 2019-04-01T03:05:00Z
用户输入的日期范围:
convertedDateFrom 2020-09-15T18:30:00.000Z
convertedDateTo 2020-09-21T18:30:00.000Z
我想将 date range from user input
转换为 date range from API
。我怎样才能做到这一点?
EXPECTED: I want to compare the values two date-ranges and depending on that
I will perform certain export functionality.
The user input date-range could
- fall completely within the date-range of the API
- or at least one of the date values could fall or overlap within the
date-range from the API.
应该与 API 中的日期范围重叠。
这是我的date range picker handle()
handleDatePickerChange = (setSelectedDayRange) => {
console.log("initializing handleDatePickerChange()");
console.log("setSelectedDayRange", setSelectedDayRange);
// TODO
// convert the dates
let convertedDateFrom = moment(setSelectedDayRange.from).toISOString();
console.log("convertedDateFrom", convertedDateFrom);
let convertedDateTo = moment(setSelectedDayRange.to).toISOString();
console.log("convertedDateTo", convertedDateTo);
// compare dates
// if(convertedDateFrom === )
// check if data exists
this.setState({
selectedDayRange: setSelectedDayRange,
});
};
再见,你可以这样使用moment提供的函数isBetween
:
// interval comes from API
let dateAPIFrom = moment().toISOString();
let dateAPITo = moment().add(2, "days").toISOString();
// user date interval
let convertedDateFrom = moment(setSelectedDayRange.from).toISOString();
let convertedDateTo = moment(setSelectedDayRange.to).toISOString();
if (
moment(convertedDateFrom)
.subtract(1, "month")
.isBetween(dateAPIFrom, dateAPITo) &&
moment(convertedDateTo)
.subtract(1, "month")
.isBetween(dateAPIFrom, dateAPITo)
) {
//The user input date-range fall completely within the date-range of the API
} else if (
moment(convertedDateFrom)
.subtract(1, "month")
.isBetween(dateAPIFrom, dateAPITo) ||
moment(convertedDateTo)
.subtract(1, "month")
.isBetween(dateAPIFrom, dateAPITo)
) {
//or at least one of the date values could fall or overlap within the date-range from the API.
}
.subtract(1, "month")
因为 moment({day: 19, month: 8, year: 2020}).toISOString()
returns 总是 month + 1
.
Here 您的 codesandbox 已修改。
它们都是 ISO-8601 日期,可以很容易地转换为原生 Date
对象,可以转换为自 Unix 纪元以来的毫秒数。您不需要任何复杂的逻辑,甚至不需要为此使用 moment
。
/**
* If result is negative, the first date is earlier
* If result is positive, the second date is earlier
* If result is 0, both dates are exactly the same
*/
const compareIsoDates = (isoString1, isoString2) => {
return new Date(isoString1).valueOf() - new Date(isoString2).valueOf()
}
// result is -46106760000, meaning first date is earlier
console.log(compareIsoDates('2019-04-01T03:04:00Z', '2020-09-15T18:30:00.000Z'))
/**
* strictly between (cannot be the same as start or end)
* if you want to allow same as start and end, change to
* >= and <= instead of > and <
*/
const isStrictlyBetween = (targetDate, [startDate, endDate]) => {
return compareIsoDates(targetDate, startDate) > 0
&& compareIsoDates(targetDate, endDate) < 0
}
// true
console.log(isStrictlyBetween(
'2020-05-01T00:00:00.000Z',
['2020-04-20T18:30:00Z', '2020-05-10T00:00:00Z']
))
// you can also use `compareIsoDates` a sort function to sort an array of
// ISO strings in ascending order (earliest to latest)
console.log([
"1998-02-12T08:18:27.991Z",
"2005-03-19T19:48:59.501Z",
"1997-05-01T14:58:13.848Z",
"2008-08-31T01:30:11.880Z",
"2004-08-05T16:07:55.443Z"
].sort(compareIsoDates))
ISO 日期格式的一大优点是它们可以按字母顺序排序。
这意味着虽然您可以将其转换为 Date
/ moment
/ 等。您将获得与将它们作为字符串进行比较时完全相同的结果。
例如,您可以将 Lionel 的 compareISODates
函数编写为:
/**
* If result is negative, the first date is earlier
* If result is positive, the second date is earlier
* If result is 0, both dates are exactly the same
*/
const compareISODates = (isoString1, isoString2) => {
return isoString1.localeCompare(isoString2);
};
或者另一个例子,convertedDateFrom/To
完全属于dateStart/End
你可以简单地检查是否
convertedDateFrom >= dateStart && convertedDateTo <= dateEnd
当然,如果您需要更复杂的逻辑,您应该使用上面提到的日期库之一。
我有两个日期范围,一个来自 API,另一个来自用户输入。两者都是ISO格式。
日期范围从 API:
dateStart 2019-04-01T03:04:00Z
dateStop 2019-04-01T03:05:00Z
用户输入的日期范围:
convertedDateFrom 2020-09-15T18:30:00.000Z
convertedDateTo 2020-09-21T18:30:00.000Z
我想将 date range from user input
转换为 date range from API
。我怎样才能做到这一点?
EXPECTED: I want to compare the values two date-ranges and depending on that
I will perform certain export functionality.
The user input date-range could
- fall completely within the date-range of the API
- or at least one of the date values could fall or overlap within the
date-range from the API.
应该与 API 中的日期范围重叠。
这是我的date range picker handle()
handleDatePickerChange = (setSelectedDayRange) => {
console.log("initializing handleDatePickerChange()");
console.log("setSelectedDayRange", setSelectedDayRange);
// TODO
// convert the dates
let convertedDateFrom = moment(setSelectedDayRange.from).toISOString();
console.log("convertedDateFrom", convertedDateFrom);
let convertedDateTo = moment(setSelectedDayRange.to).toISOString();
console.log("convertedDateTo", convertedDateTo);
// compare dates
// if(convertedDateFrom === )
// check if data exists
this.setState({
selectedDayRange: setSelectedDayRange,
});
};
再见,你可以这样使用moment提供的函数isBetween
:
// interval comes from API
let dateAPIFrom = moment().toISOString();
let dateAPITo = moment().add(2, "days").toISOString();
// user date interval
let convertedDateFrom = moment(setSelectedDayRange.from).toISOString();
let convertedDateTo = moment(setSelectedDayRange.to).toISOString();
if (
moment(convertedDateFrom)
.subtract(1, "month")
.isBetween(dateAPIFrom, dateAPITo) &&
moment(convertedDateTo)
.subtract(1, "month")
.isBetween(dateAPIFrom, dateAPITo)
) {
//The user input date-range fall completely within the date-range of the API
} else if (
moment(convertedDateFrom)
.subtract(1, "month")
.isBetween(dateAPIFrom, dateAPITo) ||
moment(convertedDateTo)
.subtract(1, "month")
.isBetween(dateAPIFrom, dateAPITo)
) {
//or at least one of the date values could fall or overlap within the date-range from the API.
}
.subtract(1, "month")
因为 moment({day: 19, month: 8, year: 2020}).toISOString()
returns 总是 month + 1
.
Here 您的 codesandbox 已修改。
它们都是 ISO-8601 日期,可以很容易地转换为原生 Date
对象,可以转换为自 Unix 纪元以来的毫秒数。您不需要任何复杂的逻辑,甚至不需要为此使用 moment
。
/**
* If result is negative, the first date is earlier
* If result is positive, the second date is earlier
* If result is 0, both dates are exactly the same
*/
const compareIsoDates = (isoString1, isoString2) => {
return new Date(isoString1).valueOf() - new Date(isoString2).valueOf()
}
// result is -46106760000, meaning first date is earlier
console.log(compareIsoDates('2019-04-01T03:04:00Z', '2020-09-15T18:30:00.000Z'))
/**
* strictly between (cannot be the same as start or end)
* if you want to allow same as start and end, change to
* >= and <= instead of > and <
*/
const isStrictlyBetween = (targetDate, [startDate, endDate]) => {
return compareIsoDates(targetDate, startDate) > 0
&& compareIsoDates(targetDate, endDate) < 0
}
// true
console.log(isStrictlyBetween(
'2020-05-01T00:00:00.000Z',
['2020-04-20T18:30:00Z', '2020-05-10T00:00:00Z']
))
// you can also use `compareIsoDates` a sort function to sort an array of
// ISO strings in ascending order (earliest to latest)
console.log([
"1998-02-12T08:18:27.991Z",
"2005-03-19T19:48:59.501Z",
"1997-05-01T14:58:13.848Z",
"2008-08-31T01:30:11.880Z",
"2004-08-05T16:07:55.443Z"
].sort(compareIsoDates))
ISO 日期格式的一大优点是它们可以按字母顺序排序。
这意味着虽然您可以将其转换为 Date
/ moment
/ 等。您将获得与将它们作为字符串进行比较时完全相同的结果。
例如,您可以将 Lionel 的 compareISODates
函数编写为:
/**
* If result is negative, the first date is earlier
* If result is positive, the second date is earlier
* If result is 0, both dates are exactly the same
*/
const compareISODates = (isoString1, isoString2) => {
return isoString1.localeCompare(isoString2);
};
或者另一个例子,convertedDateFrom/To
完全属于dateStart/End
你可以简单地检查是否
convertedDateFrom >= dateStart && convertedDateTo <= dateEnd
当然,如果您需要更复杂的逻辑,您应该使用上面提到的日期库之一。