我正在编写一个函数,它将为我提供任何给定日期的上一个工作日。工作日表示工作日为工作日,并且该天没有联邦假日。
我的解决方案在今天(案例1)为'2019-06-20T07:00:00.000Z'时有效;即星期四//返回星期三 另外,当今天(第2种情况)为“ 2019-06-24T07:00:00.000Z”(即星期一//返回星期五)时有效
但是在今天(案例3)为2019-05-28T07:00:00.000Z //周二时失败。
对于情况3,它应返回5月24日(星期五)的上一个工作日,因为星期一(5月27日)是假日。对于案例3,它将返回5月27日,星期一。
下面是我的代码,在我或or语句中,我正在检查前一天,但它没有考虑到这一点,
const { DateTime } = require('luxon');// I'm using luxon for DateTime.
function check_previous_business_date(date, timezone) {
const startDate = new Date(DateTime.fromISO(date).setZone(timezone));
const todayTimeStamp = +new Date(startDate); // Unix timestamp in milliseconds
const oneDayTimeStamp = 1000 * 60 * 60 * 24; // Milliseconds in a day
const diff = todayTimeStamp - oneDayTimeStamp;
const yesterdayDate = new Date(diff);
const yesterdayString = yesterdayDate.getFullYear()
+ '-' + (yesterdayDate.getMonth() + 1) + '-' + yesterdayDate.getDate();
for (startDate.setDate(startDate.getDate() - 1);
!startDate.getDay() || startDate.getDay() === 6 ||
federalHolidays.includes(startDate.toISOString().split('T')[0]) ||
federalHolidays.includes(yesterdayString);
startDate.setDate(startDate.getDate() - 1)
) {
}
return startDate.toISOString().split('T')[0];
}
const federalHolidays= [
'2019-5-27',
'2019-09-02',
'2019-10-14',
'2019-11-11',
'2019-11-28',
'2019-12-25',
'2020-01-01',
'2020-01-20',
'2020-02-17',
'2020-05-25',
'2020-07-03',
'2020-09-07',
'2020-10-12',
'2020-11-11',
'2020-11-26',
'2020-12-25',
'2021-01-01',
'2021-01-18',
'2021-02-15',
'2021-05-31',
'2021-07-05',
'2021-09-06',
'2021-10-11',
'2021-11-11',
'2021-11-25',
'2021-12-24',
'2021-12-31',
'2022-01-17',
'2022-02-21',
'2022-05-30',
'2022-07-04',
'2022-09-05',
'2022-10-10',
'2022-11-11',
'2022-11-24',
'2022-12-26',
'2023-01-02',
'2023-01-16',
'2023-02-20',
'2023-05-29',
'2023-07-04',
'2023-09-04',
'2023-10-09',
'2023-11-10',
'2023-11-23',
'2023-12-25',
'2024-01-01',
'2024-01-15',
'2024-02-19',
'2024-05-27',
'2024-07-04',
'2024-09-02',
'2024-10-14',
'2024-11-11',
'2024-11-28',
'2024-12-25',
'2025-01-01',
'2025-01-20',
'2025-02-17',
'2025-05-26',
'2025-07-04',
'2025-09-01',
'2025-10-13',
'2025-11-11',
'2025-11-27',
'2025-12-25',
'2026-01-01',
'2026-01-19',
'2026-02-16',
'2026-05-25',
'2026-07-03',
'2026-09-07',
'2026-10-12',
'2026-11-11',
'2026-11-26',
'2026-12-25',
'2027-01-01',
'2027-01-18',
'2027-02-15',
'2027-05-31',
'2027-07-05',
'2027-09-06',
'2027-10-11',
'2027-11-11',
'2027-11-25',
'2027-12-24',
'2027-12-31',
'2028-01-17',
'2028-02-21',
'2028-05-29',
'2028-07-04',
'2028-09-04',
'2028-10-09',
'2028-11-10',
'2028-11-23',
'2028-12-25',
'2029-01-01',
'2029-01-15',
'2029-02-19',
'2029-05-28',
'2029-07-04',
'2029-09-03',
'2029-10-08',
'2029-11-12',
'2029-11-22',
'2029-12-25'
];
check_previous_business_date('2019-05-28T07:00:00.000Z', 'America/New_York');
// <script //src="https://cdn.jsdelivr.net/npm/luxon@1.21.1/build/global/luxon.min.j//s"></script>
答案 0 :(得分:0)
当您检查假期数组时,您正在检查的是完整日期而不是日期部分。
function check_previous_business_date(date, timezone) {
const startDate = new Date(luxon.DateTime.fromISO(date).setZone(timezone));
const todayTimeStamp = +new Date(startDate); // Unix timestamp in milliseconds
const oneDayTimeStamp = 1000 * 60 * 60 * 24; // Milliseconds in a day
const diff = todayTimeStamp - oneDayTimeStamp;
const yesterdayDate = new Date(diff);
const yesterdayString = yesterdayDate.getFullYear()
+ '-' + (yesterdayDate.getMonth() + 1) + '-' + yesterdayDate.getDate();
for (startDate.setDate(startDate.getDate() - 1);
!startDate.getDay() || startDate.getDay() === 6 ||
federalHolidays.includes(startDate.toISOString().split('T')[0]) ||
federalHolidays.includes(yesterdayString);
startDate.setDate(startDate.getDate() - 1)
) {
}
return startDate.toISOString().split('T')[0];
}
const federalHolidays= [
'2019-05-27',
'2019-09-02',
'2019-10-14',
'2019-11-11'
];
console.log('Prev. day of 2019-05-28 is ',check_previous_business_date('2019-05-28T07:00:00.000Z', 'America/New_York'));
console.log('Prev. day of 2019-06-20 is ',check_previous_business_date('2019-06-20T07:00:00.000Z', 'America/New_York'));
<script src="https://cdn.jsdelivr.net/npm/luxon@1.21.1/build/global/luxon.min.js"></script>
答案 1 :(得分:0)
您没有充分利用Luxon的潜力。您应该将日期保留为Luxon对象,使用Luxon的方法对其进行所有操作,然后将日期转换为字符串。
为此,我定义了一个辅助函数prevBusinessDayHelper
,该函数采用Luxon日期时间并返回代表前一个工作日的日期时间。它完全按照Luxon日期时间操作,这很容易。然后在外部函数中,我与Luxon日期时间之间进行转换。
const DateTime = luxon.DateTime;
// use a Set to make lookups cheaper
const federalHolidays = new Set([
'2019-05-27', // <-- you were missing the 0 here in yours
'2019-09-02',
// snip
]);
// recursion is good here because it's very shallow
const prevBusinessDayHelper = dt => {
// use luxon's tools!
const yest = dt.minus({ days: 1 });
if (yest.weekday == 6 || yest.weekday == 7 || federalHolidays.has(yest.toISODate()))
return prevBusinessDayHelper(yest);
return yest;
};
const prevBusinessDay = (isoString, zone) => {
const dt = DateTime.fromISO(isoString).setZone(zone);
return prevBusinessDayHelper(dt).toISODate();
};
console.log(prevBusinessDay("2019-05-28T07:00:00.000Z", "America/New_York"));
<script src="https://cdn.jsdelivr.net/npm/luxon@1.21.1/build/global/luxon.min.js"></script>