package packagepkg import ( "time" "github.com/break/junhong_cmp_fiber/pkg/constants" ) // CalculateExpiryTime 计算套餐过期时间 // calendarType: 套餐周期类型(natural_month=自然月,by_day=按天) // activatedAt: 激活时间 // durationMonths: 套餐时长(月数,calendar_type=natural_month 时使用) // durationDays: 套餐天数(calendar_type=by_day 时使用) // 返回:过期时间(当天 23:59:59) func CalculateExpiryTime(calendarType string, activatedAt time.Time, durationMonths, durationDays int) time.Time { var expiryDate time.Time if calendarType == constants.PackageCalendarTypeNaturalMonth { // 自然月套餐:activated_at 月份 + N 个月,月末 23:59:59 // 计算目标年月 targetYear := activatedAt.Year() targetMonth := activatedAt.Month() + time.Month(durationMonths) // 处理月份溢出 for targetMonth > 12 { targetMonth -= 12 targetYear++ } // 获取目标月份的最后一天(下个月的第0天就是本月最后一天) expiryDate = time.Date(targetYear, targetMonth+1, 0, 23, 59, 59, 0, activatedAt.Location()) } else { // 按天套餐:activated_at + N 天,23:59:59 expiryDate = activatedAt.AddDate(0, 0, durationDays) expiryDate = time.Date(expiryDate.Year(), expiryDate.Month(), expiryDate.Day(), 23, 59, 59, 0, expiryDate.Location()) } return expiryDate } // CalculateNextResetTime 计算下次流量重置时间 // dataResetCycle: 流量重置周期(daily/monthly/yearly/none) // calendarType: 套餐周期类型(natural_month/by_day),影响月重置逻辑 // currentTime: 当前时间 // activatedAt: 套餐激活时间(按天套餐月重置时使用) // 返回:下次重置时间(00:00:00) func CalculateNextResetTime(dataResetCycle, calendarType string, currentTime, activatedAt time.Time) *time.Time { if dataResetCycle == constants.PackageDataResetNone { // 不重置 return nil } var nextResetTime time.Time switch dataResetCycle { case constants.PackageDataResetDaily: // 日重置:明天 00:00:00 nextResetTime = time.Date( currentTime.Year(), currentTime.Month(), currentTime.Day()+1, 0, 0, 0, 0, currentTime.Location(), ) case constants.PackageDataResetMonthly: if calendarType == constants.PackageCalendarTypeNaturalMonth { // 自然月套餐:每月1号 00:00:00 重置 year := currentTime.Year() month := currentTime.Month() // 如果当前日期 >= 1号(即已过重置点),则下次重置为下个月1号 if currentTime.Day() >= 1 { month++ if month > 12 { month = 1 year++ } } nextResetTime = time.Date(year, month, 1, 0, 0, 0, 0, currentTime.Location()) } else { // 按天套餐:从激活日期开始,每30天重置一次 // 计算从激活到现在经过了多少个30天周期 daysSinceActivation := int(currentTime.Sub(activatedAt).Hours() / 24) cyclesPassed := daysSinceActivation / 30 // 下次重置时间 = 激活时间 + (已过周期数+1) * 30天 nextResetTime = activatedAt.AddDate(0, 0, (cyclesPassed+1)*30) nextResetTime = time.Date( nextResetTime.Year(), nextResetTime.Month(), nextResetTime.Day(), 0, 0, 0, 0, nextResetTime.Location(), ) } case constants.PackageDataResetYearly: // 年重置:每年1月1日 00:00:00 year := currentTime.Year() // 如果当前日期已经过了1月1日,则使用明年 jan1ThisYear := time.Date(year, 1, 1, 0, 0, 0, 0, currentTime.Location()) if currentTime.After(jan1ThisYear) || currentTime.Equal(jan1ThisYear) { year++ } nextResetTime = time.Date(year, 1, 1, 0, 0, 0, 0, currentTime.Location()) default: return nil } return &nextResetTime }