fix: DateToDay (#1125)

This commit is contained in:
Chetan Patil
2022-10-10 08:01:58 +02:00
committed by GitHub
parent e32fdce52f
commit d94929ea0d
2 changed files with 52 additions and 39 deletions

View File

@ -9,35 +9,11 @@
algorithm shown below gives us the number of the day and algorithm shown below gives us the number of the day and
finally converts it to the name of the day. finally converts it to the name of the day.
Algorithm & Explanation : https://cs.uwaterloo.ca/~alopez-o/math-faq/node73.html Algorithm & Explanation : https://en.wikipedia.org/wiki/Zeller%27s_congruence
*/ */
// March is taken as the first month of the year. // Array holding name of the day: Saturday - Sunday - Friday => 0 - 1 - 6
const calcMonthList = { const daysNameArr = ['Saturday', 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
1: 11,
2: 12,
3: 1,
4: 2,
5: 3,
6: 4,
7: 5,
8: 6,
9: 7,
10: 8,
11: 9,
12: 10
}
// show the week day in a number : Sunday - Saturday => 0 - 6
const daysNameList = { // weeks-day
0: 'Sunday',
1: 'Monday',
2: 'Tuesday',
3: 'Wednesday',
4: 'Thursday',
5: 'Friday',
6: 'Saturday'
}
const DateToDay = (date) => { const DateToDay = (date) => {
// firstly, check that input is a string or not. // firstly, check that input is a string or not.
@ -45,18 +21,40 @@ const DateToDay = (date) => {
return new TypeError('Argument is not a string.') return new TypeError('Argument is not a string.')
} }
// extract the date // extract the date
const [day, month, year] = date.split('/').map((x) => Number(x)) let [day, month, year] = date.split('/').map((x) => Number(x))
// check the data are valid or not. // check the data are valid or not.
if (day < 0 || day > 31 || month > 12 || month < 0) { if (day < 1 || day > 31 || month > 12 || month < 1) {
return new TypeError('Date is not valid.') return new TypeError('Date is not valid.')
} }
// divide year to century and yearDigit value.
const yearDigit = (year % 100) // In case of Jan and Feb:
// Year: we consider it as previous year
// e.g., 1/1/1987 here year is 1986 (-1)
// Month: we consider value as 13 & 14 respectively
if (month < 3) {
year--
month += 12
}
// divide year into century and the last two digits of the century
const yearDigits = year % 100
const century = Math.floor(year / 100) const century = Math.floor(year / 100)
// Apply the algorithm shown above
const weekDay = Math.abs((day + Math.floor((2.6 * calcMonthList[month]) - 0.2) - (2 * century) + yearDigit + Math.floor(yearDigit / 4) + Math.floor(century / 4)) % 7) /*
// return the weekDay name. In mathematics, remainders of divisions are usually defined to always be positive;
return daysNameList[weekDay] As an example, -2 mod 7 = 5.
Many programming languages including JavaScript implement the remainder of `n % m` as `sign(n) * (abs(n) % m)`.
This means the result has the same sign as the numerator. Here, `-2 % 7 = -1 * (2 % 7) = -2`.
To ensure a positive numerator, the formula is adapted: `- 2 * century` is replaced with `+ 5 * century`
which does not alter the resulting numbers mod 7 since `7 - 2 = 5`
The following example shows the issue with modulo division:
Without the adaption, the formula yields `weekDay = -6` for the date 2/3/2014;
With the adaption, it yields the positive result `weekDay = 7 - 6 = 1` (Sunday), which is what we need to index the array
*/
const weekDay = (day + Math.floor((month + 1) * 2.6) + yearDigits + Math.floor(yearDigits / 4) + Math.floor(century / 4) + 5 * century) % 7
return daysNameArr[weekDay] // name of the weekday
} }
// Example : DateToDay("18/12/2020") => Friday // Example : DateToDay("18/12/2020") => Friday

View File

@ -1,8 +1,8 @@
import { DateToDay } from '../DateToDay' import { DateToDay } from '../DateToDay'
test('The date 18/02/2001 is Monday', () => { test('The date 18/02/2001 is Sunday', () => {
const res = DateToDay('18/02/2001') const res = DateToDay('18/02/2001')
expect(res).toBe('Monday') expect(res).toBe('Sunday')
}) })
test('The date 18/12/2020 is Friday', () => { test('The date 18/12/2020 is Friday', () => {
@ -14,7 +14,22 @@ test('The date 12/12/2012 is Wednesday', () => {
const res = DateToDay('12/12/2012') const res = DateToDay('12/12/2012')
expect(res).toBe('Wednesday') expect(res).toBe('Wednesday')
}) })
test('The date 01/01/2001 is Friday', () => { test('The date 01/01/2001 is Monday', () => {
const res = DateToDay('01/01/2001') const res = DateToDay('01/01/2001')
expect(res).toBe('Friday') expect(res).toBe('Monday')
})
test('The date 1/1/2020 is Wednesday', () => {
const res = DateToDay('1/1/2020')
expect(res).toBe('Wednesday')
})
test('The date 2/3/2014 is Sunday', () => {
const res = DateToDay('2/3/2014')
expect(res).toBe('Sunday')
})
test('The date 28/2/2017 is Tuesday', () => {
const res = DateToDay('28/2/2017')
expect(res).toBe('Tuesday')
}) })