+++ /dev/null
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-/*============================================================
-**
-**
-**
-** Purpose:
-** This class represents the current system timezone. It is
-** the only meaningful implementation of the TimeZone class
-** available in this version.
-**
-** The only TimeZone that we support in version 1 is the
-** CurrentTimeZone as determined by the system timezone.
-**
-**
-============================================================*/
-
-using System;
-using System.Diagnostics.Contracts;
-using System.Text;
-using System.Collections;
-using System.Globalization;
-using System.Runtime.CompilerServices;
-using System.Runtime.Versioning;
-
-namespace System
-{
- [Obsolete("System.CurrentSystemTimeZone has been deprecated. Please investigate the use of System.TimeZoneInfo.Local instead.")]
- [Serializable]
- internal partial class CurrentSystemTimeZone : TimeZone
- {
- // Standard offset in ticks to the Universal time if
- // no daylight saving is in used.
- // E.g. the offset for PST (Pacific Standard time) should be -8 * 60 * 60 * 1000 * 10000.
- // (1 millisecond = 10000 ticks)
- private long m_ticksOffset;
- private String m_standardName;
- private String m_daylightName;
-
- internal CurrentSystemTimeZone()
- {
- TimeZoneInfo local = TimeZoneInfo.Local;
-
- m_ticksOffset = local.BaseUtcOffset.Ticks;
- m_standardName = local.StandardName;
- m_daylightName = local.DaylightName;
- }
-
- public override String StandardName
- {
- get
- {
- return m_standardName;
- }
- }
-
- public override String DaylightName
- {
- get
- {
- return m_daylightName;
- }
- }
-
- internal long GetUtcOffsetFromUniversalTime(DateTime time, ref Boolean isAmbiguousLocalDst)
- {
- // Get the daylight changes for the year of the specified time.
- TimeSpan offset = new TimeSpan(m_ticksOffset);
- DaylightTime daylightTime = GetDaylightChanges(time.Year);
- isAmbiguousLocalDst = false;
-
- if (daylightTime == null || daylightTime.Delta.Ticks == 0)
- {
- return offset.Ticks;
- }
-
- // The start and end times represent the range of universal times that are in DST for that year.
- // Within that there is an ambiguous hour, usually right at the end, but at the beginning in
- // the unusual case of a negative daylight savings delta.
- DateTime startTime = daylightTime.Start - offset;
- DateTime endTime = daylightTime.End - offset - daylightTime.Delta;
- DateTime ambiguousStart;
- DateTime ambiguousEnd;
-
- if (daylightTime.Delta.Ticks > 0)
- {
- ambiguousStart = endTime - daylightTime.Delta;
- ambiguousEnd = endTime;
- }
- else
- {
- ambiguousStart = startTime;
- ambiguousEnd = startTime - daylightTime.Delta;
- }
-
- Boolean isDst = false;
- if (startTime > endTime)
- {
- // In southern hemisphere, the daylight saving time starts later in the year, and ends in the beginning of next year.
- // Note, the summer in the southern hemisphere begins late in the year.
- isDst = (time < endTime || time >= startTime);
- }
- else
- {
- // In northern hemisphere, the daylight saving time starts in the middle of the year.
- isDst = (time >= startTime && time < endTime);
- }
-
- if (isDst)
- {
- offset += daylightTime.Delta;
-
- // See if the resulting local time becomes ambiguous. This must be captured here or the
- // DateTime will not be able to round-trip back to UTC accurately.
- if (time >= ambiguousStart && time < ambiguousEnd)
- {
- isAmbiguousLocalDst = true;
- }
- }
- return offset.Ticks;
- }
-
- public override DateTime ToLocalTime(DateTime time)
- {
- if (time.Kind == DateTimeKind.Local)
- {
- return time;
- }
- Boolean isAmbiguousLocalDst = false;
- Int64 offset = GetUtcOffsetFromUniversalTime(time, ref isAmbiguousLocalDst);
- long tick = time.Ticks + offset;
- if (tick > DateTime.MaxTicks)
- {
- return new DateTime(DateTime.MaxTicks, DateTimeKind.Local);
- }
- if (tick < DateTime.MinTicks)
- {
- return new DateTime(DateTime.MinTicks, DateTimeKind.Local);
- }
- return new DateTime(tick, DateTimeKind.Local, isAmbiguousLocalDst);
- }
-
- public override DaylightTime GetDaylightChanges(int year)
- {
- if (year < 1 || year > 9999)
- {
- throw new ArgumentOutOfRangeException(nameof(year), SR.Format(SR.ArgumentOutOfRange_Range, 1, 9999));
- }
-
- return GetCachedDaylightChanges(year);
- }
-
- private static DaylightTime CreateDaylightChanges(int year)
- {
- DaylightTime currentDaylightChanges = null;
-
- if (TimeZoneInfo.Local.SupportsDaylightSavingTime)
- {
- DateTime start;
- DateTime end;
- TimeSpan delta;
-
- foreach (var rule in TimeZoneInfo.Local.GetAdjustmentRules())
- {
- if (rule.DateStart.Year <= year && rule.DateEnd.Year >= year && rule.DaylightDelta != TimeSpan.Zero)
- {
- start = TimeZoneInfo.TransitionTimeToDateTime(year, rule.DaylightTransitionStart);
- end = TimeZoneInfo.TransitionTimeToDateTime(year, rule.DaylightTransitionEnd);
- delta = rule.DaylightDelta;
-
- currentDaylightChanges = new DaylightTime(start, end, delta);
- break;
- }
- }
- }
-
- if (currentDaylightChanges == null)
- {
- currentDaylightChanges = new DaylightTime(DateTime.MinValue, DateTime.MinValue, TimeSpan.Zero);
- }
-
- return currentDaylightChanges;
- }
-
- public override TimeSpan GetUtcOffset(DateTime time)
- {
- if (time.Kind == DateTimeKind.Utc)
- {
- return TimeSpan.Zero;
- }
- else
- {
- return new TimeSpan(TimeZone.CalculateUtcOffset(time, GetDaylightChanges(time.Year)).Ticks + m_ticksOffset);
- }
- }
- } // class CurrentSystemTimeZone
-}
+++ /dev/null
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-/*============================================================
-**
-**
-**
-** Purpose:
-** This class is used to represent a TimeZone. It
-** has methods for converting a DateTime to UTC from local time
-** and to local time from UTC and methods for getting the
-** standard name and daylight name of the time zone.
-**
-** The only TimeZone that we support in version 1 is the
-** CurrentTimeZone as determined by the system timezone.
-**
-**
-============================================================*/
-
-using System;
-using System.Text;
-using System.Threading;
-using System.Collections;
-using System.Diagnostics;
-using System.Globalization;
-
-namespace System
-{
- [Serializable]
- [Obsolete("System.TimeZone has been deprecated. Please investigate the use of System.TimeZoneInfo instead.")]
- public abstract class TimeZone
- {
- private static volatile TimeZone currentTimeZone = null;
-
- // Private object for locking instead of locking on a public type for SQL reliability work.
- private static Object s_InternalSyncObject;
- private static Object InternalSyncObject
- {
- get
- {
- if (s_InternalSyncObject == null)
- {
- Object o = new Object();
- Interlocked.CompareExchange<Object>(ref s_InternalSyncObject, o, null);
- }
- return s_InternalSyncObject;
- }
- }
-
-
- protected TimeZone()
- {
- }
-
- public static TimeZone CurrentTimeZone
- {
- get
- {
- //Grabbing the cached value is required at the top of this function so that
- //we don't incur a race condition with the ResetTimeZone method below.
- TimeZone tz = currentTimeZone;
- if (tz == null)
- {
- lock (InternalSyncObject)
- {
- if (currentTimeZone == null)
- {
- currentTimeZone = new CurrentSystemTimeZone();
- }
- tz = currentTimeZone;
- }
- }
- return (tz);
- }
- }
-
- //This method is called by CultureInfo.ClearCachedData in response to control panel
- //change events. It must be synchronized because otherwise there is a race condition
- //with the CurrentTimeZone property above.
- internal static void ResetTimeZone()
- {
- if (currentTimeZone != null)
- {
- lock (InternalSyncObject)
- {
- currentTimeZone = null;
- }
- }
- }
-
- public abstract String StandardName
- {
- get;
- }
-
- public abstract String DaylightName
- {
- get;
- }
-
- public abstract TimeSpan GetUtcOffset(DateTime time);
-
- //
- // Converts the specified datatime to the Universal time base on the current timezone
- //
- public virtual DateTime ToUniversalTime(DateTime time)
- {
- if (time.Kind == DateTimeKind.Utc)
- {
- return time;
- }
- long tickCount = time.Ticks - GetUtcOffset(time).Ticks;
- if (tickCount > DateTime.MaxTicks)
- {
- return new DateTime(DateTime.MaxTicks, DateTimeKind.Utc);
- }
- if (tickCount < DateTime.MinTicks)
- {
- return new DateTime(DateTime.MinTicks, DateTimeKind.Utc);
- }
- return new DateTime(tickCount, DateTimeKind.Utc);
- }
-
- //
- // Convert the specified datetime value from UTC to the local time based on the time zone.
- //
- public virtual DateTime ToLocalTime(DateTime time)
- {
- if (time.Kind == DateTimeKind.Local)
- {
- return time;
- }
- Boolean isAmbiguousLocalDst = false;
- Int64 offset = ((CurrentSystemTimeZone)(TimeZone.CurrentTimeZone)).GetUtcOffsetFromUniversalTime(time, ref isAmbiguousLocalDst);
- return new DateTime(time.Ticks + offset, DateTimeKind.Local, isAmbiguousLocalDst);
- }
-
- // Return an array of DaylightTime which reflects the daylight saving periods in a particular year.
- // We currently only support having one DaylightSavingTime per year.
- // If daylight saving time is not used in this timezone, null will be returned.
- public abstract DaylightTime GetDaylightChanges(int year);
-
- public virtual bool IsDaylightSavingTime(DateTime time)
- {
- return (IsDaylightSavingTime(time, GetDaylightChanges(time.Year)));
- }
-
- // Check if the specified time is in a daylight saving time. Allows the user to
- // specify the array of Daylight Saving Times.
- public static bool IsDaylightSavingTime(DateTime time, DaylightTime daylightTimes)
- {
- return CalculateUtcOffset(time, daylightTimes) != TimeSpan.Zero;
- }
-
- //
- // NOTENOTE: Implementation detail
- // In the transition from standard time to daylight saving time,
- // if we convert local time to Universal time, we can have the
- // following (take PST as an example):
- // Local Universal UTC Offset
- // ----- --------- ----------
- // 01:00AM 09:00 -8:00
- // 02:00 (=> 03:00) 10:00 -8:00 [This time doesn't actually exist, but it can be created from DateTime]
- // 03:00 10:00 -7:00
- // 04:00 11:00 -7:00
- // 05:00 12:00 -7:00
- //
- // So from 02:00 - 02:59:59, we should return the standard offset, instead of the daylight saving offset.
- //
- // In the transition from daylight saving time to standard time,
- // if we convert local time to Universal time, we can have the
- // following (take PST as an example):
- // Local Universal UTC Offset
- // ----- --------- ----------
- // 01:00AM 08:00 -7:00
- // 02:00 (=> 01:00) 09:00 -8:00
- // 02:00 10:00 -8:00
- // 03:00 11:00 -8:00
- // 04:00 12:00 -8:00
- //
- // So in this case, the 02:00 does exist after the first 2:00 rolls back to 01:00. We don't need to special case this.
- // But note that there are two 01:00 in the local time.
-
- //
- // And imagine if the daylight saving offset is negative (although this does not exist in real life)
- // In the transition from standard time to daylight saving time,
- // if we convert local time to Universal time, we can have the
- // following (take PST as an example, but the daylight saving offset is -01:00):
- // Local Universal UTC Offset
- // ----- --------- ----------
- // 01:00AM 09:00 -8:00
- // 02:00 (=> 01:00) 10:00 -9:00
- // 02:00 11:00 -9:00
- // 03:00 12:00 -9:00
- // 04:00 13:00 -9:00
- // 05:00 14:00 -9:00
- //
- // So in this case, the 02:00 does exist after the first 2:00 rolls back to 01:00. We don't need to special case this.
- //
- // In the transition from daylight saving time to standard time,
- // if we convert local time to Universal time, we can have the
- // following (take PST as an example, daylight saving offset is -01:00):
- //
- // Local Universal UTC Offset
- // ----- --------- ----------
- // 01:00AM 10:00 -9:00
- // 02:00 (=> 03:00) 11:00 -9:00
- // 03:00 11:00 -8:00
- // 04:00 12:00 -8:00
- // 05:00 13:00 -8:00
- // 06:00 14:00 -8:00
- //
- // So from 02:00 - 02:59:59, we should return the daylight saving offset, instead of the standard offset.
- //
- internal static TimeSpan CalculateUtcOffset(DateTime time, DaylightTime daylightTimes)
- {
- if (daylightTimes == null)
- {
- return TimeSpan.Zero;
- }
- DateTimeKind kind = time.Kind;
- if (kind == DateTimeKind.Utc)
- {
- return TimeSpan.Zero;
- }
-
- DateTime startTime;
- DateTime endTime;
-
- // startTime and endTime represent the period from either the start of DST to the end and includes the
- // potentially overlapped times
- startTime = daylightTimes.Start + daylightTimes.Delta;
- endTime = daylightTimes.End;
-
- // For normal time zones, the ambiguous hour is the last hour of daylight saving when you wind the
- // clock back. It is theoretically possible to have a positive delta, (which would really be daylight
- // reduction time), where you would have to wind the clock back in the begnning.
- DateTime ambiguousStart;
- DateTime ambiguousEnd;
- if (daylightTimes.Delta.Ticks > 0)
- {
- ambiguousStart = endTime - daylightTimes.Delta;
- ambiguousEnd = endTime;
- }
- else
- {
- ambiguousStart = startTime;
- ambiguousEnd = startTime - daylightTimes.Delta;
- }
-
- Boolean isDst = false;
- if (startTime > endTime)
- {
- // In southern hemisphere, the daylight saving time starts later in the year, and ends in the beginning of next year.
- // Note, the summer in the southern hemisphere begins late in the year.
- if (time >= startTime || time < endTime)
- {
- isDst = true;
- }
- }
- else if (time >= startTime && time < endTime)
- {
- // In northern hemisphere, the daylight saving time starts in the middle of the year.
- isDst = true;
- }
-
- // If this date was previously converted from a UTC date and we were able to detect that the local
- // DateTime would be ambiguous, this data is stored in the DateTime to resolve this ambiguity.
- if (isDst && time >= ambiguousStart && time < ambiguousEnd)
- {
- isDst = time.IsAmbiguousDaylightSavingTime();
- }
-
- if (isDst)
- {
- return daylightTimes.Delta;
- }
- return TimeSpan.Zero;
- }
- }
-}