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
}
}