【问题标题】:How to calculate days between two date excluding weekends in angularjs? [duplicate]如何计算两个日期之间的天数,不包括angularjs中的周末? [复制]
【发布时间】:2020-01-23 03:20:02
【问题描述】:

在我的应用程序中,我有两个日期选择器作为开始日期和结束日期。当用户选择开始和结束日期时,系统将显示两个日期之间的天数,但不包括周六和周日。 angularjs如何计算?

【问题讨论】:

  • 我使用 moment.js momentjs.com 你可以将它添加到你的 package.json 并且也许在你的应用程序中使用它
  • 并非所有地方或文化都认为周六和周日是非工作日或周末。
  • 所需结果取决于日期是否应包含在内。 1 月 1 日至 1 月 1 日是一个工作日还是没有? 1 月 1 日到 1 月 2 日是一天还是两天?规则会因业务需求而异。
  • 我已经使用 Angular 框架和 Moment.js 库来实现该解决方案。它涵盖了所有情况。现场演示:stackblitz.com/edit/weekdays?embed=1&file=src/app/…

标签: javascript angularjs date


【解决方案1】:

这样的工作是否有效:

var startDate = new Date("01-10-2020");
var endDate = new Date("01-20-2020");
var nextDay = new Date(startDate);
var cnt = 0;
do {
    /*if (nextDay.getDay() >= 1 && nextDay.getDay() <= 5) {
        cnt = cnt + 1;
    }*/
    cnt += (nextDay.getDay() >= 1 && nextDay.getDay() <= 5) ? 1 : 0;
    nextDay.setDate(nextDay.getDate() + 1);
} while (nextDay <= endDate);
console.log("Number of week days between " + startDate + " and " + endDate + " = " + cnt);

Here 是提琴手。

【讨论】:

  • new Date("01-10-2020") 在 Firefox 和 Safari 中返回无效的日期。最好使用new Date(2020, 9, 1)
【解决方案2】:

您不希望每天进行昂贵的循环来查看是周六还是周日。逻辑应该是这样的:

  • 在 UTC 工作,因此我们无需担心时区
  • 计算日历周的总数。在一个日历周内,保证有 5 个工作日(不是周末 == SAT || SUN)
  • 计算剩余天数。这将在稍后添加到计算中。
  • 通过查看剩余部分是否属于周末来确定“finalAdjustment”。
  • 工作日数为 (5 * numWeeks) + remainingDays + finalAdjust

(function() {
  "use strict";

  var SUN = 0;
  var MON = 1;
  var TUE = 2;
  var WED = 3;
  var THU = 4;
  var FRI = 5;
  var SAT = 6;

  function isWeekendDay(day) {
    return day === SAT || day === SUN;
  }

  function numberWeekDays(start, end) {
    var numCalendarDays = (end - start) / 1000 / 60 / 60 / 24;
    var numWeeks = Math.floor(numCalendarDays / 7);

    // Potential days to add on to the number of full calendar
    // weeks. This will be adjusted by "finalAdjust"
    var remainderDays = numCalendarDays % 7;

    // Adjustments for start and end dates being on a weekend
    // ----------------------------
    // Start  at one because the same day should count as 1
    // but number of days between same day is 0 based on
    // arithmetic above.
    // Change this to 0 if you don't want end date inclusive...
    var finalAdjust = 1;
    var startDay = start.getUTCDay();
    var endDay = end.getUTCDay();
    // On a weekend, so adjust by subtracting 1
    if (isWeekendDay(startDay)) {
      finalAdjust--;
    }
    // On a weekend, so adjust by subtracting 1
    if (isWeekendDay(endDay)) {
      finalAdjust--;
    }
    // This accounts for subtracting an extra weekend when starting
    // at the beginning of a weekend (e.g. Saturday into Monday)
    // The end day cannot also be on a weekend based on week modular division (mod 7)
    if (startDay === SAT && remainderDays > 2) {
      finalAdjust--;
    }
    // ---------------------------

    // For every full calendar week there are 5 week days
    // Use that number with the remainderDays and finalAdjust above
    // to arrive at the answer.
    var numWeekDays = (5 * numWeeks) + remainderDays + finalAdjust;

    return numWeekDays;
  }

  // Test cases
  // Assume that the start and end dates are inclusive
  // 2020-01-01 to 2020-01-01 is one day
  // 2020-01-01 to 2020-01-02 is two days
  // ----------------------
  // A Wednesdday
  var start = new Date("2020-01-08");
  // A Saturday
  var end = new Date("2020-02-01");
  // Expected answer: 18
  console.log(numberWeekDays(start, end));

  // A Saturday
  start = new Date("2020-01-05");
  // A Monday
  end = new Date("2020-01-31");
  // Expected answer: 20
  console.log(numberWeekDays(start, end));

  // Weekday to weekday Tuesday to 
  start = new Date("2020-01-07");
  end = new Date("2020-01-16");
  // Expected: 8
  console.log(numberWeekDays(start, end));

  // Same week: Mon-Wed
  start = new Date("2020-01-06");
  end = new Date("2020-01-08");
  // Expected answer: 3
  console.log(numberWeekDays(start, end));

  // Same day
  start = new Date("2020-01-08");
  end = new Date("2020-01-08");
  // Expect: 1
  console.log(numberWeekDays(start, end));

  // Weekend only
  start = new Date("2020-01-04");
  end = new Date("2020-01-05");
  // Expect: 0;
  console.log(numberWeekDays(start, end));
  // ------------------
}());

正如其他人所说,像 moment 这样的日期库在这里很有用,因为它为您提供了许多用于处理日期和持续时间的实用函数。

【讨论】:

  • 此答案假定天数包括结束日期,因此 2020 年 1 月 1 日至 2020 年 1 月 2 日为 2 个工作日。
  • 我在 cmets 中明确说明了这一点。无论如何,我正在修改算法以提高效率。
  • 一个选项是添加一个可选的“包含”标志,默认为真。这总是一个令人担忧的问题,因为我认为大多数人认为周一到周五是 5 天,而不是周一到周一是 1 天。 :-)
  • 星期一是多少天?当然我可以有一个“包含”标志,但这应该足以让某人弄清楚。
猜你喜欢
  • 2019-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-03
  • 2015-04-25
  • 1970-01-01
相关资源
最近更新 更多