首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在JavaScript中计算不包括周末和联邦节假日的前一个工作日

在JavaScript中计算不包括周末和联邦节假日的前一个工作日
EN

Stack Overflow用户
提问于 2019-11-15 18:46:14
回答 2查看 835关注 0票数 1

我正在写一个函数,它将为我提供任何给定日期的前一个工作日。工作日的意思是工作日,那天没有联邦假日。

我的解决方案适用于今天(案例1)为‘2019-06-20T07:00:00.000Z’的情况;即星期四//返回星期三,也适用于今天(案例2)为'2019-06-24T07:00:00.000Z‘的情况,即星期一//返回星期五

但当今天(案例3)是2019-05-28T07:00:00.000Z //星期二时失败。

对于情况3,它应该返回前一个工作日,因为5月24日(星期五)是假日。对于案例3,它返回5月27日,星期一。

下面是我的代码,在我的or语句中,我正在检查前一天的情况,但它没有考虑到这一点,

代码语言:javascript
复制
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>
EN

回答 2

Stack Overflow用户

发布于 2019-12-12 01:35:14

你没有充分利用Luxon的潜力。您应该将date保留为Luxon对象,使用Luxon的方法对其执行所有操作,然后将date转换为字符串。

为此,我定义了一个辅助函数prevBusinessDayHelper,该函数接受Luxon datetime并返回表示前一个工作日的日期时间。它完全按照Luxon datetimes来操作,这使得它变得很容易。然后,在外部函数中,我在Luxon datetimes之间进行转换。

代码语言:javascript
复制
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"));
代码语言:javascript
复制
<script src="https://cdn.jsdelivr.net/npm/luxon@1.21.1/build/global/luxon.min.js"></script>

票数 2
EN

Stack Overflow用户

发布于 2019-11-15 20:42:11

当您检查假日数组时,您检查的是完整日期而不是日期部分。

代码语言:javascript
复制
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'));
代码语言:javascript
复制
<script src="https://cdn.jsdelivr.net/npm/luxon@1.21.1/build/global/luxon.min.js"></script>

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58875371

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档