Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 127 lines (107 sloc) 4.272 kB
f4b065b @nberardi moved around some code from issues #28 and #30 and used DateTimePreci…
nberardi authored
1 using System;
2 using System.Diagnostics;
3
4 namespace System
5 {
6 /// DateTimePrecise class in C# -- an improvement to DateTime.Now
7 /// By jamesdbrock
8 /// http://www.codeproject.com/KB/cs/DateTimePrecise.aspx
9 /// Licensed via The Code Project Open License (CPOL) 1.02
10 /// http://www.codeproject.com/info/cpol10.aspx
11 ///
12 /// DateTimePrecise provides a way to get a DateTime that exhibits the
13 /// relative precision of
14 /// System.Diagnostics.Stopwatch, and the absolute accuracy of DateTime.Now.
15 public class DateTimePrecise
16 {
17 private static readonly DateTimePrecise PrivateHelperInstance = new DateTimePrecise(10);
18
19 /// <summary>Returns the current date and time, just like DateTime.Now.</summary>
20 public static DateTime Now
21 {
22 get { return PrivateHelperInstance.GetNow(); }
23 }
24
25 /// <summary>Returns the current date and time, just like DateTime.UtcNow.</summary>
26 public static DateTime UtcNow
27 {
28 get { return PrivateHelperInstance.GetUtcNow(); }
29 }
30
31 /// <summary>Returns the current date and time, just like DateTimeOffset.Now.</summary>
32 public static DateTimeOffset NowOffset
33 {
34 get { return PrivateHelperInstance.GetNowOffset(); }
35 }
36
37 /// <summary>Returns the current date and time, just like DateTimeOffset.UtcNow.</summary>
38 public static DateTimeOffset UtcNowOffset
39 {
40 get { return PrivateHelperInstance.GetUtcNowOffset(); }
41 }
42
43 private const long ClockTickFrequency = 10000000;
44
45 private readonly Stopwatch _stopwatch;
46 private readonly long _synchronizePeriodStopwatchTicks;
47 private DateTimePreciseSafeImmutable _immutable;
48
49 /// <summary>Creates a new instance of DateTimePrecise.
50 /// A large value of synchronizePeriodSeconds may cause arithmetic overthrow
51 /// exceptions to be thrown. A small value may cause the time to be unstable.
52 /// A good value is 10.
53 /// synchronizePeriodSeconds = The number of seconds after which the
54 /// DateTimePrecise will synchronize itself with the system clock.</summary>
55 public DateTimePrecise(long synchronizePeriodSeconds)
56 {
57 _stopwatch = Stopwatch.StartNew();
58 _stopwatch.Start();
59
60 var utc = DateTime.UtcNow;
61 _immutable = new DateTimePreciseSafeImmutable(utc, utc, _stopwatch.ElapsedTicks, Stopwatch.Frequency);
62
63 _synchronizePeriodStopwatchTicks = synchronizePeriodSeconds * Stopwatch.Frequency;
64 }
65
66 /// <summary>Returns the current date and time, just like DateTime.UtcNow.</summary>
67 public DateTime GetUtcNow()
68 {
69 var stopWatchTicks = _stopwatch.ElapsedTicks;
70 var immutable = _immutable;
71
72 if (stopWatchTicks < immutable.ObservedTicks + _synchronizePeriodStopwatchTicks)
73 {
74 return immutable.BaseTime.AddTicks(((
efd5d8c @nberardi added Math.Max(1, *) to preven the devide by zero exception in issue #48
nberardi authored
75 stopWatchTicks - immutable.ObservedTicks) * ClockTickFrequency) / (immutable.StopWatchFrequency));
f4b065b @nberardi moved around some code from issues #28 and #30 and used DateTimePreci…
nberardi authored
76 }
77 else
78 {
79 var utc = DateTime.UtcNow;
80
efd5d8c @nberardi added Math.Max(1, *) to preven the devide by zero exception in issue #48
nberardi authored
81 DateTime tBaseNew = immutable.BaseTime.AddTicks(((stopWatchTicks - immutable.ObservedTicks) * ClockTickFrequency) / (immutable.StopWatchFrequency));
f4b065b @nberardi moved around some code from issues #28 and #30 and used DateTimePreci…
nberardi authored
82
83 _immutable = new DateTimePreciseSafeImmutable(
84 utc,
85 tBaseNew,
86 stopWatchTicks,
efd5d8c @nberardi added Math.Max(1, *) to preven the devide by zero exception in issue #48
nberardi authored
87 ((stopWatchTicks - immutable.ObservedTicks) * ClockTickFrequency * 2) / (3 * utc.Ticks - 2 * immutable.ObservedTime.Ticks - tBaseNew.Ticks));
f4b065b @nberardi moved around some code from issues #28 and #30 and used DateTimePreci…
nberardi authored
88
89 return tBaseNew;
90 }
91 }
92
93 /// <summary>Returns the current date and time, just like DateTime.Now.</summary>
94 public DateTime GetNow()
95 {
96 return GetUtcNow().ToLocalTime();
97 }
98
99 /// <summary>Returns the current date and time, just like DateTimeOffset.UtcNow.</summary>
100 public DateTimeOffset GetUtcNowOffset()
101 {
102 return new DateTimeOffset(GetUtcNow());
103 }
104
105 /// <summary>Returns the current date and time, just like DateTimeOffset.Now.</summary>
106 public DateTimeOffset GetNowOffset()
107 {
108 return new DateTimeOffset(GetNow());
109 }
110
2c77dfc @nberardi refactored mutation handling to better handle super columns which fix…
nberardi authored
111 private struct DateTimePreciseSafeImmutable
f4b065b @nberardi moved around some code from issues #28 and #30 and used DateTimePreci…
nberardi authored
112 {
113 public DateTimePreciseSafeImmutable(DateTime observedTime, DateTime baseTime, long observedTicks, long stopWatchFrequency)
114 {
115 ObservedTime = observedTime;
116 BaseTime = baseTime;
117 ObservedTicks = observedTicks;
efd5d8c @nberardi added Math.Max(1, *) to preven the devide by zero exception in issue #48
nberardi authored
118 StopWatchFrequency = Math.Max(1, stopWatchFrequency);
f4b065b @nberardi moved around some code from issues #28 and #30 and used DateTimePreci…
nberardi authored
119 }
120
121 public readonly DateTime ObservedTime;
122 public readonly DateTime BaseTime;
123 public readonly long ObservedTicks;
124 public readonly long StopWatchFrequency;
125 }
126 }
127 }
Something went wrong with that request. Please try again.