Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiguel de Icaza <miguel@gnome.org>2015-10-14 06:03:43 +0300
committerMarek Safar <marek.safar@gmail.com>2016-05-03 01:10:27 +0300
commit5f82524097130bf3e29844adcb47d1695bb14c6b (patch)
treeb27b022f5c8c7e83039f383cfd2120f70248caaf /mcs/class/referencesource/mscorlib/system
parent2c381b5a7f699f4a0f3839bdb61ee79aca374376 (diff)
DateTime, DateTimeOffset, bring Unix time APIs from CoreCLR
Diffstat (limited to 'mcs/class/referencesource/mscorlib/system')
-rw-r--r--mcs/class/referencesource/mscorlib/system/datetime.cs3
-rw-r--r--mcs/class/referencesource/mscorlib/system/datetimeoffset.cs75
2 files changed, 68 insertions, 10 deletions
diff --git a/mcs/class/referencesource/mscorlib/system/datetime.cs b/mcs/class/referencesource/mscorlib/system/datetime.cs
index 216fe8d12a6..930ed91fd50 100644
--- a/mcs/class/referencesource/mscorlib/system/datetime.cs
+++ b/mcs/class/referencesource/mscorlib/system/datetime.cs
@@ -82,6 +82,9 @@ namespace System {
private const int DaysTo1601 = DaysPer400Years * 4; // 584388
// Number of days from 1/1/0001 to 12/30/1899
private const int DaysTo1899 = DaysPer400Years * 4 + DaysPer100Years * 3 - 367;
+ // Number of days from 1/1/0001 to 12/31/1969
+ internal const int DaysTo1970 = DaysPer400Years * 4 + DaysPer100Years * 3 + DaysPer4Years * 17 + DaysPerYear; // 719,162
+
// Number of days from 1/1/0001 to 12/31/9999
private const int DaysTo10000 = DaysPer400Years * 25 - 366; // 3652059
diff --git a/mcs/class/referencesource/mscorlib/system/datetimeoffset.cs b/mcs/class/referencesource/mscorlib/system/datetimeoffset.cs
index 8f0aa8715bf..7f0348a838f 100644
--- a/mcs/class/referencesource/mscorlib/system/datetimeoffset.cs
+++ b/mcs/class/referencesource/mscorlib/system/datetimeoffset.cs
@@ -1,8 +1,6 @@
-// ==++==
-//
-// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-// ==--==
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
namespace System {
using System;
@@ -41,7 +39,14 @@ namespace System {
// Constants
internal const Int64 MaxOffset = TimeSpan.TicksPerHour * 14;
internal const Int64 MinOffset = -MaxOffset;
-
+
+ private const long UnixEpochTicks = TimeSpan.TicksPerDay * DateTime.DaysTo1970; // 621,355,968,000,000,000
+ private const long UnixEpochSeconds = UnixEpochTicks / TimeSpan.TicksPerSecond; // 62,135,596,800
+ private const long UnixEpochMilliseconds = UnixEpochTicks / TimeSpan.TicksPerMillisecond; // 62,135,596,800,000
+
+ internal const long UnixMinSeconds = DateTime.MinTicks / TimeSpan.TicksPerSecond - UnixEpochSeconds;
+ internal const long UnixMaxSeconds = DateTime.MaxTicks / TimeSpan.TicksPerSecond - UnixEpochSeconds;
+
// Static Fields
public static readonly DateTimeOffset MinValue = new DateTimeOffset(DateTime.MinTicks, TimeSpan.Zero);
public static readonly DateTimeOffset MaxValue = new DateTimeOffset(DateTime.MaxTicks, TimeSpan.Zero);
@@ -60,8 +65,8 @@ namespace System {
m_dateTime = ValidateDate(dateTime, offset);
}
- // Constructs a DateTimeOffset from a DateTime. For UTC and Unspecified kinds, creates a
- // UTC instance with a zero offset. For local, extracts the local offset.
+ // Constructs a DateTimeOffset from a DateTime. For Local and Unspecified kinds,
+ // extracts the local offset. For UTC, creates a UTC instance with a zero offset.
public DateTimeOffset(DateTime dateTime) {
TimeSpan offset;
if (dateTime.Kind != DateTimeKind.Utc) {
@@ -470,8 +475,30 @@ namespace System {
public static DateTimeOffset FromFileTime(long fileTime) {
return new DateTimeOffset(DateTime.FromFileTime(fileTime));
}
-
+ public static DateTimeOffset FromUnixTimeSeconds(long seconds) {
+ if (seconds < UnixMinSeconds || seconds > UnixMaxSeconds) {
+ throw new ArgumentOutOfRangeException("seconds",
+ string.Format(Environment.GetResourceString("ArgumentOutOfRange_Range"), UnixMinSeconds, UnixMaxSeconds));
+ }
+
+ long ticks = seconds * TimeSpan.TicksPerSecond + UnixEpochTicks;
+ return new DateTimeOffset(ticks, TimeSpan.Zero);
+ }
+
+ public static DateTimeOffset FromUnixTimeMilliseconds(long milliseconds) {
+ const long MinMilliseconds = DateTime.MinTicks / TimeSpan.TicksPerMillisecond - UnixEpochMilliseconds;
+ const long MaxMilliseconds = DateTime.MaxTicks / TimeSpan.TicksPerMillisecond - UnixEpochMilliseconds;
+
+ if (milliseconds < MinMilliseconds || milliseconds > MaxMilliseconds) {
+ throw new ArgumentOutOfRangeException("milliseconds",
+ string.Format(Environment.GetResourceString("ArgumentOutOfRange_Range"), MinMilliseconds, MaxMilliseconds));
+ }
+
+ long ticks = milliseconds * TimeSpan.TicksPerMillisecond + UnixEpochTicks;
+ return new DateTimeOffset(ticks, TimeSpan.Zero);
+ }
+
// ----- SECTION: private serialization instance methods ----------------*
#if FEATURE_SERIALIZATION
@@ -592,6 +619,34 @@ namespace System {
public long ToFileTime() {
return UtcDateTime.ToFileTime();
}
+
+ public long ToUnixTimeSeconds() {
+ // Truncate sub-second precision before offsetting by the Unix Epoch to avoid
+ // the last digit being off by one for dates that result in negative Unix times.
+ //
+ // For example, consider the DateTimeOffset 12/31/1969 12:59:59.001 +0
+ // ticks = 621355967990010000
+ // ticksFromEpoch = ticks - UnixEpochTicks = -9990000
+ // secondsFromEpoch = ticksFromEpoch / TimeSpan.TicksPerSecond = 0
+ //
+ // Notice that secondsFromEpoch is rounded *up* by the truncation induced by integer division,
+ // whereas we actually always want to round *down* when converting to Unix time. This happens
+ // automatically for positive Unix time values. Now the example becomes:
+ // seconds = ticks / TimeSpan.TicksPerSecond = 62135596799
+ // secondsFromEpoch = seconds - UnixEpochSeconds = -1
+ //
+ // In other words, we want to consistently round toward the time 1/1/0001 00:00:00,
+ // rather than toward the Unix Epoch (1/1/1970 00:00:00).
+ long seconds = UtcDateTime.Ticks / TimeSpan.TicksPerSecond;
+ return seconds - UnixEpochSeconds;
+ }
+
+ public long ToUnixTimeMilliseconds() {
+ // Truncate sub-millisecond precision before offsetting by the Unix Epoch to avoid
+ // the last digit being off by one for dates that result in negative Unix times
+ long milliseconds = UtcDateTime.Ticks / TimeSpan.TicksPerMillisecond;
+ return milliseconds - UnixEpochMilliseconds;
+ }
public DateTimeOffset ToLocalTime() {
return ToLocalTime(false);
@@ -721,7 +776,7 @@ namespace System {
}
Contract.EndContractBlock();
- // RoundtripKind does not make sense for DateTimeOffset; ignore this flag for backward compatability with DateTime
+ // RoundtripKind does not make sense for DateTimeOffset; ignore this flag for backward compatibility with DateTime
style &= ~DateTimeStyles.RoundtripKind;
// AssumeLocal is also ignored as that is what we do by default with DateTimeOffset.Parse