mirror of
https://github.com/TheAlgorithms/JavaScript.git
synced 2025-07-05 08:16:50 +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
|
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
|
||||||
|
@ -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')
|
||||||
})
|
})
|
||||||
|
Reference in New Issue
Block a user