refactor(server): 日期工具统一迁入 dayjs(utc 插件),移除手写 Intl/padStart 重复实现

This commit is contained in:
2026-08-08 17:27:14 +08:00
parent 74d5b90faa
commit d324b2fb0a
9 changed files with 37 additions and 72 deletions

View File

@@ -11,6 +11,7 @@ import {
ScheduleType,
} from '../entities';
import { toMinutes, isClassStudentActiveOnDate } from './attendance-time';
import dayjs from '../common/dayjs';
import type { BatchCreateAttendanceDto, GenerateAttendanceFromSchedulesDto, GenerateFromSchedulesDto, SaveAttendancePeriodConfigsDto } from './dto/attendance.dto';
@Injectable()
@@ -162,23 +163,15 @@ export class AttendanceGenerationService {
}
private getCourseClock(date: Date): { date: string; minutes: number } {
const parts = Object.fromEntries(
new Intl.DateTimeFormat('en-CA', {
timeZone: 'Asia/Shanghai',
year: 'numeric', month: '2-digit', day: '2-digit',
hour: '2-digit', minute: '2-digit', hourCycle: 'h23',
}).formatToParts(date).filter((part) => part.type !== 'literal').map((part) => [part.type, part.value]),
);
const c = dayjs.utc(date).add(8, 'hour');
return {
date: `${parts.year}-${parts.month}-${parts.day}`,
minutes: Number(parts.hour) * 60 + Number(parts.minute),
date: c.format('YYYY-MM-DD'),
minutes: c.hour() * 60 + c.minute(),
};
}
private shiftDate(date: string, days: number): string {
const shifted = new Date(`${date}T00:00:00.000Z`);
shifted.setUTCDate(shifted.getUTCDate() + days);
return shifted.toISOString().slice(0, 10);
return dayjs.utc(`${date}T00:00:00.000Z`).add(days, 'day').format('YYYY-MM-DD');
}
private async ensureAttendancePeriodConfigs() {

View File

@@ -1,4 +1,5 @@
import { BadRequestException, Injectable, Logger } from '@nestjs/common';
import dayjs from '../common/dayjs';
import { Cron } from '@nestjs/schedule';
import { InjectRepository } from '@nestjs/typeorm';
import { In, LessThan, LessThanOrEqual, MoreThanOrEqual, Repository } from 'typeorm';
@@ -283,18 +284,13 @@ export class AttendanceSettlementService {
}
private getCourseClock(date: Date): { date: string; weekDay: number; minutes: number } {
const parts = Object.fromEntries(
new Intl.DateTimeFormat('en-CA', {
timeZone: this.courseTimeZone,
year: 'numeric', month: '2-digit', day: '2-digit', weekday: 'short',
hour: '2-digit', minute: '2-digit', hourCycle: 'h23',
}).formatToParts(date).filter((part) => part.type !== 'literal').map((part) => [part.type, part.value]),
);
const weekDays: Record<string, number> = { Mon: 1, Tue: 2, Wed: 3, Thu: 4, Fri: 5, Sat: 6, Sun: 7 };
// Asia/Shanghai 无夏令时,固定 UTC+8 与 Intl 时区格式化等价
const c = dayjs.utc(date).add(8, 'hour');
const weekDay = c.day() === 0 ? 7 : c.day();
return {
date: `${parts.year}-${parts.month}-${parts.day}`,
weekDay: weekDays[parts.weekday],
minutes: Number(parts.hour) * 60 + Number(parts.minute),
date: c.format('YYYY-MM-DD'),
weekDay,
minutes: c.hour() * 60 + c.minute(),
};
}

View File

@@ -1,22 +1,20 @@
import dayjs from '../common/dayjs';
export function toMinutes(time: string): number {
const [hour, minute] = time.split(':').map(Number);
return hour * 60 + minute;
}
export function getCourseClock(date: Date): { date: string; minutes: number } {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const d = dayjs(date);
return {
date: `${year}-${month}-${day}`,
minutes: date.getHours() * 60 + date.getMinutes(),
date: d.format('YYYY-MM-DD'),
minutes: d.hour() * 60 + d.minute(),
};
}
export function shiftDate(date: string, days: number): string {
const d = new Date(`${date}T00:00:00.000Z`);
d.setUTCDate(d.getUTCDate() + days);
return d.toISOString().slice(0, 10);
return dayjs.utc(`${date}T00:00:00.000Z`).add(days, 'day').format('YYYY-MM-DD');
}
export function mapLessonScheduleTimeToSession(startTime: string): string {

View File

@@ -1,4 +1,5 @@
import { UseGuards } from '@nestjs/common';
import dayjs from '../common/dayjs';
import { AttendanceService } from './attendance.service';
import { AttendanceImportService } from './attendance-import.service';
import { OperationLogsService } from '../operation-logs/operation-logs.service';
@@ -32,11 +33,7 @@ export abstract class AttendanceControllerBase {
) {}
protected getTodayDateOnly(): string {
const today = new Date();
const year = today.getFullYear();
const month = String(today.getMonth() + 1).padStart(2, '0');
const day = String(today.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
return dayjs().format('YYYY-MM-DD');
}
protected canManageAllAttendance(req: { user: RequestUser }): boolean {