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

Angular Material日期范围选择器悬停周日选中下周问题求助

问题描述

我使用Angular Material日期选择器,将周起始日改为周一后,悬停周日时会选中下周。以下是我的实现代码:

自定义DateAdapter代码

import { NativeDateAdapter } from '@angular/material/core';

export class CustomDateAdapter extends NativeDateAdapter {
    override getFirstDayOfWeek(): number {
        return 1;
    }
}

周范围选择策略代码

@Injectable()
export class FiveDayRangeSelectionStrategy<D> implements MatDateRangeSelectionStrategy<D> {
  constructor(private _dateAdapter: DateAdapter<D>) {}

  selectionFinished(date: D | null): DateRange<D> {
    return this._createFiveDayRange(date);
  }

  createPreview(activeDate: D | null): DateRange<D> {
    return this._createFiveDayRange(activeDate);
  }

  private _createFiveDayRange(date: D | null): DateRange<D> {
    if (date) {
      console.log(date)
      const start = this._getMondayBefore(date);
      const end = this._getSundayAfter(start);
      return new DateRange<D>(start, end);
    }
    return new DateRange<D>(null, null);
  }
  private _getMondayBefore(date: D): D {
    const dayOfWeek = this._dateAdapter.getDayOfWeek(date);
    const daysToSubtract = dayOfWeek - (this._dateAdapter.getFirstDayOfWeek());
    return this._dateAdapter.addCalendarDays(date, -daysToSubtract);
  }

  private _getSundayAfter(date: D): D {
    const dayOfWeek = this._dateAdapter.getDayOfWeek(date);
    const daysToAdd = 8 - dayOfWeek - this._dateAdapter.getFirstDayOfWeek();
    return this._dateAdapter.addCalendarDays(date, daysToAdd);
  }
}

@Component({
  selector: 'app-browser',
  templateUrl: './browser.component.html',
  styleUrls: ['./browser.component.scss'],
  providers: [
    {
      provide: MAT_DATE_RANGE_SELECTION_STRATEGY,
      useClass: FiveDayRangeSelectionStrategy,
    },
  ],
})

HTML代码

<mat-form-field appearance="fill">
    <mat-label>Enter a date range</mat-label>
    <mat-date-range-input [rangePicker]="picker">
      <input matStartDate placeholder="Start date">
      <input matEndDate placeholder="End date">
    </mat-date-range-input>
    <mat-datepicker-toggle matIconSuffix [for]="picker"></mat-datepicker-toggle>
    <mat-date-range-picker #picker></mat-date-range-picker>
</mat-form-field>

我尝试修改daysToAdd和daysToSubtract参数,但仅改变了范围,无法解决悬停周日选中下周的问题。请问如何实现悬停周日时选中当前周一至周日的范围?


解决方案

问题出在_getMondayBefore方法的逻辑上。NativeDateAdapter中周日的dayOfWeek返回0,周一返回1,当日期是周日时,原逻辑计算出的daysToSubtract = 0 - 1 = -1,调用addCalendarDays(date, 1)会得到下周一,导致范围变成下周的周一到周日。

调整_getMondayBefore的逻辑,针对周日单独处理:

private _getMondayBefore(date: D): D {
  const dayOfWeek = this._dateAdapter.getDayOfWeek(date);
  const firstDayOfWeek = this._dateAdapter.getFirstDayOfWeek(); // 1(周一)
  let daysToSubtract: number;

  if (dayOfWeek === 0) { // 周日时,减去6天得到当前周的周一
    daysToSubtract = 6;
  } else {
    daysToSubtract = dayOfWeek - firstDayOfWeek;
  }

  return this._dateAdapter.addCalendarDays(date, -daysToSubtract);
}

同时简化_getSundayAfter方法,因为起始日期已经是周一,直接加6天即可得到当前周的周日:

private _getSundayAfter(date: D): D {
  return this._dateAdapter.addCalendarDays(date, 6);
}

修改后,无论悬停哪一天(包括周日),都会选中当前周的周一至周日范围。

内容的提问来源于stack exchange,提问作者Jochem Bergers

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 20:40:34