You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 5日期自定义:开发计算指定日期间企业工作日的算法

Got it, let's tackle this requirement step by step. Calculating business days between two dates in Angular while excluding weekends and custom holidays is a common task, and here's a solid approach to implement it:

1. Create a Holiday Service to Manage Holidays

First, we'll build a service to handle loading and checking holidays. This keeps our code organized and makes it easy to update the holiday list later.

  • Generate a service using Angular CLI:

    ng generate service holiday
    
  • In holiday.service.ts, we'll load our holiday array (you can store this in a JSON file or directly define it in the service). For example, if you have a holidays.json file in your assets folder:

    import { Injectable } from '@angular/core';
    import { HttpClient } from '@angular/common/http';
    import { Observable } from 'rxjs';
    import { map } from 'rxjs/operators';
    
    @Injectable({
      providedIn: 'root'
    })
    export class HolidayService {
      constructor(private http: HttpClient) { }
    
      getHolidays(): Observable<Date[]> {
        return this.http.get<string[]>('/assets/holidays.json').pipe(
          // Convert string dates to Date objects for consistent comparison
          map(holidayStrings => holidayStrings.map(dateStr => new Date(dateStr)))
        );
      }
    
      // Helper method to check if a given date is a holiday
      isHoliday(date: Date, holidays: Date[]): boolean {
        const targetDateStr = date.toISOString().split('T')[0];
        return holidays.some(holiday => holiday.toISOString().split('T')[0] === targetDateStr);
      }
    }
    

    Your holidays.json would look like this (ISO date format is recommended for consistency):

    [
      "2024-01-01",
      "2024-05-27",
      "2024-07-04",
      "2024-11-28",
      "2024-12-25"
    ]
    
2. Implement the Business Day Calculation Logic

Next, we'll create a dedicated service for the core calculation. The algorithm needs to:

  1. Ensure the start date is always before the end date
  2. Iterate through each date in the range
  3. Skip weekends (Saturdays = 6, Sundays = 0 via getDay())
  4. Skip dates that are in our holiday list

Here's the code for business-day.service.ts:

import { Injectable } from '@angular/core';
import { HolidayService } from './holiday.service';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class BusinessDayService {
  constructor(private holidayService: HolidayService) { }

  calculateBusinessDays(startDate: Date, endDate: Date): Observable<number> {
    // Swap dates if start is after end
    if (startDate > endDate) {
      [startDate, endDate] = [endDate, startDate];
    }

    return this.holidayService.getHolidays().pipe(
      map(holidays => {
        let businessDayCount = 0;
        const currentDate = new Date(startDate);

        while (currentDate <= endDate) {
          const dayOfWeek = currentDate.getDay();
          // Check if it's a weekday AND not a holiday
          if (dayOfWeek !== 0 && dayOfWeek !== 6 && !this.holidayService.isHoliday(currentDate, holidays)) {
            businessDayCount++;
          }
          // Move to next day (avoids mutating the original start date)
          currentDate.setDate(currentDate.getDate() + 1);
        }

        return businessDayCount;
      })
    );
  }
}
3. Use the Service in Your Component

Now you can integrate this logic into any component. Here's a simple calculator component example:

import { Component } from '@angular/core';
import { BusinessDayService } from './business-day.service';

@Component({
  selector: 'app-business-day-calculator',
  template: `
    <div class="calculator-container">
      <div class="date-inputs">
        <label>Start Date: 
          <input type="date" [(ngModel)]="startDateStr" required>
        </label>
        <label>End Date: 
          <input type="date" [(ngModel)]="endDateStr" required>
        </label>
      </div>
      <button (click)="computeBusinessDays()" [disabled]="!startDateStr || !endDateStr">
        Calculate Business Days
      </button>
      <p *ngIf="result !== null" class="result">
        Total Business Days: <strong>{{ result }}</strong>
      </p>
    </div>
  `,
  styles: [`
    .calculator-container { padding: 20px; max-width: 500px; margin: 0 auto; }
    .date-inputs { margin-bottom: 15px; display: flex; gap: 10px; }
    button { padding: 8px 16px; cursor: pointer; }
    .result { margin-top: 15px; font-size: 1.1rem; }
  `]
})
export class BusinessDayCalculatorComponent {
  startDateStr: string = '';
  endDateStr: string = '';
  result: number | null = null;

  constructor(private businessDayService: BusinessDayService) { }

  computeBusinessDays() {
    const startDate = new Date(this.startDateStr);
    const endDate = new Date(this.endDateStr);
    
    this.businessDayService.calculateBusinessDays(startDate, endDate).subscribe(count => {
      this.result = count;
    });
  }
}
Quick Optimization Tip

For very large date ranges (e.g., years apart), looping through each day can be slow. You can optimize it by:

  1. Calculating total days between the two dates
  2. Mathematically computing the number of weekends
  3. Counting only holidays that fall on weekdays (to avoid double-counting)

Here's a snippet for the optimized weekend calculation:

const totalDays = Math.floor((endDate.getTime() - startDate.getTime()) / (1000 * 60 * 60 * 24)) + 1;
const fullWeeks = Math.floor(totalDays / 7);
let weekendDays = fullWeeks * 2;

// Add remaining weekend days from the partial week
const remainingDays = totalDays % 7;
for (let i = 0; i < remainingDays; i++) {
  const day = (startDate.getDay() + i) % 7;
  if (day === 0 || day === 6) weekendDays++;
}

内容的提问来源于stack exchange,提问作者Marouen Abdi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:02:04