Skip to content

Commit 999561a

Browse files
authored
Fix DateTime ticks discrepancy from full .NET (#80)
1 parent f3f0113 commit 999561a

File tree

2 files changed

+21
-19
lines changed

2 files changed

+21
-19
lines changed

source/nanoFramework.CoreLibrary/System/DateTime.cs

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,13 @@ public enum DateTimeKind
5454
[Serializable]
5555
public struct DateTime
5656
{
57+
/// Our origin is at 1601/01/01:00:00:00.000
58+
/// While desktop CLR's origin is at 0001/01/01:00:00:00.000.
59+
/// There are 504911232000000000 ticks between them which we are subtracting.
60+
/// See nf-interpreter\src\HAL\Include\nanoHAL_Time.h for explanation of why we are taking
61+
/// year 1601 as origin for our HAL, PAL, and CLR.
62+
private const long _ticksAtOrigin = 504911232000000000;
63+
5764
// Number of 100ns ticks per time unit
5865
private const long TicksPerMillisecond = 10000;
5966
private const long TicksPerSecond = TicksPerMillisecond * 1000;
@@ -70,20 +77,21 @@ public struct DateTime
7077
private const long MinTicks = 0;
7178
private const long MaxTicks = 441796895990000000;
7279

73-
// This is mask to extract ticks from m_ticks
80+
// This is mask to extract ticks from _ticks
7481
private const ulong TickMask = 0x7FFFFFFFFFFFFFFFL;
7582
private const ulong UtcMask = 0x8000000000000000L;
7683

7784
/// <summary>
7885
/// Represents the smallest possible value of DateTime. This field is read-only.
7986
/// </summary>
8087
/// <remarks>The value of this constant is equivalent to 00:00:00.0000000, January 1, 1601.</remarks>
81-
public static readonly DateTime MinValue = new DateTime(MinTicks);
88+
public static readonly DateTime MinValue = new DateTime(MinTicks + _ticksAtOrigin);
89+
8290
/// <summary>
8391
/// Represents the largest possible value of DateTime. This field is read-only.
8492
/// </summary>
8593
/// <remarks>The value of this constant is equivalent to 23:59:59.9999999, December 31, 9999, exactly one tick (100 nanoseconds) before 00:00:00, January 1, 10000.</remarks>
86-
public static readonly DateTime MaxValue = new DateTime(MaxTicks);
94+
public static readonly DateTime MaxValue = new DateTime(MaxTicks + _ticksAtOrigin);
8795

8896
private ulong _ticks;
8997

@@ -94,6 +102,8 @@ public struct DateTime
94102
/// <exception cref="System.ArgumentOutOfRangeException">ticks - Ticks must be between DateTime.MinValue.Ticks and DateTime.MaxValue.Ticks.</exception>
95103
public DateTime(long ticks)
96104
{
105+
ticks -= _ticksAtOrigin;
106+
97107
#pragma warning disable S3928 // Parameter names used into ArgumentException constructors should match an existing one
98108
if ((ticks & (long)TickMask) < MinTicks || (ticks & (long)TickMask) > MaxTicks) throw new ArgumentOutOfRangeException();
99109
#pragma warning restore S3928 // Parameter names used into ArgumentException constructors should match an existing one
@@ -158,12 +168,12 @@ public DateTime(int year, int month, int day, int hour, int minute, int second)
158168
/// <returns>An object whose value is the sum of the date and time represented by this instance and the time interval represented by val.</returns>
159169
public DateTime Add(TimeSpan val)
160170
{
161-
return new DateTime((long)_ticks + val.Ticks);
171+
return new DateTime((long)_ticks + val.Ticks + _ticksAtOrigin);
162172
}
163173

164174
private DateTime Add(double val, int scale)
165175
{
166-
return new DateTime((long)_ticks + (long)(val * scale * TicksPerMillisecond + (val >= 0 ? 0.5 : -0.5)));
176+
return new DateTime((long)_ticks + (long)(val * scale * TicksPerMillisecond + (val >= 0 ? 0.5 : -0.5)) + _ticksAtOrigin);
167177
}
168178

169179
/// <summary>
@@ -223,7 +233,7 @@ public DateTime AddSeconds(double val)
223233
/// <returns>An object whose value is the sum of the date and time represented by this instance and the time represented by val.</returns>
224234
public DateTime AddTicks(long val)
225235
{
226-
return new DateTime((long)_ticks + val);
236+
return new DateTime((long)_ticks + val + _ticksAtOrigin);
227237
}
228238

229239
/// <summary>
@@ -440,14 +450,6 @@ public extern int Second
440450
get;
441451
}
442452

443-
/// Our origin is at 1601/01/01:00:00:00.000
444-
/// While desktop CLR's origin is at 0001/01/01:00:00:00.000.
445-
/// There are 504911232000000000 ticks between them which we are subtracting.
446-
/// See DeviceCode\PAL\time_decl.h for explanation of why we are taking
447-
/// year 1601 as origin for our HAL, PAL, and CLR.
448-
// static Int64 ticksAtOrigin = 504911232000000000;
449-
private const Int64 TicksAtOrigin = 0;
450-
451453
/// <summary>
452454
/// Gets the number of ticks that represent the date and time of this instance.
453455
/// </summary>
@@ -458,7 +460,7 @@ public long Ticks
458460
{
459461
get
460462
{
461-
return (long)(_ticks & TickMask) + TicksAtOrigin;
463+
return (long)(_ticks & TickMask) + _ticksAtOrigin;
462464
}
463465
}
464466

@@ -507,7 +509,7 @@ public extern int Year
507509
/// <returns>A time interval that is equal to the date and time represented by this instance minus the date and time represented by val.</returns>
508510
public TimeSpan Subtract(DateTime val)
509511
{
510-
return new TimeSpan((long)(_ticks & TickMask) - (long)(val._ticks & TickMask));
512+
return new TimeSpan((long)(_ticks & TickMask) - (long)(val._ticks & TickMask) + _ticksAtOrigin);
511513
}
512514

513515
/// <summary>
@@ -549,7 +551,7 @@ public String ToString(String format)
549551
/// </returns>
550552
public static DateTime operator +(DateTime d, TimeSpan t)
551553
{
552-
return new DateTime((long)(d._ticks + (ulong)t._ticks));
554+
return new DateTime((long)(d._ticks + (ulong)t._ticks) + _ticksAtOrigin);
553555
}
554556

555557

@@ -563,7 +565,7 @@ public String ToString(String format)
563565
/// </returns>
564566
public static DateTime operator -(DateTime d, TimeSpan t)
565567
{
566-
return new DateTime((long)(d._ticks - (ulong)t._ticks));
568+
return new DateTime((long)(d._ticks - (ulong)t._ticks) + _ticksAtOrigin);
567569
}
568570

569571
/// <summary>

source/version.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"$schema": "https://raw.githubusercontent.com/AArnott/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
3-
"version": "1.2.4-preview.{height}",
3+
"version": "1.2.5-preview.{height}",
44
"assemblyVersion": {
55
"precision": "revision"
66
},

0 commit comments

Comments
 (0)