test: parse-date
This commit is contained in:
parent
cd0043b774
commit
cf09a77e25
|
|
@ -1,4 +1,4 @@
|
|||
import parseDate from '@/utils/parse-date';
|
||||
import { parseDate } from '@/utils/parse-date';
|
||||
const title = require('title');
|
||||
|
||||
// convert a string into title case
|
||||
|
|
@ -21,7 +21,7 @@ const convertDateToISO8601 = (date?: string | Date | number | null) => {
|
|||
}
|
||||
if (typeof date !== 'object') {
|
||||
// some routes may call `.toUTCString()` before passing the date to ctx...
|
||||
date = parseDate.parse(date);
|
||||
date = parseDate(date);
|
||||
}
|
||||
return date.toISOString();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
const { parseRelativeDate } = require('@/utils/parse-date');
|
||||
const MockDate = require('mockdate');
|
||||
import { describe, expect, it } from '@jest/globals';
|
||||
import { parseRelativeDate } from '@/utils/parse-date';
|
||||
import MockDate from 'mockdate';
|
||||
|
||||
describe('parseRelativeDate', () => {
|
||||
const second = 1000;
|
||||
|
|
@ -125,84 +125,83 @@ const toDurations = (matches: string[]) => {
|
|||
return durations;
|
||||
};
|
||||
|
||||
export default {
|
||||
parse: (date: string | number, ...options: any) => dayjs(date, ...options).toDate(),
|
||||
parseRelativeDate: (date: string) => {
|
||||
// 预处理日期字符串 date
|
||||
export const parseDate = (date: string | number, ...options: any) => dayjs(date, ...options).toDate();
|
||||
|
||||
const theDate = toDate(date);
|
||||
export const parseRelativeDate = (date: string) => {
|
||||
// 预处理日期字符串 date
|
||||
|
||||
// 将 `\d+年\d+月...\d+秒前` 分割成 `['\d+年', ..., '\d+秒前']`
|
||||
const theDate = toDate(date);
|
||||
|
||||
const matches = theDate.match(/(?:\D+)?\d+(?!:|-|\/|(a|p)m)\D+/g);
|
||||
// 将 `\d+年\d+月...\d+秒前` 分割成 `['\d+年', ..., '\d+秒前']`
|
||||
|
||||
if (matches) {
|
||||
// 获得最后的时间单元,如 `\d+秒前`
|
||||
const matches = theDate.match(/(?:\D+)?\d+(?!:|-|\/|(a|p)m)\D+/g);
|
||||
|
||||
const lastMatch = matches.pop();
|
||||
if (matches) {
|
||||
// 获得最后的时间单元,如 `\d+秒前`
|
||||
|
||||
if (lastMatch) {
|
||||
// 若最后的时间单元含有 `前`、`以前`、`之前` 等标识字段,减去相应的时间长度
|
||||
// 如 `1分10秒前`
|
||||
const lastMatch = matches.pop();
|
||||
|
||||
const beforeMatches = /(.*)(?:[之以]?前|ago)$/.exec(lastMatch);
|
||||
if (beforeMatches) {
|
||||
matches.push(beforeMatches[1]);
|
||||
return dayjs()
|
||||
.subtract(dayjs.duration(toDurations(matches)))
|
||||
.toDate();
|
||||
}
|
||||
if (lastMatch) {
|
||||
// 若最后的时间单元含有 `前`、`以前`、`之前` 等标识字段,减去相应的时间长度
|
||||
// 如 `1分10秒前`
|
||||
|
||||
// 若最后的时间单元含有 `后`、`以后`、`之后` 等标识字段,加上相应的时间长度
|
||||
// 如 `1分10秒后`
|
||||
const beforeMatches = /(.*)(?:[之以]?前|ago)$/.exec(lastMatch);
|
||||
if (beforeMatches) {
|
||||
matches.push(beforeMatches[1]);
|
||||
return dayjs()
|
||||
.subtract(dayjs.duration(toDurations(matches)))
|
||||
.toDate();
|
||||
}
|
||||
|
||||
const afterMatches = /(?:^in(.*)|(.*)[之以]?[后後])$/.exec(lastMatch);
|
||||
if (afterMatches) {
|
||||
matches.push(afterMatches[1] ?? afterMatches[2]);
|
||||
return dayjs()
|
||||
// 若最后的时间单元含有 `后`、`以后`、`之后` 等标识字段,加上相应的时间长度
|
||||
// 如 `1分10秒后`
|
||||
|
||||
const afterMatches = /(?:^in(.*)|(.*)[之以]?[后後])$/.exec(lastMatch);
|
||||
if (afterMatches) {
|
||||
matches.push(afterMatches[1] ?? afterMatches[2]);
|
||||
return dayjs()
|
||||
.add(dayjs.duration(toDurations(matches)))
|
||||
.toDate();
|
||||
}
|
||||
|
||||
// 以下处理日期字符串 date 含有特殊词的情形
|
||||
// 如 `今天1点10分`
|
||||
|
||||
matches.push(lastMatch);
|
||||
}
|
||||
const firstMatch = matches.shift();
|
||||
|
||||
if (firstMatch) {
|
||||
for (const w of words) {
|
||||
const wordMatches = w.regExp.exec(firstMatch);
|
||||
if (wordMatches) {
|
||||
matches.unshift(wordMatches[1]);
|
||||
|
||||
// 取特殊词对应日零时为起点,加上相应的时间长度
|
||||
|
||||
return w.startAt
|
||||
.set('hour', 0)
|
||||
.set('minute', 0)
|
||||
.set('second', 0)
|
||||
.set('millisecond', 0)
|
||||
.add(dayjs.duration(toDurations(matches)))
|
||||
.toDate();
|
||||
}
|
||||
|
||||
// 以下处理日期字符串 date 含有特殊词的情形
|
||||
// 如 `今天1点10分`
|
||||
|
||||
matches.push(lastMatch);
|
||||
}
|
||||
const firstMatch = matches.shift();
|
||||
|
||||
if (firstMatch) {
|
||||
for (const w of words) {
|
||||
const wordMatches = w.regExp.exec(firstMatch);
|
||||
if (wordMatches) {
|
||||
matches.unshift(wordMatches[1]);
|
||||
|
||||
// 取特殊词对应日零时为起点,加上相应的时间长度
|
||||
|
||||
return w.startAt
|
||||
.set('hour', 0)
|
||||
.set('minute', 0)
|
||||
.set('second', 0)
|
||||
.set('millisecond', 0)
|
||||
.add(dayjs.duration(toDurations(matches)))
|
||||
.toDate();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 若日期字符串 date 不匹配 patterns 中所有模式,则默认为 `特殊词 + 标准时间格式` 的情形,此时直接将特殊词替换为对应日期
|
||||
// 如今天为 `2022-03-22`,则 `今天 20:00` => `2022-03-22 20:00`
|
||||
|
||||
for (const w of words) {
|
||||
const wordMatches = w.regExp.exec(theDate);
|
||||
if (wordMatches) {
|
||||
// The default parser of dayjs() can parse '8:00 pm' but not '8:00pm'
|
||||
// so we need to insert a space in between
|
||||
return dayjs(`${w.startAt.format('YYYY-MM-DD')} ${/a|pm$/.test(wordMatches[1]) ? wordMatches[1].replace(/a|pm/, ' $&') : wordMatches[1]}`).toDate();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 若日期字符串 date 不匹配 patterns 中所有模式,则默认为 `特殊词 + 标准时间格式` 的情形,此时直接将特殊词替换为对应日期
|
||||
// 如今天为 `2022-03-22`,则 `今天 20:00` => `2022-03-22 20:00`
|
||||
|
||||
return date;
|
||||
},
|
||||
for (const w of words) {
|
||||
const wordMatches = w.regExp.exec(theDate);
|
||||
if (wordMatches) {
|
||||
// The default parser of dayjs() can parse '8:00 pm' but not '8:00pm'
|
||||
// so we need to insert a space in between
|
||||
return dayjs(`${w.startAt.format('YYYY-MM-DD')} ${/a|pm$/.test(wordMatches[1]) ? wordMatches[1].replace(/a|pm/, ' $&') : wordMatches[1]}`).toDate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return date;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue