Last active
February 4, 2020 20:27
-
-
Save vandy/2e10c67e778e17e6b5832fbed39bb948 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Compares a date with today in the client's time zone. The comparison is day-wise, | |
* so that all dates since today's midnight till the next midnight are considered "today". | |
* Yesterday and tomorrow are separate from the past and future. | |
* | |
* @param dateRepresentation {string|number|Date} | |
* @returns {number} | |
* +2 - date is in the future (after tomorrow) | |
* +1 - tomorrow | |
* 0 - today | |
* -1 - yesterday | |
* -2 - date is in the past (before yesterday) | |
*/ | |
export function relativeToLocaleToday(dateRepresentation) { | |
return relativeToDate(dateRepresentation, Date.now()); | |
} | |
/** | |
* Compares a date with the reference date in the client's time zone. The comparison is day-wise, | |
* so that all dates since the date's midnight till the next midnight are considered "same day". | |
* | |
* @param dateRepresentation {string|number|Date} | |
* @param to {string|number|Date} | |
* @returns {number} | |
* +2 - the date is after the reference date (2 days or more) | |
* +1 - the date is next to the reference date | |
* 0 - the same day | |
* -1 - the date is one day before the reference date | |
* -2 - the date is earlier the reference date (2 days or more) | |
*/ | |
export function relativeToDate(dateRepresentation, to) { | |
const date = new Date(dateRepresentation); | |
const referenceDate = new Date(to); | |
if (referenceDate.toDateString() === date.toDateString()) { | |
return 0; | |
} | |
const inFuture = date > referenceDate; | |
const midnight = new Date( | |
referenceDate.getFullYear(), | |
referenceDate.getMonth(), | |
referenceDate.getDate() + (inFuture ? 2 : -1) | |
); | |
if (inFuture) { | |
return midnight > date | |
? 1 | |
: 2; | |
} | |
return midnight <= date | |
? -1 | |
: -2; | |
} | |
/** | |
* Returns a range of dates between 'from' and 'to' exclusively: 'from', [N+1, N+2, ...], 'to'. | |
* If 'from' is greater than 'to', the range is reversed: 'from', [N-1, N-2, ...], 'to'. | |
* If 'include' argument is true and 'from' is the same day as 'to' (time may be different), | |
* the range would contain only one element, which is max('from', 'to'). | |
* | |
* @param from {string|number|Date} | |
* @param to {string|number|Date} | |
* @param [include=false] {boolean} - | |
* include 'from' and/or 'to' to the resulting array. | |
* @param [transform=null] {null|true|Function} - | |
* if null, time of the dates between 'from' and 'to' would be the same as 'from'. | |
* if true, time of the dates would be set to locale midnight, | |
* if Function, each Date in the range would be passed to the function, | |
* returned value is used in the resulting array. | |
* @returns {[]} | |
*/ | |
export function datesRange(from, to, {include = false, transform = null} = {}) { | |
const range = []; | |
from = new Date(from); | |
to = new Date(to); | |
const reversed = from > to; | |
if (reversed) { | |
[from, to] = [to, from]; | |
} | |
const insert = reversed ? range.unshift.bind(range) : range.push.bind(range); | |
const formatter = typeof transform === 'function' ? transform : function (d) { | |
if (transform === true) { | |
d.setHours(0); | |
d.setMinutes(0); | |
d.setSeconds(0); | |
d.setMilliseconds(0); | |
} | |
return d; | |
}; | |
const fromToOffset = relativeToDate(from, to); | |
if (fromToOffset < -1) { | |
const toMidnight = new Date(to.getFullYear(), to.getMonth(), to.getDate()); | |
const nextDay = new Date(from); | |
while (nextDay.setDate(nextDay.getDate() + 1) < toMidnight) { | |
insert(formatter(new Date(nextDay))); | |
} | |
} | |
if (include) { | |
insert(formatter(to)); | |
if (fromToOffset) { | |
const resultFrom = formatter(from); | |
if (reversed) { | |
range.push(resultFrom); | |
} else { | |
range.unshift(resultFrom); | |
} | |
} | |
} | |
return range; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment