A
download currenttimezone.cs
Language: C#
Copyright: (c) 2006 Microsoft Corporation. All rights reserved.
LOC: 175
Project Info
Rotor IL Logger(rotorillogger)
Server: CodePlex1
Type: svn
...ger\svn\clr\src\bcl\system\
   __filters.cs
   __hresults.cs
   _localdatastore.cs
   _localdatastoremgr.cs
   ...ssviolationexception.cs
   activationarguments.cs
   activator.cs
   appdomain.cs
   appdomainattributes.cs
   appdomainmanager.cs
   appdomainsetup.cs
   ...ainunloadedexception.cs
   applicationactivator.cs
   applicationexception.cs
   applicationid.cs
   argiterator.cs
   argumentexception.cs
   argumentnullexception.cs
   ...toutofrangeexception.cs
   arithmeticexception.cs
   array.cs
   arraysegment.cs
   ...ypemismatchexception.cs
   asynccallback.cs
   attribute.cs
   attributetargets.cs
   attributeusageattribute.cs
   badimageformatexception.cs
   bcldebug.cs
   bitconverter.cs
   boolean.cs
   buffer.cs
   byte.cs
   ...adappdomainexception.cs
   cfgparser.cs
   char.cs
   charenumerator.cs
   clscompliantattribute.cs
   cominterfaces.cs
   compatibilityflags.cs
   ...usmethodframegeneric.cs
   console.cs
   consolecanceleventargs.cs
   consolespecialkey.cs
   contextboundobject.cs
   contextmarshalexception.cs
   contextstaticattribute.cs
   convert.cs
   currency.cs
   currenttimezone.cs
   datamisalignedexception.cs
   datetime.cs
   datetimekind.cs
   dayofweek.cs
   dbnull.cs
   decimal.cs
   defaultbinder.cs
   delegate.cs
   ...eserializationholder.cs
   dividebyzeroexception.cs
   dllnotfoundexception.cs
   double.cs
   ...ewaitobjectexception.cs
   empty.cs
   ...intnotfoundexception.cs
   enum.cs
   environment.cs
   eventargs.cs
   eventhandler.cs
   exception.cs
   ...utionengineexception.cs
   fieldaccessexception.cs
   flagsattribute.cs
   formatexception.cs
   gc.cs
   guid.cs
   iappdomain.cs
   iappdomainsetup.cs
   iasyncresult.cs
   icloneable.cs
   icomparable.cs
   iconvertible.cs
   icustomformatter.cs
   idisposable.cs
   iequatable.cs
   iformatprovider.cs
   iformattable.cs
   ...xoutofrangeexception.cs
   ...cientmemoryexception.cs
   int16.cs
   int32.cs
   int64.cs
   internal.cs
   intptr.cs
   invalidcastexception.cs
   ...idoperationexception.cs
   invalidprogramexception.cs
   iserviceobjectprovider.cs
   marshalbyrefobject.cs
   math.cs
   mda.cs
   memberaccessexception.cs
   methodaccessexception.cs
   midpointrounding.cs
   missingfieldexception.cs
   missingmemberexception.cs
   missingmethodexception.cs
   multicastdelegate.cs
   ...otsupportedexception.cs
   ndirectmethodframeex.cs
   nonserializedattribute.cs
   ...initenumberexception.cs
   notimplementedexception.cs
   notsupportedexception.cs
   nullable.cs
   nullreferenceexception.cs
   number.cs
   object.cs
   objectdisposedexception.cs
   obsoleteattribute.cs
   oleautbinder.cs
   operatingsystem.cs
   ...ioncanceledexception.cs
   outofmemoryexception.cs
   overflowexception.cs
   paramarrayattribute.cs
   parsenumbers.cs
   platformid.cs
   ...otsupportedexception.cs
   random.cs
   rankexception.cs
   resid.cs
   rttype.cs
   runtimeargumenthandle.cs
   runtimehandles.cs
   sbyte.cs
   serializableattribute.cs
   sharedstatics.cs
   single.cs
   stackoverflowexception.cs
   string.cs
   stringcomparer.cs
   stringcomparison.cs
   stringfreezingattribute.cs
   systemexception.cs
   threadattributes.cs
   threadstaticattribute.cs
   throwhelper.cs
   timeoutexception.cs
   timespan.cs
   timezone.cs
   type.cs
   typecode.cs
   typedreference.cs
   ...tializationexception.cs
   typeloadexception.cs
   typeunloadedexception.cs
   uint16.cs
   uint32.cs
   uint64.cs
   uintptr.cs
   ...rizedaccessexception.cs
   ...edexceptioneventargs.cs
   ...xceptioneventhandler.cs
   ...yserializationholder.cs
   unsafecharbuffer.cs
   valuetype.cs
   variant.cs
   version.cs
   void.cs
   weakreference.cs
   ...gnorememberattribute.cs

// ==++==
// 
//   
//    Copyright (c) 2006 Microsoft Corporation.  All rights reserved.
//   
//    The use and distribution terms for this software are contained in the file
//    named license.txt, which can be found in the root of this distribution.
//    By using this software in any fashion, you are agreeing to be bound by the
//    terms of this license.
//   
//    You must not remove this notice, or any other, from this software.
//   
// 
// ==--==
/*============================================================
**
** Class: CurrentTimeZone
**
**
** 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.
**
**
============================================================*/
namespace System {
    using System;
    using System.Text;
    using System.Threading;
    using System.Collections;
    using System.Globalization;
    using System.Runtime.CompilerServices;

    //
    // Currently, this is the only supported timezone.
    // The values of the timezone is from the current system timezone setting in the
    // control panel.
    //
    [Serializable()]
    internal class CurrentSystemTimeZone : TimeZone {
        //    
        private const long TicksPerMillisecond = 10000;
        private const long TicksPerSecond = TicksPerMillisecond * 1000;
        private const long TicksPerMinute = TicksPerSecond * 60;

        // The per-year information is cached in in this instance value. As a result it can
        // be cleaned up by CultureInfo.ClearCachedData, which will clear the instance of this object
        private Hashtable m_CachedDaylightChanges = new Hashtable();

        // 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() {
            m_ticksOffset = nativeGetTimeZoneMinuteOffset() * TicksPerMinute;
            m_standardName = null;
            m_daylightName = null;
        }
    
        public override String StandardName {
            get {
                if (m_standardName == null) {
                    m_standardName = nativeGetStandardName();
                }
                return (m_standardName);
            }    
        }

        public override String DaylightName {
            get {
                if (m_daylightName == null) {
                    m_daylightName = nativeGetDaylightName(); 
                    if (m_daylightName == null) {
                        m_daylightName = this.StandardName;
                    }
                }
                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);            
        }

        // 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(ref s_InternalSyncObject, o, null);
                }
                return s_InternalSyncObject;
            }
        }

        
        public override DaylightTime GetDaylightChanges(int year) {
            if (year < 1 || year > 9999) {
                throw new ArgumentOutOfRangeException("year", String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("ArgumentOutOfRange_Range"), 1, 9999));
            }
            
            Object objYear = (Object)year;

            if (!m_CachedDaylightChanges.Contains(objYear)) {
                BCLDebug.Log("Getting TimeZone information for: " + objYear);

                lock (InternalSyncObject) {

                    if (!m_CachedDaylightChanges.Contains(objYear)) {

                        //
                        // rawData is an array of 17 short (16 bit) numbers.
                        // The first 8 numbers contains the 
                        // year/month/day/dayOfWeek/hour/minute/second/millisecond for the starting time of daylight saving time.
                        // The next 8 numbers contains the
                        // year/month/day/dayOfWeek/hour/minute/second/millisecond for the ending time of daylight saving time.
                        // The last short number is the delta to the standard offset in minutes.
                        //
                        short[] rawData = nativeGetDaylightChanges();

                        if (rawData == null) {
                            //
                            // If rawData is null, it means that daylight saving time is not used
                            // in this timezone. So keep currentDaylightChanges as the empty array.
                            //
                            m_CachedDaylightChanges.Add(objYear, new DaylightTime(DateTime.MinValue, DateTime.MinValue, TimeSpan.Zero));
                        } else {
                            DateTime start;
                            DateTime end;
                            TimeSpan delta;

                            //
                            // Store the start of daylight saving time.
                            //

                            start = GetDayOfWeek( year, rawData[1], rawData[2],
                                              rawData[3], 
                                              rawData[4], rawData[5], rawData[6], rawData[7]);

                            //
                            // Store the end of daylight saving time.
                            //
                            end = GetDayOfWeek( year, rawData[9], rawData[10],
                                            rawData[11], 
                                            rawData[12], rawData[13], rawData[14], rawData[15]);            

                            delta = new TimeSpan(rawData[16] * TicksPerMinute);                
                            DaylightTime currentDaylightChanges = new DaylightTime(start, end, delta);
                            m_CachedDaylightChanges.Add(objYear, currentDaylightChanges);
                        }
                    }
                }
            }        

            DaylightTime result = (DaylightTime)m_CachedDaylightChanges[objYear];

            return result;
        }

        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);                    
            }
        }

        //
        // Return the (numberOfSunday)th day of week in a particular year/month.
        //
        private static DateTime GetDayOfWeek(int year, int month, int targetDayOfWeek, int numberOfSunday, int hour, int minute, int second, int millisecond) {
            DateTime time;
            
            if (numberOfSunday <= 4) {
                //
                // Get the (numberOfSunday)th Sunday.
                //
                
                time = new DateTime(year, month, 1, hour, minute, second, millisecond, DateTimeKind.Local);
    
                int dayOfWeek = (int)time.DayOfWeek;
                int delta = targetDayOfWeek - dayOfWeek;
                if (delta < 0) {
                    delta += 7;
                }
                delta += 7 * (numberOfSunday - 1);
    
                if (delta > 0) {
                    time = time.AddDays(delta);
                }
            } else {
                //
                // If numberOfSunday is greater than 4, we will get the last sunday.
                //
                Calendar cal = GregorianCalendar.GetDefaultInstance();            
                time = new DateTime(year, month, cal.GetDaysInMonth(year, month), hour, minute, second, millisecond, DateTimeKind.Local);
                // This is the day of week for the last day of the month.
                int dayOfWeek = (int)time.DayOfWeek;
                int delta = dayOfWeek - targetDayOfWeek;
                if (delta < 0) {
                    delta += 7;
                }
                
                if (delta > 0) {
                    time = time.AddDays(-delta);
                }
            }
            return (time);
        }

        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        internal extern static int nativeGetTimeZoneMinuteOffset();
        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        internal extern static String nativeGetDaylightName();
        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        internal extern static String nativeGetStandardName();
        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        internal extern static short[] nativeGetDaylightChanges();
    } // class CurrentSystemTimeZone
}

About Koders | Resources | Downloads | Support | Black Duck | Terms of Service | DMCA | Privacy Policy | Contact Us