schangxiang@126.com
2025-11-04 f5ed29dc26c7cd952d56ec5721a2efc43cd25992
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
using System;
 
namespace Sodao.FastSocket.SocketBase.Utils
{
    /// <summary>
    /// 关于时间的一些操作
    /// </summary>
    static public class Date
    {
        #region Private Members
        static private int lastTicks = -1;
        static private DateTime lastDateTime;
 
        /// <summary>
        /// unix下的纪元时间
        /// </summary>
        static private readonly DateTime unixEpoch =
            new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
        /// <summary>
        /// the max milliseconds since epoch.
        /// </summary>
        static private readonly long dateTimeMaxValueMillisecondsSinceEpoch =
            (DateTime.MaxValue - unixEpoch).Ticks / 10000;
        #endregion
 
        #region Public Methods
        /// <summary>
        /// Gets the current utc time in an optimized fashion.
        /// </summary>
        static public DateTime UtcNow
        {
            get
            {
                int tickCount = Environment.TickCount;
                if (tickCount == lastTicks) return lastDateTime;
 
                DateTime dt = DateTime.UtcNow;
                lastTicks = tickCount;
                lastDateTime = dt;
                return dt;
            }
        }
        /// <summary>
        /// Converts a DateTime to UTC (with special handling for MinValue and MaxValue).
        /// </summary>
        /// <param name="dateTime">A DateTime.</param>
        /// <returns>The DateTime in UTC.</returns>
        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();
            }
        }
        /// <summary>
        /// Converts a DateTime to number of milliseconds since Unix epoch.
        /// </summary>
        /// <param name="dateTime">A DateTime.</param>
        /// <returns>Number of seconds since Unix epoch.</returns>
        public static long ToMillisecondsSinceEpoch(DateTime dateTime)
        {
            return (ToUniversalTime(dateTime) - unixEpoch).Ticks / 10000;
        }
        /// <summary>
        /// Converts a DateTime to number of seconds since Unix epoch.
        /// </summary>
        /// <param name="dateTime">A DateTime.</param>
        /// <returns>Number of seconds since Unix epoch.</returns>
        public static long ToSecondsSinceEpoch(DateTime dateTime)
        {
            return ToMillisecondsSinceEpoch(dateTime) / 1000;
        }
        /// <summary>
        /// Converts from number of milliseconds since Unix epoch to DateTime.
        /// </summary>
        /// <param name="millisecondsSinceEpoch">The number of milliseconds since Unix epoch.</param>
        /// <returns>A DateTime.</returns>
        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);
        }
        /// <summary>
        /// Converts from number of seconds since Unix epoch to DateTime.
        /// </summary>
        /// <param name="secondsSinceEpoch">The number of seconds since Unix epoch.</param>
        /// <returns>A DateTime.</returns>
        public static DateTime ToDateTimeFromSecondsSinceEpoch(long secondsSinceEpoch)
        {
            return ToDateTimeFromMillisecondsSinceEpoch(secondsSinceEpoch * 1000);
        }
        /// <summary>
        /// Converts a DateTime to local time (with special handling for MinValue and MaxValue).
        /// </summary>
        /// <param name="dateTime">A DateTime.</param>
        /// <param name="kind">A DateTimeKind.</param>
        /// <returns>The DateTime in local time.</returns>
        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);
            }
        }
        /// <summary>
        /// SpecifyKind
        /// </summary>
        /// <param name="dt"></param>
        /// <param name="kind"></param>
        /// <returns></returns>
        public static DateTime SpecifyKind(DateTime dt, DateTimeKind kind)
        {
            if (dt.Kind == kind) return dt;
            return DateTime.SpecifyKind(dt, kind);
        }
        #endregion
    }
}