feat: support relativeTime query constraint on Postgres (#7747)
This commit is contained in:
132
src/Utils.js
132
src/Utils.js
@@ -200,6 +200,138 @@ class Utils {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the relative date based on a string.
|
||||
* @param {String} text The string to interpret the date from.
|
||||
* @param {Date} now The date the string is comparing against.
|
||||
* @returns {Object} The relative date object.
|
||||
**/
|
||||
static relativeTimeToDate(text, now = new Date()) {
|
||||
text = text.toLowerCase();
|
||||
let parts = text.split(' ');
|
||||
|
||||
// Filter out whitespace
|
||||
parts = parts.filter(part => part !== '');
|
||||
|
||||
const future = parts[0] === 'in';
|
||||
const past = parts[parts.length - 1] === 'ago';
|
||||
|
||||
if (!future && !past && text !== 'now') {
|
||||
return {
|
||||
status: 'error',
|
||||
info: "Time should either start with 'in' or end with 'ago'",
|
||||
};
|
||||
}
|
||||
|
||||
if (future && past) {
|
||||
return {
|
||||
status: 'error',
|
||||
info: "Time cannot have both 'in' and 'ago'",
|
||||
};
|
||||
}
|
||||
|
||||
// strip the 'ago' or 'in'
|
||||
if (future) {
|
||||
parts = parts.slice(1);
|
||||
} else {
|
||||
// past
|
||||
parts = parts.slice(0, parts.length - 1);
|
||||
}
|
||||
|
||||
if (parts.length % 2 !== 0 && text !== 'now') {
|
||||
return {
|
||||
status: 'error',
|
||||
info: 'Invalid time string. Dangling unit or number.',
|
||||
};
|
||||
}
|
||||
|
||||
const pairs = [];
|
||||
while (parts.length) {
|
||||
pairs.push([parts.shift(), parts.shift()]);
|
||||
}
|
||||
|
||||
let seconds = 0;
|
||||
for (const [num, interval] of pairs) {
|
||||
const val = Number(num);
|
||||
if (!Number.isInteger(val)) {
|
||||
return {
|
||||
status: 'error',
|
||||
info: `'${num}' is not an integer.`,
|
||||
};
|
||||
}
|
||||
|
||||
switch (interval) {
|
||||
case 'yr':
|
||||
case 'yrs':
|
||||
case 'year':
|
||||
case 'years':
|
||||
seconds += val * 31536000; // 365 * 24 * 60 * 60
|
||||
break;
|
||||
|
||||
case 'wk':
|
||||
case 'wks':
|
||||
case 'week':
|
||||
case 'weeks':
|
||||
seconds += val * 604800; // 7 * 24 * 60 * 60
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
case 'day':
|
||||
case 'days':
|
||||
seconds += val * 86400; // 24 * 60 * 60
|
||||
break;
|
||||
|
||||
case 'hr':
|
||||
case 'hrs':
|
||||
case 'hour':
|
||||
case 'hours':
|
||||
seconds += val * 3600; // 60 * 60
|
||||
break;
|
||||
|
||||
case 'min':
|
||||
case 'mins':
|
||||
case 'minute':
|
||||
case 'minutes':
|
||||
seconds += val * 60;
|
||||
break;
|
||||
|
||||
case 'sec':
|
||||
case 'secs':
|
||||
case 'second':
|
||||
case 'seconds':
|
||||
seconds += val;
|
||||
break;
|
||||
|
||||
default:
|
||||
return {
|
||||
status: 'error',
|
||||
info: `Invalid interval: '${interval}'`,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const milliseconds = seconds * 1000;
|
||||
if (future) {
|
||||
return {
|
||||
status: 'success',
|
||||
info: 'future',
|
||||
result: new Date(now.valueOf() + milliseconds),
|
||||
};
|
||||
} else if (past) {
|
||||
return {
|
||||
status: 'success',
|
||||
info: 'past',
|
||||
result: new Date(now.valueOf() - milliseconds),
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
status: 'success',
|
||||
info: 'present',
|
||||
result: new Date(now.valueOf()),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Utils;
|
||||
|
||||
Reference in New Issue
Block a user