mirror of
https://github.com/TheAlgorithms/JavaScript.git
synced 2025-07-05 00:01:37 +08:00
fix: DateToDay (#1125)
This commit is contained in:
@ -9,35 +9,11 @@
|
||||
algorithm shown below gives us the number of the day and
|
||||
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.
|
||||
const calcMonthList = {
|
||||
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'
|
||||
}
|
||||
// Array holding name of the day: Saturday - Sunday - Friday => 0 - 1 - 6
|
||||
const daysNameArr = ['Saturday', 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
|
||||
|
||||
const DateToDay = (date) => {
|
||||
// firstly, check that input is a string or not.
|
||||
@ -45,18 +21,40 @@ const DateToDay = (date) => {
|
||||
return new TypeError('Argument is not a string.')
|
||||
}
|
||||
// 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.
|
||||
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.')
|
||||
}
|
||||
// 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)
|
||||
// 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.
|
||||
return daysNameList[weekDay]
|
||||
|
||||
/*
|
||||
In mathematics, remainders of divisions are usually defined to always be positive;
|
||||
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
|
||||
|
@ -1,8 +1,8 @@
|
||||
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')
|
||||
expect(res).toBe('Monday')
|
||||
expect(res).toBe('Sunday')
|
||||
})
|
||||
|
||||
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')
|
||||
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')
|
||||
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')
|
||||
})
|
||||
|
Reference in New Issue
Block a user