fix: edge cases for dates where the next month had fewer days than the current one

This commit is contained in:
kolaente 2022-01-30 12:38:17 +01:00
parent 931941359b
commit d913fa1745
No known key found for this signature in database
GPG key ID: F40E70337AB24C9B
2 changed files with 43 additions and 16 deletions

View file

@ -302,17 +302,17 @@ const getDayFromText = (text: string) => {
const day = parseInt(results[0]) const day = parseInt(results[0])
date.setDate(day) date.setDate(day)
// If the parsed day is the 31st but the next month only has 30 days, setting the day to 31 will "overflow" the // If the parsed day is the 31st (or 29+ and the next month is february) but the next month only has 30 days,
// date to the next month, but the first. // setting the day to 31 will "overflow" the date to the next month, but the first.
// This would look like a very weired bug. Now, to prevent that, we check if the day is the same as parsed after // This would look like a very weired bug. Now, to prevent that, we check if the day is the same as parsed after
// setting it for the first time and set it again if it isn't - that would mean the month overflowed. // setting it for the first time and set it again if it isn't - that would mean the month overflowed.
if (day === 31 && date.getDate() !== day) { while (date < now) {
date.setDate(day)
}
if (date < now) {
date.setMonth(date.getMonth() + 1) date.setMonth(date.getMonth() + 1)
} }
if (date.getDate() !== day) {
date.setDate(day)
}
return { return {
foundText: results[0], foundText: results[0],

View file

@ -1,4 +1,4 @@
import {describe, it, expect} from 'vitest' import {beforeEach, afterEach, describe, it, expect, vi} from 'vitest'
import {parseTaskText} from './parseTaskText' import {parseTaskText} from './parseTaskText'
import {getDateFromText, getDateFromTextIn} from '../helpers/time/parseDate' import {getDateFromText, getDateFromTextIn} from '../helpers/time/parseDate'
@ -6,6 +6,14 @@ import {calculateDayInterval} from '../helpers/time/calculateDayInterval'
import priorities from '../models/constants/priorities.json' import priorities from '../models/constants/priorities.json'
describe('Parse Task Text', () => { describe('Parse Task Text', () => {
beforeEach(() => {
vi.useFakeTimers()
})
afterEach(() => {
vi.useRealTimers()
})
it('should return text with no intents as is', () => { it('should return text with no intents as is', () => {
expect(parseTaskText('Lorem Ipsum').text).toBe('Lorem Ipsum') expect(parseTaskText('Lorem Ipsum').text).toBe('Lorem Ipsum')
}) })
@ -211,17 +219,36 @@ describe('Parse Task Text', () => {
expect(`${result.date.getHours()}:${result.date.getMinutes()}`).toBe('14:0') expect(`${result.date.getHours()}:${result.date.getMinutes()}`).toBe('14:0')
}) })
it('should recognize dates of the month in the past but next month', () => { it('should recognize dates of the month in the past but next month', () => {
const date = new Date() const time = new Date(2022, 0, 15)
date.setDate(date.getDate() - 1) vi.setSystemTime(time)
const result = parseTaskText(`Lorem Ipsum ${date.getDate()}nd`)
const result = parseTaskText(`Lorem Ipsum ${time.getDate() - 1}th`)
expect(result.text).toBe('Lorem Ipsum') expect(result.text).toBe('Lorem Ipsum')
expect(result.date.getDate()).toBe(date.getDate()) expect(result.date.getDate()).toBe(time.getDate() - 1)
expect(result.date.getMonth()).toBe(time.getMonth() + 1)
})
it('should recognize dates of the month in the past but next month when february is the next month', () => {
const jan = new Date(2022, 0, 30)
vi.setSystemTime(jan)
const nextMonthWithDate = result.date.getDate() === 31 const result = parseTaskText(`Lorem Ipsum ${jan.getDate() - 1}th`)
? (date.getMonth() + 2) % 12
: (date.getMonth() + 1) % 12 const expectedDate = new Date(2022, 2, jan.getDate() - 1)
expect(result.date.getMonth()).toBe(nextMonthWithDate) expect(result.text).toBe('Lorem Ipsum')
expect(result.date.getDate()).toBe(expectedDate.getDate())
expect(result.date.getMonth()).toBe(expectedDate.getMonth())
})
it('should recognize dates of the month in the past but next month when the next month has less days than this one', () => {
const mar = new Date(2022, 2, 32)
vi.setSystemTime(mar)
const result = parseTaskText(`Lorem Ipsum 31st`)
const expectedDate = new Date(2022, 4, 31)
expect(result.text).toBe('Lorem Ipsum')
expect(result.date.getDate()).toBe(expectedDate.getDate())
expect(result.date.getMonth()).toBe(expectedDate.getMonth())
}) })
it('should recognize dates of the month in the future', () => { it('should recognize dates of the month in the future', () => {
const nextDay = new Date(+new Date() + 60 * 60 * 24 * 1000) const nextDay = new Date(+new Date() + 60 * 60 * 24 * 1000)