package conv import ( "errors" "fmt" "time" "github.com/LoveLosita/smartflow/backend/respond" "github.com/spf13/viper" ) // DateFormat 此处定义一个全局常量,确保在整个代码中使用统一的日期格式解析和格式化 const DateFormat = "2006-01-02" // RealDateToRelativeDate 将绝对日期转换为相对日期(格式: "week-day") func RealDateToRelativeDate(realDate string) (int, int, error) { SemesterStartDate := viper.GetString("time.semesterStartDate") // 从配置文件中读取学期开始日期 SemesterEndDate := viper.GetString("time.semesterEndDate") // 从配置文件中读取学期结束日期 t, err := time.Parse(DateFormat, realDate) if err != nil { return 0, 0, err } start, err := time.Parse(DateFormat, SemesterStartDate) if err != nil { return 0, 0, err } end, err := time.Parse(DateFormat, SemesterEndDate) if err != nil { return 0, 0, err } // 边界校验:日期必须在学期范围内 if t.Before(start) || t.After(end) { return 0, 0, errors.New("日期超出学期范围") } // 计算天数差值(注意:24小时为一个基准天) days := int(t.Sub(start).Hours() / 24) // 计算周数和星期 // 假设 SemesterStartDate 对应第 1 周,周 1 week := (days / 7) + 1 dayOfWeek := (days % 7) + 1 return week, dayOfWeek, nil } // RelativeDateToRealDate 将相对日期转换为绝对日期(输入格式: "week-day") func RelativeDateToRealDate(week, dayOfWeek int) (string, error) { SemesterStartDate := viper.GetString("time.semesterStartDate") // 从配置文件中读取学期开始日期 SemesterEndDate := viper.GetString("time.semesterEndDate") // 从配置文件中读取学期结束日期 start, _ := time.Parse(DateFormat, SemesterStartDate) // 核心转换逻辑:(周-1)*7 + (天-1) offsetDays := (week-1)*7 + (dayOfWeek - 1) targetDate := start.AddDate(0, 0, offsetDays) // 校验计算出的日期是否超出学期结束日期 end, _ := time.Parse(DateFormat, SemesterEndDate) if targetDate.After(end) { return "", respond.TimeOutOfRangeOfThisSemester } return targetDate.Format(DateFormat), nil } type SectionTime struct { Start string // 第一个开始 End string // 第一个结束 } var SectionTimeMap2 = map[int]SectionTime{ 1: {Start: "08:00", End: "08:45"}, 2: {Start: "08:55", End: "09:40"}, 3: {Start: "10:15", End: "11:00"}, 4: {Start: "11:10", End: "11:55"}, 5: {Start: "14:00", End: "14:45"}, 6: {Start: "14:55", End: "15:40"}, 7: {Start: "16:15", End: "17:00"}, 8: {Start: "17:10", End: "17:55"}, 9: {Start: "19:00", End: "19:45"}, 10: {Start: "19:55", End: "20:40"}, 11: {Start: "20:50", End: "21:35"}, 12: {Start: "21:45", End: "22:30"}, } func RelativeTimeToRealTime(week, dayOfWeek, startSection, endSection int) (time.Time, time.Time, error) { // 1. 安全校验 if startSection > endSection { return time.Time{}, time.Time{}, respond.InvalidSectionRange } startTimeInfo, okStart := SectionTimeMap2[startSection] endTimeInfo, okEnd := SectionTimeMap2[endSection] if !okStart || !okEnd { return time.Time{}, time.Time{}, respond.InvalidSectionNumber } if week < 1 || dayOfWeek < 1 || dayOfWeek > 7 { return time.Time{}, time.Time{}, respond.InvalidWeekOrDayOfWeek } // 2. 计算目标日期 // 偏移天数 = (周数-1)*7 + (周几-1) daysOffset := (week-1)*7 + (dayOfWeek - 1) TermStartDate := viper.GetString("time.semesterStartDate") // 从配置文件中读取学期开始日期 baseDate, _ := time.Parse("2006-01-02", TermStartDate) targetDate := baseDate.AddDate(0, 0, daysOffset) dateStr := targetDate.Format("2006-01-02") // 3. 锁定时区 (Asia/Shanghai) timeZone := viper.GetString("time.zone") // 从配置文件中读取时区 loc, _ := time.LoadLocation(timeZone) // 拼接:起始节次的 Start 和 结束节次的 End startFullStr := fmt.Sprintf("%s %s", dateStr, startTimeInfo.Start) endFullStr := fmt.Sprintf("%s %s", dateStr, endTimeInfo.End) startTime, err := time.ParseInLocation("2006-01-02 15:04", startFullStr, loc) if err != nil { return time.Time{}, time.Time{}, err } endTime, err := time.ParseInLocation("2006-01-02 15:04", endFullStr, loc) if err != nil { return time.Time{}, time.Time{}, err } return startTime, endTime, nil } func CalculateFirstDayOfWeek(date time.Time) time.Time { // 计算当前日期是周几(0-6,0表示周日) weekday := int(date.Weekday()) if weekday == 0 { weekday = 7 // 将周日调整为7,方便计算 } // 计算距离周一的天数偏移 offset := weekday - 1 // 计算本周一的日期 firstDayOfWeek := date.AddDate(0, 0, -offset) return firstDayOfWeek } func CalculateLastDayOfWeek(date time.Time) time.Time { // 计算当前日期是周几(0-6,0表示周日) weekday := int(date.Weekday()) if weekday == 0 { weekday = 7 // 将周日调整为7,方便计算 } // 计算距离周日的天数偏移 offset := 7 - weekday // 计算本周日的日期 lastDayOfWeek := date.AddDate(0, 0, offset) return lastDayOfWeek }