using System; using System.Collections.Generic; using System.Globalization; using ET; namespace GFGGame { public partial class TimeUtil { public static int HOURS_PER_DAY = 24; //每天的小时数 public static int MUNITE_PER_HOUR = 60; //每小时的分钟数 public static int SECOND_PER_MUNITE = 60; //每分钟的秒数 public static long SECOND_PER_HOUR = 3600; //一小时的秒数 public static long SECOND_PER_DAY = 86400; //一天的秒数 public static long SECOND_PER_WEEK = 604800; //一个星期的妙数 public static long FIRST_YEAR_ZERO_POINT_MUNITE = 57600; //计算机元年第二天的0点,即1970-01-02 00:00:00的时间戳 57600 秒级 //NextZeroTime public static int NextZeroSecs { get { //转换为时间对象必须使用此接口 DateTime current = TimeInfo.Instance.ToDateTime(TimeInfo.Instance.ServerNow()); var todayZero = new DateTime(current.Year, current.Month, current.Day, 0, 0, 0); if (current.Ticks < todayZero.Ticks) { //转换为时间戳必须使用此接口 return (int)(TimeInfo.Instance.Transition(todayZero) / 1000); } var timeSpan = new TimeSpan(24, 0, 0); var tomorrowZero = todayZero.Add(timeSpan); return (int)(TimeInfo.Instance.Transition(tomorrowZero) / 1000); } } public static int NextResetSecs { get { //转换为时间对象必须使用此接口 DateTime current = TimeInfo.Instance.ToDateTime(TimeInfo.Instance.ServerNow()); var today5 = new DateTime(current.Year, current.Month, current.Day, GameConst.DAILY_RESET_HOUR, 0, 0); if (current.Ticks < today5.Ticks) { //转换为时间戳必须使用此接口 return (int)(TimeInfo.Instance.Transition(today5) / 1000); } TimeSpan timeSpan = new TimeSpan(24, 0, 0); var tomorrow5 = today5.Add(timeSpan); return (int)(TimeInfo.Instance.Transition(tomorrow5) / 1000); } } public static int NextWeekSecs { get { var current = TimeInfo.Instance.ToDateTime(TimeInfo.Instance.ServerNow()); var monday = current.AddDays(-(int)current.DayOfWeek + 1).Date; var mondayFive = monday.AddHours(GameConst.DAILY_RESET_HOUR); if (current.Ticks < mondayFive.Ticks) { //转换为时间戳必须使用此接口 return (int)(TimeInfo.Instance.Transition(mondayFive) / 1000); } mondayFive = mondayFive.AddDays(7); return (int)(TimeInfo.Instance.Transition(mondayFive) / 1000); } } public static int NextMouthSecs { get { var current = TimeInfo.Instance.ToDateTime(TimeInfo.Instance.ServerNow()); var firstDay = current.AddDays(1 - current.Day).Date; var firstDayFive = firstDay.AddHours(GameConst.DAILY_RESET_HOUR); if (current.Ticks < firstDayFive.Ticks) { //转换为时间戳必须使用此接口 return (int)(TimeInfo.Instance.Transition(firstDayFive) / 1000); } firstDayFive = firstDayFive.AddMonths(1); return (int)(TimeInfo.Instance.Transition(firstDayFive) / 1000); } } public static int NextYearSecs { get { var current = TimeInfo.Instance.ToDateTime(TimeInfo.Instance.ServerNow()); var firstDay = current.AddDays(1 - current.DayOfYear).Date; var firstDayFive = firstDay.AddHours(GameConst.DAILY_RESET_HOUR); if (current.Ticks < firstDayFive.Ticks) { //转换为时间戳必须使用此接口 return (int)(TimeInfo.Instance.Transition(firstDayFive) / 1000); } firstDayFive = firstDayFive.AddYears(1); return (int)(TimeInfo.Instance.Transition(firstDayFive) / 1000); } } public static long TodayRestTime() { var current = TimeInfo.Instance.ToDateTime(TimeInfo.Instance.ServerNow()); var today5 = new DateTime(current.Year, current.Month, current.Day, GameConst.DAILY_RESET_HOUR, 0, 0); //转换为时间戳必须使用此接口 return TimeInfo.Instance.Transition(today5); } //星期天是0,依次递增 public static bool CheckDayOfWeek(int dayOfWeek) { //转换为时间对象必须使用此接口 DateTime current = TimeInfo.Instance.ToDateTime(TimeInfo.Instance.ServerNow()); if ((int)current.DayOfWeek == dayOfWeek) { return true; } return false; } //星期天是0,依次递增 public static bool CheckDayOfWeek(int[] dayOfWeeks) { if (dayOfWeeks.Length == 0) { return true; } //转换为时间对象必须使用此接口 DateTime current = TimeInfo.Instance.ToDateTime(TimeInfo.Instance.ServerNow()); foreach (var dayOfWeek in dayOfWeeks) { if ((int)current.DayOfWeek == dayOfWeek) { return true; } } return false; } public static bool CheckDayOfWeek(List dayOfWeeks) { if (dayOfWeeks.Count == 0) { return true; } //转换为时间对象必须使用此接口 DateTime current = TimeInfo.Instance.ToDateTime(TimeInfo.Instance.ServerNow()); foreach (var dayOfWeek in dayOfWeeks) { if ((int)current.DayOfWeek == dayOfWeek) { return true; } } return false; } //检测两个时间是否为同一天 public static bool CheckIsSameTime(long time1, long time2) { DateTime date1 = TimeInfo.Instance.ToDateTime(time1); string str1 = date1.ToString("yyyy-MM-dd "); DateTime date2 = TimeInfo.Instance.ToDateTime(time2); string str2 = date2.ToString("yyyy-MM-dd "); return str1 == str2; } /// /// 检测两个时间是否为同一天(秒时间戳入参) /// /// /// /// public static bool CheckIsSameTimeExt(long time1, long time2) { long daysDifference = DaysDifference(time1, time2); if (daysDifference == 0) { return true; } else { return false; } } //两个时间戳的差值天数(秒 时间戳入参),结果为正负,假设:time1 < time2 的话,差值为-1 public static long DaysDifference(long time1, long time2) { //先设置一个计算机元年第二天的0点,即1970-01-02 00:00:00的时间戳(FIRST_YEAR_ZERO_POINT_MUNITE=57600,有两个时间戳字段x和y,假设x和y满足,(x - m) / 86400 - (y - m) / 86400 = 0,即x和y处在同一天。(其中 / 表示整除) return (time1 - FIRST_YEAR_ZERO_POINT_MUNITE) / SECOND_PER_DAY - (time2 - FIRST_YEAR_ZERO_POINT_MUNITE) / SECOND_PER_DAY; } //检查今天是否是指定日子 public static bool CheckDayOfMonth(int dayOfMonth) { //转换为时间对象必须使用此接口 DateTime current = TimeInfo.Instance.ToDateTime(TimeInfo.Instance.ServerNow()); if ((int)current.Day == dayOfMonth) { return true; } return false; } /// ///判断是否在当前服务器时间之前 /// /// 策划配置时间串 格式 [年][月][日][时:分] /// 是否检查时间相等, 默认不检查 /// public static bool IsBeforeCurTime(string time, bool isSame = false) { if (time.Contains("24:00:00")) { time = time.Replace("24:00:00", "23:59:59"); } if (time.Contains("24:00")) { time = time.Replace("24:00", "23:59:59"); } DateTime date = GetDateTime(time); // if (time.EndsWith("24:00:00")) // { // time = time.Substring(0, time.Length - 8) + " 23:59:59"; // } // DateTime date = DateTime.Parse(time); DateTime current = TimeInfo.Instance.ToDateTime(TimeInfo.Instance.ServerNow()); if (isSame) { return date <= current; } return date < current; } /// /// 判断是否在当前服务器时间之后 /// /// /// public static bool IsLaterCurTime(string time) { if (time.Contains("24:00:00")) { time = time.Replace("24:00:00", "23:59:59"); } if (time.Contains("24:00")) { time = time.Replace("24:00", "23:59"); } DateTime date = GetDateTime(time); DateTime current = TimeInfo.Instance.ToDateTime(TimeInfo.Instance.ServerNow()); return date > current; } /// /// 将utc时间转换成时间戳 /// /// /// public static long DateTimeToTimestamp(string time) { // if (time.EndsWith("24:00:00")) // { // time = time.Substring(0, time.Length - 8) + " 23:59:59"; // } // // DateTime date = DateTime.Parse(time); if (time.Contains("24:00:00")) { time = time.Replace("24:00:00", "23:59:59"); } if (time.Contains("24:00")) { time = time.Replace("24:00", "23:59"); } DateTime date = GetDateTime(time); return TimeInfo.Instance.Transition(date); } /// /// 根据时间戳获取当天指定时间(如传入当天7点的时间戳获取当天5点的时间戳) /// /// 时间戳,单位毫秒 /// public static long GetDayTimeBySec(long timeMilliSec, string time = "00:00:00") { DateTime date = TimeInfo.Instance.ToDateTime(timeMilliSec); string str = date.ToString("yyyy-MM-dd ") + time; DateTime date1 = DateTime.Parse(str); return TimeInfo.Instance.Transition(date1); } /// /// 获取明天指定时间的时间戳,返回毫秒 /// /// public static long GetTomorrowTime(string time = "00:00:00") { DateTime current = TimeInfo.Instance.ToDateTime(TimeInfo.Instance.ServerNow()); DateTime dt = current.AddDays(1); string str = dt.ToString("yyyy-MM-dd ") + time; DateTime date = DateTime.Parse(str); return TimeInfo.Instance.Transition(date); } /// /// 获取下月一号指定时间的时间戳,返回毫秒 /// /// /// public static long GetNextMonthTime(string time = "00:00:00") { DateTime current = TimeInfo.Instance.ToDateTime(TimeInfo.Instance.ServerNow()); DateTime date = DateTime.Parse(current.ToString("yyyy-MM-01 ")).AddMonths(1); string str = date.ToString("yyyy-MM-dd ") + time; date = DateTime.Parse(str); return TimeInfo.Instance.Transition(date); } /// /// 获取下周一指定时间的时间戳,返回毫秒 /// /// /// public static long GetNextWeekTime(string time = "00:00:00") { DateTime current = TimeInfo.Instance.ToDateTime(TimeInfo.Instance.ServerNow()); int week = Convert.ToInt32(current.DayOfWeek); week = week == 0 ? 7 : week; var start_time_next_week = current.AddDays(1 - week + 7).ToString("yyyy-MM-dd ") + time; DateTime date = DateTime.Parse(start_time_next_week); return TimeInfo.Instance.Transition(date); } /// /// 获取下周一指定时间的时间戳,返回毫秒 /// /// /// public static long GetNextWeekTime(int _week, string time = "00:00:00") { _week = _week == 0 ? 7 : _week; DateTime current = TimeInfo.Instance.ToDateTime(TimeInfo.Instance.ServerNow()); int _curweek = Convert.ToInt32(current.DayOfWeek); _curweek = _curweek == 0 ? 7 : _curweek; var end_time_last_week = current.AddDays(_week - _curweek + 7).ToString("yyyy-MM-dd ") + time; DateTime date = DateTime.Parse(end_time_last_week); return TimeInfo.Instance.Transition(date); } /// /// 获取本周某天指定时间时间戳,返回毫秒 /// /// public static long GetCurWeekTime(int _week, string time = "00:00:00") { _week = _week == 0 ? 7 : _week; DateTime current = TimeInfo.Instance.ToDateTime(TimeInfo.Instance.ServerNow()); int _curweek = Convert.ToInt32(current.DayOfWeek); _curweek = _curweek == 0 ? 7 : _curweek; var start_time_current_week = current.AddDays(_week - _curweek).ToString("yyyy-MM-dd ") + time; DateTime date = DateTime.Parse(start_time_current_week); return TimeInfo.Instance.Transition(date); } /// /// 获取上周某天指定时间时间戳,返回毫秒 /// /// /// public static long GetLastWeekTime(int _week, string time = "00:00:00") { _week = _week == 0 ? 7 : _week; DateTime current = TimeInfo.Instance.ToDateTime(TimeInfo.Instance.ServerNow()); int _curweek = Convert.ToInt32(current.DayOfWeek); _curweek = _curweek == 0 ? 7 : _curweek; var end_time_last_week = current.AddDays(_week - _curweek - 7).ToString("yyyy-MM-dd ") + time; DateTime date = DateTime.Parse(end_time_last_week); return TimeInfo.Instance.Transition(date); } /// /// 获取今天时间时间戳,返回毫秒 /// /// public static long GetCurDayTime(string time = "00:00:00") { var current = TimeInfo.Instance.ToDateTime(TimeInfo.Instance.ServerNow()); var targetTimeStar = current.ToString("yyyy-MM-dd ") + time; var date = DateTime.Parse(targetTimeStar); return TimeInfo.Instance.Transition(date); } /// /// 获取下一个指定时间 /// /// public static long GetNextTime(string time = "00:00:00") { var curDayTime = GetCurDayTime(time); var curTime = TimeInfo.Instance.ServerNow(); return curDayTime > curTime ? curDayTime : GetTomorrowTime(time); } private static readonly string[] Formats = { "HH:mm", "'['yyyy']['M']['dd']'", "'['yyyy']['MM']['d']'", "'['yyyy']['M']['d']'", "'['yyyy']['MM']['dd']'", "'['yyyy']['MM']['dd']['HH:mm']'", "'['yyyy']['MM']['dd']['H:mm']'", "'['yyyy']['M']['dd']['HH:mm']'", "'['yyyy']['M']['dd']['H:mm']'", "'['yyyy']['MM']['d']['HH:mm']'", "'['yyyy']['MM']['d']['H:mm']'", "'['yyyy']['M']['d']['HH:mm']'", "'['yyyy']['M']['d']['H:mm']'", "'['yyyy']['MM']['dd']['HH:mm:ss']'", "'['yyyy']['M']['dd']['HH:mm:ss']'", "'['yyyy']['MM']['d']['HH:mm:ss']'", "'['yyyy']['M']['d']['HH:mm:ss']'", }; public static DateTime GetDateTime(string timeStr) { if (DateTime.TryParseExact(timeStr, Formats, null, DateTimeStyles.None, out var result)) { return result; } throw new FormatException($"Invalid date format. timeStr:{timeStr}"); } //转换成时间戳,单位毫秒 public static long GetTimestamp(string timeStr) { var dateTime = GetDateTime(timeStr); return TimeInfo.Instance.Transition(dateTime); } //当前时间加N天 public static long AddDays(int day) { return TimeInfo.Instance.ServerNow() + day * SECOND_PER_DAY * 1000; } /// /// 获取指定年月位周几, 周一为1 周日为7 /// /// /// /// 周几 public static int GetWeekday(int month, int day) { TimeInfo.Instance.ServerNow(); var date = new DateTime(DateTime.Now.Year, month, day); var weekdayNum = (int)date.DayOfWeek + 1; if (weekdayNum == 7) { weekdayNum = 1; } return weekdayNum; } /// /// 判断当前时间是否在时间段内 /// public static bool IsInTime(string startTimeStr, string endTimeStr) { var startTime = GetDateTime(startTimeStr); var endTime = GetDateTime(endTimeStr); var dateTime = DateTime.Now; return dateTime >= startTime && dateTime < endTime; } /// /// 获取日清时间戳 格式 ['yyyy']['M']['dd'] ['yyyy']['MM']['d'] 等 会自动加到真实日清时间点 GameConst.DAILY_RESET_HOUR /// 返回到DateTime /// public static DateTime GetResetTime(string timeStr) { var time = GetDateTime(timeStr); var resetTime = new DateTime(time.Year, time.Month, time.Day, GameConst.DAILY_RESET_HOUR, 0, 0); return resetTime; } public static long GetResetTimeSec(string timeStr) { var dateTime = GetResetTime(timeStr); return TimeInfo.Instance.Transition(dateTime); } /// /// 当前时间是否在传入时间日清时间之后 /// public static bool IsAfterResetTime(string timeStr) { var resetTime = GetResetTime(timeStr); return DateTime.Now > resetTime; } /// /// 获取当前时间属于那一年(1月1号5点前算上一年,5点后算今年) /// /// public static int GetCurYear() { //这个是东8时区的0时间戳,然后去获取服务器时间 DateTime unixStartTime = new DateTime(1970, 1, 1, 8, 0, 0); DateTime dateTime = unixStartTime.AddMilliseconds(TimeHelper.ServerNow()); if (dateTime.Hour < 5 && dateTime.Month == 1 && dateTime.Day == 1) { return dateTime.Year - 1; } else { return dateTime.Year; } } /// /// 获取服务器 当前时间属于那个月(1号5点前算上个月,5点后算本月) /// /// public static int GetCurMonth() { //这个是东8时区的0时间戳,然后去获取服务器时间 DateTime unixStartTime = new DateTime(1970, 1, 1, 8, 0, 0); DateTime dateTime = unixStartTime.AddMilliseconds(TimeHelper.ServerNow()); //if (TimeHelper.ServerNow() < TimeUtil.GetCurDayTime(GlobalCfgArray.globalCfg.refreshTime)) if (dateTime.Hour < 5 && dateTime.Day == 1) { if (dateTime.Month == 1) { return 12; } else { return dateTime.Month - 1; } } else { return dateTime.Month; } } /// /// 获取当前时间是本月的那一天(5点前算上一天,5点后算当天) /// /// public static int GetCurDay() { int _month = 0; //这个是东8时区的0时间戳,然后去获取服务器时间 DateTime unixStartTime = new DateTime(1970, 1, 1, 8, 0, 0); DateTime dateTime = unixStartTime.AddMilliseconds(TimeHelper.ServerNow()); //if (TimeHelper.ClientNow() < TimeUtil.GetCurDayTime(GlobalCfgArray.globalCfg.refreshTime)) if (dateTime.Hour < 5) { if (dateTime.Day == 1) { if (dateTime.Month == 1) { _month = 12; } else { _month = dateTime.Month - 1; } return DateTime.DaysInMonth(dateTime.Year, _month); } else { return dateTime.Day - 1; } } else { return dateTime.Day; } } //检查两个时间区间是否有重合 public static bool CheckTimeOverlap(long start1, long end1, long start2, long end2) { if (start1 >= start2 && start1 < end2) return true; if (end1 >= start2 && end1 < end2) return true; return start1 <= start2 && end1 >= end2; } //通过开始时间结束时间,算出是第几天, 单位毫秒 public static int GetDayByTime(long startTime, long endTime) { var day = (endTime - startTime) / (SECOND_PER_DAY * 1000); return (int)day; } //通过开始时间结束时间,算出是第几天,每天5点是一天的开始时间 单位毫秒 public static int GetDay5(long startTime) { var serverNow = TimeInfo.Instance.ServerNow(); var startDay5Time = GetDay5Time(startTime); var nowDay5Time = GetDay5Time(serverNow); var day = (nowDay5Time - startDay5Time) / (SECOND_PER_DAY * 1000); //开始时间在5点之前,算一天 if (startTime < startDay5Time) day++; //当前时间在5点之后,算一天 if (serverNow > nowDay5Time) day++; return (int)day; } public static long GetDay5Time(long time) { var date = TimeInfo.Instance.ToDateTime(time); var todayFive = new DateTime(date.Year, date.Month, date.Day, 5, 0, 0); return TimeInfo.Instance.Transition(todayFive); } //从一组周几数据中,匹配拿到周几,往前匹配,可用来做开始时间 public static int GetWeekDay(int[] days) { // 当前的“周几”数字,周日=0, 周一=1,..., 周六=6 DateTime current = TimeInfo.Instance.ToDateTime(TimeInfo.Instance.ServerNow()); int today = (int)current.DayOfWeek; // 如果数组中包含今天,则返回今天 if (Array.Exists(days, day => day == today)) { return today; } // 查找最近的之前的“周几” for (int i = 1; i <= 7; i++) { int previousDay = (today - i + 7) % 7; // 加7和取模是为了保证值在0-6之间 if (Array.Exists(days, day => day == previousDay)) { return previousDay; } } // 如果没有找到,则返回数组中的第一个“周几” return days[0]; } //从一组周几数据中,匹配拿到周几,往后匹配,可用来做结束时间 public static int GetNextWeekDay(int[] days) { // 当前的“周几”数字,周日=0, 周一=1,..., 周六=6 DateTime current = TimeInfo.Instance.ToDateTime(TimeInfo.Instance.ServerNow()); int today = (int)current.DayOfWeek; // 排序days数组以便查找 Array.Sort(days); // 查找最近的下一个“周几” foreach (int day in days) { if (day > today) { return day; } } // 如果没有找到下一个“周几”,则返回数组中的第一个,表示下一周的那一天 return days[0]; } /// /// 从一组周几数据中,匹配拿到周几,往前匹配,可用来做开始时间 /// /// /// public static DateTime GetWeekDayDateTime(int[] days) { // 获取当前的“周几”数字,周日=0, 周一=1, ..., 周六=6 DateTime current = TimeInfo.Instance.ToDateTime(TimeInfo.Instance.ServerNow()); int today = (int)current.DayOfWeek; // 如果数组中包含今天,则返回今天的日期对象 if (Array.Exists(days, day => day == today)) { return current.Date; // 返回当天的日期 } // 查找最近的之前的“周几” for (int i = 1; i <= 7; i++) { int previousDay = (today - i + 7) % 7; // 加7和取模是为了保证值在0-6之间 if (Array.Exists(days, day => day == previousDay)) { DateTime previousDateTime = current.AddDays(-i); return previousDateTime.Date; // 返回之前的日期 } } // 如果没有找到,则返回本周第一个“周几”的日期 DateTime firstDay = current.AddDays((days[0] - today + 7) % 7); return firstDay.Date; } /// /// 从一组周几数据中,匹配拿到周几,往后匹配,可用来做结束时间 /// /// /// public static DateTime GetNextWeekDayDateTime(int[] days) { // 获取当前的“周几”数字,周日=0, 周一=1, ..., 周六=6 DateTime current = TimeInfo.Instance.ToDateTime(TimeInfo.Instance.ServerNow()); int today = (int)current.DayOfWeek; // 排序days数组以便查找 Array.Sort(days); // 查找最近的下一个“周几” foreach (int day in days) { if (day > today) { DateTime nextDateTime = current.AddDays(day - today); return nextDateTime.Date; // 返回下一个工作日的日期 } } // 如果没有找到下一个“周几”,返回本周的第一个工作日的日期 DateTime firstDay = current.AddDays((days[0] + 7 - today) % 7); return firstDay.Date; } /// /// 获取今指定时间的时间戳,返回毫秒 /// /// public static long GetAppointedTime(DateTime dateTime, string time = "00:00:00") { var targetTimeStar = dateTime.ToString("yyyy-MM-dd ") + time; var date = DateTime.Parse(targetTimeStar); return TimeInfo.Instance.Transition(date); } /// /// 获取周几 N点的时间 /// /// DayOfWeek.Wednesday /// /// public static long GetNextWednesdayAm(int dayOfWeek, int hour) { DateTime now = DateTime.UtcNow; DayOfWeek currentDayOfWeek = now.DayOfWeek; int daysUntilWednesday = (dayOfWeek - (int)currentDayOfWeek + 7) % 7; // 如果今天已经过了周三,就计算下周的 if (daysUntilWednesday == 0 && now.Hour >= hour) { daysUntilWednesday = 7; // 下周的周三 } DateTime nextWednesday = now.Date.AddDays(daysUntilWednesday).AddHours(hour); return TimeInfo.Instance.Transition(nextWednesday); } // 将 DateTime 转换为 Unix 时间戳 public static long ConvertToUnixTimestamp(DateTime date) { DateTime unixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); TimeSpan timeSpan = date.ToUniversalTime() - unixEpoch; return (long)timeSpan.TotalSeconds; } } }