mahjong_group/server/CoreCms.Net.Utility/Helper/TimeSlotHelper.cs
2026-01-01 14:35:52 +08:00

284 lines
9.3 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
namespace CoreCms.Net.Utility.Helper
{
/// <summary>
/// 时段工具类
/// </summary>
public static class TimeSlotHelper
{
#region
/// <summary>
/// 凌晨时段
/// </summary>
public const int DAWN = 0;
/// <summary>
/// 上午时段
/// </summary>
public const int MORNING = 1;
/// <summary>
/// 下午时段
/// </summary>
public const int AFTERNOON = 2;
/// <summary>
/// 晚上时段
/// </summary>
public const int EVENING = 3;
#endregion
#region
/// <summary>
/// 时段开始小时配置
/// </summary>
private static readonly Dictionary<int, int> SlotStartHours = new Dictionary<int, int>
{
{ DAWN, 0 }, // 凌晨 00:00
{ MORNING, 6 }, // 上午 06:00
{ AFTERNOON, 12 }, // 下午 12:00
{ EVENING, 18 } // 晚上 18:00
};
/// <summary>
/// 时段结束小时配置23点59分需要特殊处理
/// </summary>
private static readonly Dictionary<int, int> SlotEndHours = new Dictionary<int, int>
{
{ DAWN, 5 }, // 凌晨 05:59
{ MORNING, 11 }, // 上午 11:59
{ AFTERNOON, 17 }, // 下午 17:59
{ EVENING, 23 } // 晚上 23:59
};
/// <summary>
/// 时段名称配置
/// </summary>
private static readonly Dictionary<int, string> SlotNames = new Dictionary<int, string>
{
{ DAWN, "凌晨" },
{ MORNING, "上午" },
{ AFTERNOON, "下午" },
{ EVENING, "晚上" }
};
#endregion
#region
/// <summary>
/// 根据时间获取时段类型
/// </summary>
/// <param name="time">时间</param>
/// <returns>时段类型0=凌晨1=上午2=下午3=晚上</returns>
public static int GetTimeSlotType(DateTime time)
{
int hour = time.Hour;
if (hour >= 0 && hour < 6)
return DAWN;
else if (hour >= 6 && hour < 12)
return MORNING;
else if (hour >= 12 && hour < 18)
return AFTERNOON;
else
return EVENING;
}
/// <summary>
/// 根据时段类型获取时段名称
/// </summary>
/// <param name="timeSlotType">时段类型</param>
/// <returns>时段名称</returns>
public static string GetTimeSlotName(int timeSlotType)
{
return SlotNames.ContainsKey(timeSlotType) ? SlotNames[timeSlotType] : "未知时段";
}
/// <summary>
/// 获取时段的起止时间
/// </summary>
/// <param name="date">日期</param>
/// <param name="timeSlotType">时段类型</param>
/// <returns>起止时间元组 (开始时间, 结束时间)</returns>
public static (DateTime startTime, DateTime endTime) GetTimeRange(DateTime date, int timeSlotType)
{
if (!SlotStartHours.ContainsKey(timeSlotType))
{
throw new ArgumentException($"无效的时段类型:{timeSlotType}");
}
// 使用日期的Date部分确保从00:00:00开始
var dayStart = date.Date;
// 计算开始时间
var startHour = SlotStartHours[timeSlotType];
var startTime = dayStart.AddHours(startHour);
// 计算结束时间(设置为该时段最后一分钟的最后一秒)
var endHour = SlotEndHours[timeSlotType];
var endTime = dayStart.AddHours(endHour).AddMinutes(59).AddSeconds(59);
return (startTime, endTime);
}
/// <summary>
/// 获取时段的起止时间(返回分离的开始和结束时间)
/// </summary>
/// <param name="date">日期</param>
/// <param name="timeSlotType">时段类型</param>
/// <param name="startTime">输出参数:开始时间</param>
/// <param name="endTime">输出参数:结束时间</param>
public static void GetTimeRange(DateTime date, int timeSlotType, out DateTime startTime, out DateTime endTime)
{
var range = GetTimeRange(date, timeSlotType);
startTime = range.startTime;
endTime = range.endTime;
}
/// <summary>
/// 校验时间是否在指定时段内
/// </summary>
/// <param name="time">要校验的时间</param>
/// <param name="timeSlotType">时段类型</param>
/// <returns>是否在时段内</returns>
public static bool ValidateTimeSlot(DateTime time, int timeSlotType)
{
var (startTime, endTime) = GetTimeRange(time.Date, timeSlotType);
return time >= startTime && time <= endTime;
}
/// <summary>
/// 获取所有时段类型列表
/// </summary>
/// <returns>时段类型列表</returns>
public static List<int> GetAllTimeSlotTypes()
{
return new List<int> { DAWN, MORNING, AFTERNOON, EVENING };
}
/// <summary>
/// 获取所有时段信息(类型和名称)
/// </summary>
/// <returns>时段信息字典</returns>
public static Dictionary<int, string> GetAllTimeSlots()
{
return new Dictionary<int, string>(SlotNames);
}
/// <summary>
/// 判断时段类型是否有效
/// </summary>
/// <param name="timeSlotType">时段类型</param>
/// <returns>是否有效</returns>
public static bool IsValidTimeSlotType(int timeSlotType)
{
return timeSlotType >= DAWN && timeSlotType <= EVENING;
}
/// <summary>
/// 获取时段的时间范围描述
/// </summary>
/// <param name="timeSlotType">时段类型</param>
/// <returns>时间范围描述,如"00:00-05:59"</returns>
public static string GetTimeRangeDescription(int timeSlotType)
{
if (!SlotStartHours.ContainsKey(timeSlotType))
{
return "未知时段";
}
var startHour = SlotStartHours[timeSlotType];
var endHour = SlotEndHours[timeSlotType];
return $"{startHour:D2}:00-{endHour:D2}:59";
}
/// <summary>
/// 获取完整的时段描述
/// </summary>
/// <param name="timeSlotType">时段类型</param>
/// <returns>完整描述,如"凌晨(00:00-05:59)"</returns>
public static string GetFullTimeSlotDescription(int timeSlotType)
{
var name = GetTimeSlotName(timeSlotType);
var range = GetTimeRangeDescription(timeSlotType);
return $"{name}({range})";
}
/// <summary>
/// 检查两个时段是否有重叠
/// </summary>
/// <param name="date">日期</param>
/// <param name="slot1">时段1</param>
/// <param name="slot2">时段2</param>
/// <returns>是否重叠</returns>
public static bool IsTimeSlotOverlap(DateTime date, int slot1, int slot2)
{
// 同一时段必然重叠
if (slot1 == slot2)
return true;
var (start1, end1) = GetTimeRange(date, slot1);
var (start2, end2) = GetTimeRange(date, slot2);
// 判断时间段是否重叠
return start1 < end2 && start2 < end1;
}
/// <summary>
/// 获取当前时段类型
/// </summary>
/// <returns>当前时段类型</returns>
public static int GetCurrentTimeSlotType()
{
return GetTimeSlotType(DateTime.Now);
}
/// <summary>
/// 判断指定时段是否已过去
/// </summary>
/// <param name="date">日期</param>
/// <param name="timeSlotType">时段类型</param>
/// <returns>是否已过去</returns>
public static bool IsTimeSlotPassed(DateTime date, int timeSlotType)
{
var (startTime, endTime) = GetTimeRange(date, timeSlotType);
return DateTime.Now > endTime;
}
/// <summary>
/// 判断指定时段是否正在进行中
/// </summary>
/// <param name="date">日期</param>
/// <param name="timeSlotType">时段类型</param>
/// <returns>是否正在进行中</returns>
public static bool IsTimeSlotCurrent(DateTime date, int timeSlotType)
{
var (startTime, endTime) = GetTimeRange(date, timeSlotType);
var now = DateTime.Now;
return now >= startTime && now <= endTime;
}
/// <summary>
/// 判断指定时段是否在未来
/// </summary>
/// <param name="date">日期</param>
/// <param name="timeSlotType">时段类型</param>
/// <returns>是否在未来</returns>
public static bool IsTimeSlotFuture(DateTime date, int timeSlotType)
{
var (startTime, endTime) = GetTimeRange(date, timeSlotType);
return DateTime.Now < startTime;
}
#endregion
}
}