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

如何用mat-sort实现表格中dd-MM-yyyy格式日期的正确排序?

Angular mat-sort 正确排序 dd-MM-yyyy 格式日期

问题根源在于直接对dd-MM-yyyy格式的字符串进行排序时,mat-sort会按字典序比较字符串,只优先匹配前两位的"日"部分,完全忽略月份和年份,导致排序结果不符合日期逻辑。要解决这个问题,核心是把日期字符串转换为可正确比较的Date对象(或对应的时间戳)后再执行排序。

实现步骤

1. 编写日期解析辅助函数

先实现一个工具函数,把dd-MM-yyyy格式的字符串转换成标准Date对象:

parseDDMMYYYY(dateStr: string): Date | null {
  const dateParts = dateStr.split('-');
  // 注意:JavaScript的Date月份是0起始(0=1月,11=12月),所以要减1
  if (dateParts.length === 3) {
    return new Date(+dateParts[2], +dateParts[1] - 1, +dateParts[0]);
  }
  // 格式错误时返回null
  return null;
}

2. 配置mat-sort的排序逻辑

根据你使用的排序方式,选择以下两种方案之一:

方案一:通过sortingDataAccessor全局配置(推荐)

如果使用MatTableDataSource,可以直接配置sortingDataAccessor,让日期列自动按时间戳排序:

import { MatTableDataSource } from '@angular/material/table';
import { Sort, MatSort } from '@angular/material/sort';
import { ViewChild, AfterViewInit } from '@angular/core';

// 假设你的数据类型定义
interface YourDataType {
  id: number;
  date: string; // dd-MM-yyyy格式
  // 其他字段...
}

export class YourComponent implements AfterViewInit {
  dataSource = new MatTableDataSource<YourDataType>([]);
  displayedColumns = ['id', 'date']; // 替换成你的列名

  @ViewChild(MatSort) sort!: MatSort;

  ngAfterViewInit() {
    this.dataSource.sort = this.sort;
    // 配置排序访问器
    this.dataSource.sortingDataAccessor = (item, property) => {
      if (property === 'date') { // 替换成你的日期列字段名
        const date = this.parseDDMMYYYY(item.date);
        // 转成时间戳(数字类型),确保排序逻辑正确
        return date ? date.getTime() : '';
      }
      // 其他字段按默认逻辑处理
      return item[property] as string;
    };
  }

  parseDDMMYYYY(dateStr: string): Date | null {
    const dateParts = dateStr.split('-');
    if (dateParts.length === 3) {
      return new Date(+dateParts[2], +dateParts[1] - 1, +dateParts[0]);
    }
    return null;
  }
}
方案二:在matSortChange事件中手动处理排序

如果需要更灵活的控制,可以在排序变更事件中手动处理日期列的排序:

onSortChange(event: Sort) {
  const sortedData = [...this.dataSource.data];
  
  if (event.active === 'date' && event.direction) {
    sortedData.sort((a, b) => {
      const dateA = this.parseDDMMYYYY(a.date);
      const dateB = this.parseDDMMYYYY(b.date);

      // 处理无效日期,这里默认把无效日期放在最后
      if (!dateA) return 1;
      if (!dateB) return -1;

      return event.direction === 'asc' 
        ? dateA.getTime() - dateB.getTime() 
        : dateB.getTime() - dateA.getTime();
    });
  } else {
    // 非日期列的默认排序逻辑
    sortedData.sort((x, y) => {
      const valX = x[event.active];
      const valY = y[event.active];
      return event.direction === 'asc' ? (valX < valY ? -1 : 1) : (valX > valY ? -1 : 1);
    });
  }

  this.dataSource.data = sortedData;
}

3. 模板部分(HTML)

确保mat-sort-header绑定的列名和TS中的字段名一致:

<table mat-table [dataSource]="dataSource" matSort #sort="matSort" (matSortChange)="onSortChange($event)">
  <!-- 日期列 -->
  <ng-container matColumnDef="date">
    <th mat-header-cell *matHeaderCellDef mat-sort-header>日期</th>
    <td mat-cell *matCellDef="let item">{{ item.date }}</td>
  </ng-container>

  <!-- 其他列示例 -->
  <ng-container matColumnDef="id">
    <th mat-header-cell *matHeaderCellDef>ID</th>
    <td mat-cell *matCellDef="let item">{{ item.id }}</td>
  </ng-container>

  <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
  <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>

注意事项

  • 确保日期字符串格式严格为dd-MM-yyyy,无多余空格或异常字符,否则解析函数会返回null。
  • 若存在无效日期,可根据业务需求调整排序时的优先级(比如放在最前或最后)。
  • 使用getTime()将Date转为数字比较,比直接比较Date对象更稳定,避免部分浏览器的兼容性问题。

内容的提问来源于stack exchange,提问作者Asha A

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 22:45:30