using System; namespace Sodao.FastSocket.SocketBase.Utils { /// /// 关于时间的一些操作 /// static public class Date { #region Private Members static private int lastTicks = -1; static private DateTime lastDateTime; /// /// unix下的纪元时间 /// static private readonly DateTime unixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); /// /// the max milliseconds since epoch. /// static private readonly long dateTimeMaxValueMillisecondsSinceEpoch = (DateTime.MaxValue - unixEpoch).Ticks / 10000; #endregion #region Public Methods /// /// Gets the current utc time in an optimized fashion. /// static public DateTime UtcNow { get { int tickCount = Environment.TickCount; if (tickCount == lastTicks) return lastDateTime; DateTime dt = DateTime.UtcNow; lastTicks = tickCount; lastDateTime = dt; return dt; } } /// /// Converts a DateTime to UTC (with special handling for MinValue and MaxValue). /// /// A DateTime. /// The DateTime in UTC. public static DateTime ToUniversalTime(DateTime dateTime) { if (dateTime.Kind == DateTimeKind.Utc) return dateTime; else { if (dateTime == DateTime.MinValue) return DateTime.SpecifyKind(DateTime.MinValue, DateTimeKind.Utc); else if (dateTime == DateTime.MaxValue) return DateTime.SpecifyKind(DateTime.MaxValue, DateTimeKind.Utc); else return dateTime.ToUniversalTime(); } } /// /// Converts a DateTime to number of milliseconds since Unix epoch. /// /// A DateTime. /// Number of seconds since Unix epoch. public static long ToMillisecondsSinceEpoch(DateTime dateTime) { return (ToUniversalTime(dateTime) - unixEpoch).Ticks / 10000; } /// /// Converts a DateTime to number of seconds since Unix epoch. /// /// A DateTime. /// Number of seconds since Unix epoch. public static long ToSecondsSinceEpoch(DateTime dateTime) { return ToMillisecondsSinceEpoch(dateTime) / 1000; } /// /// Converts from number of milliseconds since Unix epoch to DateTime. /// /// The number of milliseconds since Unix epoch. /// A DateTime. public static DateTime ToDateTimeFromMillisecondsSinceEpoch(long millisecondsSinceEpoch) { // MaxValue has to be handled specially to avoid rounding errors if (millisecondsSinceEpoch == dateTimeMaxValueMillisecondsSinceEpoch) return DateTime.SpecifyKind(DateTime.MaxValue, DateTimeKind.Utc); else return unixEpoch.AddTicks(millisecondsSinceEpoch * 10000); } /// /// Converts from number of seconds since Unix epoch to DateTime. /// /// The number of seconds since Unix epoch. /// A DateTime. public static DateTime ToDateTimeFromSecondsSinceEpoch(long secondsSinceEpoch) { return ToDateTimeFromMillisecondsSinceEpoch(secondsSinceEpoch * 1000); } /// /// Converts a DateTime to local time (with special handling for MinValue and MaxValue). /// /// A DateTime. /// A DateTimeKind. /// The DateTime in local time. public static DateTime ToLocalTime(DateTime dateTime, DateTimeKind kind) { if (dateTime.Kind == kind) return dateTime; else { if (dateTime == DateTime.MinValue) return DateTime.SpecifyKind(DateTime.MinValue, kind); else if (dateTime == DateTime.MaxValue) return DateTime.SpecifyKind(DateTime.MaxValue, kind); else return DateTime.SpecifyKind(dateTime.ToLocalTime(), kind); } } /// /// SpecifyKind /// /// /// /// public static DateTime SpecifyKind(DateTime dt, DateTimeKind kind) { if (dt.Kind == kind) return dt; return DateTime.SpecifyKind(dt, kind); } #endregion } }