CultureInfo

CultureInfo // ==++==// //   //    Copyright (c) 2002 Microsoft Corporation.  All rights reserved.//   //    The use and distribution terms for this software are contained in the file//  

大家好,又见面了,我是你们的朋友全栈君。 

  1. // ==++==
  2. // 
  3. //   
  4. //    Copyright (c) 2002 Microsoft Corporation.  All rights reserved.
  5. //   
  6. //    The use and distribution terms for this software are contained in the file
  7. //    named license.txt, which can be found in the root of this distribution.
  8. //    By using this software in any fashion, you are agreeing to be bound by the
  9. //    terms of this license.
  10. //   
  11. //    You must not remove this notice, or any other, from this software.
  12. //   
  13. // 
  14. // ==–==
  15. //
  16. //  Class:    CultureInfo
  17. //
  18. //
  19. //  Purpose:  This class represents the software preferences of a particular
  20. //            culture or community.  It includes information such as the
  21. //            language, writing system, and a calendar used by the culture
  22. //            as well as methods for common operations such as printing
  23. //            dates and sorting strings.
  24. //
  25. //  Date:     March 31, 1999
  26. //
  27. namespace System.Globalization {    
  28.     using System;
  29.     using System.Threading;
  30.     using System.Runtime.CompilerServices;
  31.     
  32.     /// <include file=’doc/CultureInfo.uex’ path=’docs/doc[@for=”CultureInfo”]/*’ />
  33.     [Serializable] public class CultureInfo : ICloneable, IFormatProvider {
  34.         //
  35.         // Special culture IDs
  36.         //
  37.         internal const int InvariantCultureID = 0x007f;
  38.         internal const int zh_CHT_CultureID = 0x7c04;
  39.         
  40.         //——————————————————————–//
  41.         //                        Internal Information                        //
  42.         //——————————————————————–//
  43.     
  44.         // This is the string used to construct CultureInfo.
  45.         // It is in the format of ISO639 (2 letter language name) plus dash plus
  46.         // ISO 3166 (2 letter region name).  The language name is in lowercase and region name
  47.         // are in uppercase.
  48.         internal String m_name = null;
  49.     
  50.         //
  51.         // This points to a record in the Culture Data Table.  That record contains several fields
  52.         // There are two kinds of fields.  One is 16-bit integer data and another one is string data.
  53.         // These fields contains information about a particular culture.
  54.         // You can think of m_dataItem as a handle that can be used to call the following metdhos:
  55.         //      CultureTable.GetInt32Value()
  56.         //      CultureTable.GetStringValue()
  57.         //      CultureTable.GetMultipleStringValues()
  58.         //
  59.         // By calling these methods, you can get information about a culture.
  60.         internal int m_dataItem;
  61.         //
  62.         // This indicates that if we need to check for user-override values for this CultureInfo instance.
  63.         // For the user default culture of the system, user can choose to override some of the values
  64.         // associated with that culture.  For example, the default short-date format for en-US is
  65.         // “M/d/yyyy”, however, one may change it to “dd/MM/yyyy” from the Regional Option in
  66.         // the control panel.
  67.         // So when a CultureInfo is created, one can specify if the create CultureInfo should check
  68.         // for user-override values, or should always get the default values.
  69.         //
  70.         internal bool m_useUserOverride;
  71.         //
  72.         // This is the culture ID used in the NLS+ world.  The concept of cultureID is similar
  73.         // to the concept of LCID in Win32.  However, NLS+ support “neutral” culture 
  74.         // which Win32 doesn’t support.
  75.         //
  76.         // The format of culture ID (32 bits) is:
  77.         // 
  78.         // 31 – 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
  79.         // +—–+ +———+ +—————+ +—————–+
  80.         //    |         |           |            Primary language ID (10 bits)
  81.         //    |         |           +———– Sublanguage ID (6 its)
  82.         //    |         +———————– Sort ID (4 bits)
  83.         //    +——————————— Reserved (12 bits)
  84.         //
  85.         // Primary language ID and sublanguage ID can be zero to specify ‘neutral’ language.
  86.         // For example, cultureID 0x(0000)0009 is the English neutral culture.
  87.         // cultureID 0x(0000)0000 means the invariant culture (or called neutral culture).
  88.         //
  89.         internal int cultureID;
  90.         //Get the current user default culture.  This one is almost always used, so we create it by default.
  91.         internal static CultureInfo m_userDefaultCulture   = null;
  92.         
  93.         //
  94.         // All of the following will be created on demand.
  95.         //
  96.         
  97.         //The Invariant culture;
  98.         internal static CultureInfo m_InvariantCultureInfo = null
  99.         
  100.         //The culture used in the user interface. This is mostly used to load correct localized resources.
  101.         internal static CultureInfo m_userDefaultUICulture = null;
  102.         //This is the UI culture used to install the OS.
  103.         internal static CultureInfo m_InstalledUICultureInfo = null;
  104.         internal bool m_isReadOnly=false;        
  105.         internal CompareInfo compareInfo = null;
  106.         internal TextInfo textInfo = null;
  107.         internal NumberFormatInfo numInfo = null;
  108.         internal DateTimeFormatInfo dateTimeInfo = null;
  109.         internal Calendar calendar = null;
  110.             
  111.         //
  112.         //  Helper Methods.
  113.         //
  114.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  115.         internal static extern bool IsInstalledLCID(int LCID);
  116.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  117.         internal static extern int nativeGetUserDefaultLCID();
  118.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  119.         internal static extern int nativeGetUserDefaultUILanguage();
  120.         
  121.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  122.         internal static extern int nativeGetSystemDefaultUILanguage();
  123.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  124.         internal static extern int nativeGetThreadLocale();
  125.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  126.         internal static extern bool nativeSetThreadLocale(int LCID);
  127.         internal const int SPANISH_TRADITIONAL_SORT = 0x040a;
  128.         internal const int SPANISH_INTERNATIONAL_SORT = 0x0c0a;
  129.         static CultureInfo() {
  130.             CultureInfo temp = new CultureInfo(nativeGetUserDefaultLCID());
  131.             temp.m_isReadOnly = true;
  132.             m_userDefaultCulture = temp;
  133.         }
  134.         
  135.         //
  136.         //  CultureInfo Constructors
  137.         //
  138.         
  139.         
  140.         /// <include file=’doc/CultureInfo.uex’ path=’docs/doc[@for=”CultureInfo.CultureInfo”]/*’ />
  141.         public CultureInfo(String name) : this(name, true) {
  142.         }
  143.         
  144.         /// <include file=’doc/CultureInfo.uex’ path=’docs/doc[@for=”CultureInfo.CultureInfo1″]/*’ />
  145.         public CultureInfo(String name, bool useUserOverride) {
  146.             if (name==null) {
  147.                 throw new ArgumentNullException(“name”,
  148.                     Environment.GetResourceString(“ArgumentNull_String”));
  149.                 
  150.             }
  151.     
  152.             this.m_dataItem = CultureTable.GetDataItemFromName(name);
  153.             if (m_dataItem < 0) {
  154.                 throw new ArgumentException(
  155.                     String.Format(Environment.GetResourceString(“Argument_InvalidCultureName”), name), “name”);
  156.             }
  157.             this.m_useUserOverride = useUserOverride;
  158.             
  159.             this.cultureID = CultureTable.GetDefaultInt32Value(m_dataItem, CultureTable.ILANGUAGE);
  160.         }
  161.     
  162.         /// <include file=’doc/CultureInfo.uex’ path=’docs/doc[@for=”CultureInfo.CultureInfo2″]/*’ />
  163.         public CultureInfo(int culture) : this(culture, true) {
  164.         }
  165.         /// <include file=’doc/CultureInfo.uex’ path=’docs/doc[@for=”CultureInfo.CultureInfo3″]/*’ />
  166.         public CultureInfo(int culture, bool useUserOverride) {
  167.             if (culture < 0) {
  168.                 throw new ArgumentOutOfRangeException(“culture”
  169.                     Environment.GetResourceString(“ArgumentOutOfRange_NeedPosNum”));
  170.             }
  171.             if (culture==SPANISH_TRADITIONAL_SORT) {
  172.                 // We are removing 0x040a (Spanish Traditional sort) in NLS+.  
  173.                 // So if you create 0x040a, it’s just like 0x0c0a (Spanish International sort).
  174.                 // For a table setup reason, we can not really remove the data item for 0x040a in culture.nlp.
  175.                 // As a workaround, what we do is to make the data for 0x040a to be exactly the same as 0x0c0a.
  176.                 // Unfortunately, the culture name is the only exception.  
  177.                 // So in the table, we still have “es-ES-Ts” in there which we can not make it “es-ES”.
  178.                 // Again, this is for table setup reason.  So if we are creating
  179.                 // CultureInfo using 0x040a, hardcode culture name to be “es-ES” here so that we won’t
  180.                 // get “es-ES-Ts” in the table.
  181.                 m_name = “es-ES”;
  182.             }
  183.             m_dataItem = CultureTable.GetDataItemFromCultureID(GetLangID(culture));            
  184.             if (m_dataItem < 0) {
  185.                 throw new ArgumentException(
  186.                     String.Format(Environment.GetResourceString(“Argument_CultureNotSupported”), culture), “culture”);
  187.             }
  188.             this.m_useUserOverride = useUserOverride;            
  189.             int sortID;
  190.             if ((sortID = GetSortID(culture))!= 0) {
  191.                 //
  192.                 // Check if the sort ID is valid.
  193.                 //
  194.                 if (!CultureTable.IsValidSortID(m_dataItem, sortID)) {
  195.                     throw new ArgumentException(
  196.                         String.Format(Environment.GetResourceString(“Argument_CultureNotSupported”), culture), “culture”);            
  197.                 }
  198.             }
  199.             this.cultureID = culture;
  200.         }
  201.         private const int NEUTRAL_SPANISH_CULTURE = 0x0A; //This is the lcid for neutral spanish.
  202.         private const int INTERNATIONAL_SPANISH_CULTURE = 0x0C0A;  //This is the LCID for international spanish.
  203.         /// <include file=’doc/CultureInfo.uex’ path=’docs/doc[@for=”CultureInfo.CreateSpecificCulture”]/*’ />
  204.         public static CultureInfo CreateSpecificCulture(String name) {
  205.             CultureInfo culture = new CultureInfo(name);
  206.             //In the most common case, they’ve given us a specific culture, so we’ll just return that.
  207.             if (!(culture.IsNeutralCulture)) {
  208.                 return culture;
  209.             }
  210.             
  211.             int lcid = culture.LCID;
  212.             //If we have the Chinese locale, we have no way of producing a 
  213.             //specific culture without encountering significant geopolitical
  214.             //issues.  Based on that, we have no choice but to bail.
  215.             if ((lcid & 0x3FF)==0x04) {
  216.                 throw new ArgumentException(Environment.GetResourceString(“Argument_NoSpecificCulture”));
  217.             }
  218.             //I’ve made this a switch statement because I believe that the number fo exceptions which we’re going
  219.             //to have is going to grow.
  220.             switch(lcid) {
  221.             case NEUTRAL_SPANISH_CULTURE:
  222.                 return new CultureInfo(INTERNATIONAL_SPANISH_CULTURE);
  223.             }
  224.             //This is the algorithm that windows uses for determing the “first”
  225.             //culture associated with a neutral language.  The low-order 18 bits
  226.             //of an LCID are consumed with the language ID, so this is essentially
  227.             //a 1 in the culture id field.
  228.             lcid |= 0x0400;
  229.                 
  230.             return new CultureInfo(lcid);
  231.         }
  232.         internal static bool VerifyCultureName(CultureInfo culture, bool throwException) {
  233.             BCLDebug.Assert(culture!=null“[CultureInfo.VerifyCultureName]culture!=null”);
  234.             //If we have an instance of one of our CultureInfos, the user can’t have changed the
  235.             //name and we know that all names are valid in files.
  236.             if (culture.GetType()==typeof(CultureInfo)) {
  237.                 return true;
  238.             }
  239.             
  240.             String name = culture.Name;
  241.             
  242.             for (int i=0; i<name.Length; i++) {
  243.                 char c = name[i];
  244.                 if (Char.IsLetterOrDigit(c) || c==‘-‘ || c==‘_’) {
  245.                     continue;
  246.                 }
  247.                 if (throwException) {
  248.                     throw new ArgumentException(Environment.GetResourceString(“Argument_InvalidResourceCultureName”, name));
  249.                 }
  250.                 return false;
  251.             }
  252.             return true;
  253.         }
  254.         //——————————————————————–//
  255.         //                        Misc static functions                       //
  256.         //——————————————————————–//
  257.     
  258.         internal static int GetPrimaryLangID(int culture)
  259.         {
  260.             return (culture & 0x03ff);            
  261.         }
  262.     
  263.         internal static int GetSubLangID(int culture)
  264.         {
  265.             return ((culture >> 10) & 0x3f);
  266.         }
  267.     
  268.         internal static int GetLangID(int culture)
  269.         {
  270.             return (culture & 0xffff);
  271.         }
  272.     
  273.         internal static int MakeLangID(int primaryLangID, int subLangID)
  274.         {
  275.             BCLDebug.Assert(primaryLangID >= 0 && primaryLangID < 1024, “CultureInfo.makeLangID(): primaryLangID >= 0 && primaryLangID < 1024”);
  276.             BCLDebug.Assert(subLangID >= 0 && subLangID < 64, “CultureInfo.makeLangID(): subLangID >= 0 && subLangID < 64”);
  277.             return ((subLangID << 10)| primaryLangID);
  278.         }
  279.     
  280.         internal static int GetSortID(int lcid)   
  281.         {
  282.             return ((lcid >> 16) & 0xf);
  283.         }
  284.             
  285.         
  286.         //
  287.         //  CurrentCulture
  288.         //
  289.         //  This instance provides methods based on the current user settings.
  290.         //  These settings are volatile and may change over the lifetime of the
  291.         //  thread.
  292.         //
  293.         
  294.     
  295.         /// <include file=’doc/CultureInfo.uex’ path=’docs/doc[@for=”CultureInfo.CurrentCulture”]/*’ />
  296.         public static CultureInfo CurrentCulture
  297.         {
  298.             get {
  299.                 return Thread.CurrentThread.CurrentCulture;
  300.             }
  301.         }
  302.         //
  303.         // This is the equivalence of the Win32 GetUserDefaultLCID()
  304.         //
  305.         internal static CultureInfo UserDefaultCulture {
  306.             get {
  307.                 return (m_userDefaultCulture);
  308.             }
  309.         }
  310.     
  311.         //
  312.         //  This is the equivalence of the Win32 GetUserDefaultUILanguage()
  313.         //
  314.     
  315.         internal static CultureInfo UserDefaultUICulture {
  316.             get {
  317.                 if (m_userDefaultUICulture == null) {
  318.                     CultureInfo temp = new CultureInfo(nativeGetUserDefaultUILanguage()); ;
  319.                     temp.m_isReadOnly = true;
  320.                     m_userDefaultUICulture = temp;
  321.                 }
  322.                 return (m_userDefaultUICulture);    
  323.             }
  324.         }
  325.     
  326.         /// <include file=’doc/CultureInfo.uex’ path=’docs/doc[@for=”CultureInfo.CurrentUICulture”]/*’ />
  327.         public static CultureInfo CurrentUICulture {
  328.             get {
  329.                 return Thread.CurrentThread.CurrentUICulture;
  330.             }
  331.         }
  332.         /// <include file=’doc/CultureInfo.uex’ path=’docs/doc[@for=”CultureInfo.InstalledUICulture”]/*’ />
  333.         //
  334.         // This is the equivalence of the Win32 GetSystemDefaultUILanguage()
  335.         //
  336.         public static CultureInfo InstalledUICulture {
  337.             get {
  338.                 if (m_InstalledUICultureInfo == null) {
  339.                     CultureInfo temp = new CultureInfo(nativeGetSystemDefaultUILanguage());
  340.                     temp.m_isReadOnly = true;
  341.                     m_InstalledUICultureInfo = temp;
  342.                 }
  343.                 return (m_InstalledUICultureInfo);
  344.             }
  345.         }
  346.     
  347.         
  348.         //
  349.         //  InvariantCulture
  350.         //
  351.         //  This instance provides methods, for example for casing and sorting,
  352.         //  that are independent of the system and current user settings.  It
  353.         //  should be used only by processes such as some system services that
  354.         //  require such invariant results (eg. file systems).  In general,
  355.         //  the results are not linguistically correct and do not match any
  356.         //  culture info.
  357.         //
  358.         
  359.     
  360.         /// <include file=’doc/CultureInfo.uex’ path=’docs/doc[@for=”CultureInfo.InvariantCulture”]/*’ />
  361.         public static CultureInfo InvariantCulture {
  362.             get {
  363.                 if (m_InvariantCultureInfo == null) {
  364.                     CultureInfo temp = new CultureInfo(InvariantCultureID, false);
  365.                     temp.m_isReadOnly = true;
  366.                     m_InvariantCultureInfo = temp;
  367.                 }
  368.                 return (m_InvariantCultureInfo);
  369.             }
  370.         }
  371.     
  372.     
  373.         
  374.         //
  375.         //  Parent
  376.         //
  377.         //  Return the parent CultureInfo for the current instance.
  378.         //
  379.         
  380.     
  381.         /// <include file=’doc/CultureInfo.uex’ path=’docs/doc[@for=”CultureInfo.Parent”]/*’ />
  382.         public virtual CultureInfo Parent {
  383.             get {
  384.                 int parentCulture = CultureTable.GetDefaultInt32Value(m_dataItem, CultureTable.IPARENT);
  385.                 if (parentCulture == InvariantCultureID) {
  386.                     return (InvariantCulture);
  387.                 }
  388.                 return (new CultureInfo(parentCulture, m_useUserOverride));
  389.             }
  390.         }
  391.     
  392.         
  393.         //
  394.         //  LCID
  395.         //
  396.         //  Returns a properly formed culture identifier for the current
  397.         //  culture info.
  398.         //
  399.         
  400.     
  401.         /// <include file=’doc/CultureInfo.uex’ path=’docs/doc[@for=”CultureInfo.LCID”]/*’ />
  402.         public virtual int LCID {
  403.             get {
  404.                 return (this.cultureID);
  405.             }
  406.         }
  407.             
  408.         /// <include file=’doc/CultureInfo.uex’ path=’docs/doc[@for=”CultureInfo.GetCultures”]/*’ />
  409.         public static CultureInfo[] GetCultures(CultureTypes types) {
  410.             return (CultureTable.GetCultures(types));
  411.         }
  412.     
  413.         
  414.         //
  415.         //  Name
  416.         //
  417.         //  Returns the full name of the CultureInfo. The name is in format like
  418.         //  “en-US”
  419.         //
  420.         
  421.     
  422.         /// <include file=’doc/CultureInfo.uex’ path=’docs/doc[@for=”CultureInfo.Name”]/*’ />
  423.         public virtual String Name {
  424.             get {
  425.                 if (m_name==null) {
  426.                     m_name = CultureTable.GetDefaultStringValue(m_dataItem, CultureTable.SNAME);
  427.                 }
  428.                 return m_name;    
  429.             }
  430.         }
  431.         
  432.         //
  433.         //  DisplayName
  434.         //
  435.         //  Returns the full name of the CultureInfo in the localized language.
  436.         //  For example, if the localized language of the runtime is Spanish and the CultureInfo is
  437.         //  US English, “Ingles (Estados Unidos)” will be returned.
  438.         //
  439.         
  440.         
  441.         /// <include file=’doc/CultureInfo.uex’ path=’docs/doc[@for=”CultureInfo.DisplayName”]/*’ />
  442.         public virtual String DisplayName {
  443.             get {
  444.                 return (Environment.GetResourceString(“Globalization.ci_”+Name));
  445.             }
  446.         }
  447.         
  448.         
  449.         //
  450.         //  GetNativeName
  451.         //
  452.         //  Returns the full name of the CultureInfo in the native language.
  453.         //  For example, if the CultureInfo is US English, “English
  454.         //  (United States)” will be returned.
  455.         //
  456.         
  457.     
  458.         /// <include file=’doc/CultureInfo.uex’ path=’docs/doc[@for=”CultureInfo.NativeName”]/*’ />
  459.         public virtual String NativeName {
  460.             get {
  461.                 return (CultureTable.GetDefaultStringValue(m_dataItem, CultureTable.SNATIVEDISPLAYNAME));
  462.             }
  463.         }
  464.         
  465.         
  466.         //
  467.         //  GetEnglishName
  468.         //
  469.         //  Returns the full name of the CultureInfo in English.
  470.         //  For example, if the CultureInfo is US English, “English
  471.         //  (United States)” will be returned.
  472.         //
  473.         
  474.     
  475.         /// <include file=’doc/CultureInfo.uex’ path=’docs/doc[@for=”CultureInfo.EnglishName”]/*’ />
  476.         public virtual String EnglishName {
  477.             get {
  478.                 return (CultureTable.GetDefaultStringValue(m_dataItem, CultureTable.SENGDISPLAYNAME));
  479.             }
  480.         }
  481.     
  482.         /// <include file=’doc/CultureInfo.uex’ path=’docs/doc[@for=”CultureInfo.TwoLetterISOLanguageName”]/*’ />
  483.         public virtual String TwoLetterISOLanguageName {
  484.             get {
  485.                 return (CultureTable.GetDefaultStringValue(m_dataItem, CultureTable.SISO639LANGNAME));        
  486.             }
  487.         }
  488.         
  489.         /// <include file=’doc/CultureInfo.uex’ path=’docs/doc[@for=”CultureInfo.ThreeLetterISOLanguageName”]/*’ />
  490.         public virtual String ThreeLetterISOLanguageName {
  491.             get {
  492.                 return (CultureTable.GetDefaultStringValue(m_dataItem, CultureTable.SISO639LANGNAME2));        
  493.             }
  494.         }
  495.     
  496.         
  497.         //
  498.         //  GetAbbreviatedName
  499.         //
  500.         //  Returns the abbreviated name for the current instance.  The
  501.         //  abbreviated form is usually based on the ISO 639 standard, for
  502.         //  example the two letter abbreviation for English is “en”.
  503.         //
  504.         
  505.     
  506.        /// <include file=’doc/CultureInfo.uex’ path=’docs/doc[@for=”CultureInfo.ThreeLetterWindowsLanguageName”]/*’ />
  507.        public virtual String ThreeLetterWindowsLanguageName {
  508.             get {
  509.                 return (CultureTable.GetDefaultStringValue(m_dataItem, CultureTable.SABBREVLANGNAME));
  510.             }
  511.         }
  512.         
  513.         //
  514.         //  CompareInfo               Read-Only Property
  515.         //
  516.         //  Gets the CompareInfo for this culture.
  517.         //
  518.         
  519.     
  520.         /// <include file=’doc/CultureInfo.uex’ path=’docs/doc[@for=”CultureInfo.CompareInfo”]/*’ />
  521.         public virtual CompareInfo CompareInfo {
  522.             get {
  523.                 if (compareInfo==null) {
  524.                     compareInfo = CompareInfo.GetCompareInfo(cultureID);
  525.                 }                            
  526.                 return (compareInfo);
  527.             }
  528.         }
  529.     
  530.         
  531.         //
  532.         //  TextInfo
  533.         //
  534.         //  Gets the TextInfo for this culture.
  535.         //
  536.         
  537.     
  538.         /// <include file=’doc/CultureInfo.uex’ path=’docs/doc[@for=”CultureInfo.TextInfo”]/*’ />
  539.         public virtual TextInfo TextInfo {
  540.             get {            
  541.                 if (textInfo==null) {
  542.                     textInfo = new TextInfo(cultureID, m_dataItem, m_useUserOverride);
  543.                 }
  544.                 return (textInfo);
  545.             }
  546.         } 
  547.     
  548.         
  549.         //
  550.         //  Equals
  551.         //
  552.         //  Implements Object.Equals().  Returns a boolean indicating whether
  553.         //  or not object refers to the same CultureInfo as the current instance.
  554.         //
  555.         
  556.     
  557.         /// <include file=’doc/CultureInfo.uex’ path=’docs/doc[@for=”CultureInfo.Equals”]/*’ />
  558.         public override bool Equals(Object value) {
  559.             //
  560.             //  See if the object name is the same as the culture info object.
  561.             //
  562.             if ((value != null) && (value is CultureInfo)) {
  563.                 CultureInfo culture = (CultureInfo)value;
  564.     
  565.                 //
  566.                 //  See if the member variables are equal.  If so, then
  567.                 //  return true.
  568.                 //
  569.                 if (this.cultureID == culture.cultureID) {
  570.                     return (true);
  571.                 }
  572.             }
  573.     
  574.             //
  575.             //  Objects are not the same, so return false.
  576.             //
  577.             return (false);
  578.         }
  579.     
  580.     
  581.         
  582.         //
  583.         //  GetHashCode
  584.         //
  585.         //  Implements Object.GetHashCode().  Returns the hash code for the
  586.         //  CultureInfo.  The hash code is guaranteed to be the same for CultureInfo A
  587.         //  and B where A.Equals(B) is true.
  588.         //
  589.         
  590.     
  591.         /// <include file=’doc/CultureInfo.uex’ path=’docs/doc[@for=”CultureInfo.GetHashCode”]/*’ />
  592.         public override int GetHashCode() {
  593.             return (this.LCID);
  594.         }
  595.     
  596.     
  597.         
  598.         //
  599.         //  ToString
  600.         //
  601.         //  Implements Object.ToString().  Returns the name of the CultureInfo,
  602.         //  eg. “English (United States)”.
  603.         //
  604.         
  605.     
  606.         /// <include file=’doc/CultureInfo.uex’ path=’docs/doc[@for=”CultureInfo.ToString”]/*’ />
  607.         public override String ToString() {
  608.             return (Name);
  609.         }
  610.     
  611.         /// <include file=’doc/CultureInfo.uex’ path=’docs/doc[@for=”CultureInfo.GetFormat”]/*’ />
  612.         public virtual Object GetFormat(Type formatType) {
  613.             if (formatType == typeof(NumberFormatInfo)) {
  614.                 return (NumberFormat);
  615.             }
  616.             if (formatType == typeof(DateTimeFormatInfo)) {
  617.                 return (DateTimeFormat);
  618.             }
  619.             return (null);
  620.         }        
  621.         
  622.         private static readonly char[] groupSeparator = new char[] {
    ‘;’};
  623.         /*=================================ParseGroupString==========================
  624.         **Action: The number grouping information is stored as string.  The group numbers
  625.         **        are separated by comma.  The function split the numbers and return
  626.         **        the result as an int array.
  627.         **Returns: An array of int for the number grouping information.
  628.         **Arguments: a number grouping string.
  629.         **Exceptions: None.
  630.         ============================================================================*/
  631.         
  632.         internal static int[] ParseGroupString(String groupStr) {
  633.             BCLDebug.Assert(groupStr != null“groupStr should not be null. There is data error in culture.nlp.”);
  634.             String[] groupDigits = groupStr.Split(groupSeparator);
  635.             BCLDebug.Assert(groupDigits.Length > 0, “There is data error in culture.nlp.”);
  636.             int[] result = new int[groupDigits.Length];
  637.             try {
  638.                 for (int i=0; i < groupDigits.Length; i++) {
  639.                     result[i] = Int32.Parse(groupDigits[i], NumberStyles.None, NumberFormatInfo.InvariantInfo);
  640.                 }
  641.             } catch (Exception) {
  642.                 BCLDebug.Assert(true“There is data error in culture.nlp.”);
  643.             }
  644.             return (result);
  645.         }
  646.     
  647.         internal static void CheckNeutral(CultureInfo culture) {
  648.             if (culture.IsNeutralCulture) {
  649.                     throw new NotSupportedException(
  650.                                                     Environment.GetResourceString(“Argument_CultureInvalidFormat”
  651.                                                     culture.Name));
  652.             }
  653.         }
  654.         /// <include file=’doc/CultureInfo.uex’ path=’docs/doc[@for=”CultureInfo.IsNeutralCulture”]/*’ />
  655.         public virtual bool IsNeutralCulture {
  656.             get {
  657.                 return (cultureID!=InvariantCultureID && CultureTable.IsNeutralCulture(cultureID));
  658.             }
  659.         }
  660.         
  661.         /// <include file=’doc/CultureInfo.uex’ path=’docs/doc[@for=”CultureInfo.NumberFormat”]/*’ />
  662.         public virtual NumberFormatInfo NumberFormat {
  663.             get {
  664.                 CultureInfo.CheckNeutral(this);
  665.                 if (numInfo == null) {
  666.                     NumberFormatInfo temp = new NumberFormatInfo(m_dataItem, m_useUserOverride);
  667.                     temp.isReadOnly = m_isReadOnly;
  668.                     numInfo = temp;
  669.                 }
  670.                 return (numInfo);
  671.             }
  672.             set {
  673.                 VerifyWritable();
  674.                 if (value == null) {
  675.                     throw new ArgumentNullException(“value”,
  676.                         Environment.GetResourceString(“ArgumentNull_Obj”));                    
  677.                 }
  678.                 numInfo = value;
  679.             }
  680.         }
  681.         
  682.         //
  683.         // GetDateTimeFormatInfo
  684.         // 
  685.         // Create a DateTimeFormatInfo, and fill in the properties according to
  686.         // the CultureID.
  687.         //
  688.         
  689.         
  690.         /// <include file=’doc/CultureInfo.uex’ path=’docs/doc[@for=”CultureInfo.DateTimeFormat”]/*’ />
  691.         public virtual DateTimeFormatInfo DateTimeFormat {
  692.             get {
  693.                 CultureInfo.CheckNeutral(this);
  694.                 if (dateTimeInfo == null) { 
  695.                     lock(this) {
  696.                         if (dateTimeInfo == null) {
  697.                             // Change the calendar of DTFI to the specified calendar of this CultureInfo.
  698.                             DateTimeFormatInfo temp = new DateTimeFormatInfo(GetLangID(cultureID), m_dataItem, m_useUserOverride, this.Calendar);
  699.                             temp.m_isReadOnly = m_isReadOnly;
  700.                             dateTimeInfo = temp;
  701.                         }
  702.                     }
  703.                 }
  704.                 return (dateTimeInfo);
  705.             }
  706.             set {
  707.                 VerifyWritable();
  708.                 if (value == null) {
  709.                     throw new ArgumentNullException(“value”,
  710.                         Environment.GetResourceString(“ArgumentNull_Obj”));                    
  711.                 }                
  712.                 dateTimeInfo = value;
  713.             }                            
  714.         }
  715.         /// <include file=’doc/CultureInfo.uex’ path=’docs/doc[@for=”CultureInfo.ClearCachedData”]/*’ />
  716.         public void ClearCachedData() {
  717.             lock(typeof(CultureInfo)) {
  718.                 m_userDefaultUICulture = null;
  719.                 CultureInfo temp = new CultureInfo(nativeGetUserDefaultLCID());
  720.                 temp.m_isReadOnly = true;
  721.                 m_userDefaultCulture = temp;
  722.                 RegionInfo.m_currentRegionInfo = null;                
  723.                 
  724.                 TimeZone.ResetTimeZone();
  725.             }
  726.         }
  727.         /*=================================GetCalendarInstance==========================
  728.         **Action: Map a Win32 CALID to an instance of supported calendar.
  729.         **Returns: An instance of calendar.
  730.         **Arguments: calType    The Win32 CALID
  731.         **Exceptions:
  732.         **      Shouldn’t throw exception since the calType value is from our data table or from Win32 registry.
  733.         **      If we are in trouble (like getting a weird value from Win32 registry), just return the GregorianCalendar.
  734.         ============================================================================*/
  735.         internal Calendar GetCalendarInstance(int calType) {
  736.             if (calType==Calendar.CAL_GREGORIAN) {
  737.                 return (GregorianCalendar.GetDefaultInstance());
  738.             }
  739.             return GetCalendarInstanceRare(calType);
  740.         }
  741.         
  742.         //This function exists as a hack to prevent us from loading all of the non-gregorian
  743.         //calendars unless they’re required.  
  744.         internal Calendar GetCalendarInstanceRare(int calType) {
  745.             BCLDebug.Assert(calType!=Calendar.CAL_GREGORIAN, “calType!=Calendar.CAL_GREGORIAN”);
  746.             switch (calType) {
  747.                 case Calendar.CAL_GREGORIAN_US:               // Gregorian (U.S.) calendar
  748.                 case Calendar.CAL_GREGORIAN_ME_FRENCH:        // Gregorian Middle East French calendar
  749.                 case Calendar.CAL_GREGORIAN_ARABIC:           // Gregorian Arabic calendar
  750.                 case Calendar.CAL_GREGORIAN_XLIT_ENGLISH:     // Gregorian Transliterated English calendar
  751.                 case Calendar.CAL_GREGORIAN_XLIT_FRENCH:      // Gregorian Transliterated French calendar
  752.                     return (new GregorianCalendar((GregorianCalendarTypes)calType));
  753.                 case Calendar.CAL_TAIWAN:                     // Taiwan Era calendar
  754.                     return (TaiwanCalendar.GetDefaultInstance());
  755.                 case Calendar.CAL_JAPAN:                      // Japanese Emperor Era calendar
  756.                     return (JapaneseCalendar.GetDefaultInstance());
  757.                 case Calendar.CAL_KOREA:                      // Korean Tangun Era calendar
  758.                     return (KoreanCalendar.GetDefaultInstance());
  759.                 case Calendar.CAL_HIJRI:                      // Hijri (Arabic Lunar) calendar
  760.                     return (HijriCalendar.GetDefaultInstance());
  761.                 case Calendar.CAL_THAI:                       // Thai calendar
  762.                     return (ThaiBuddhistCalendar.GetDefaultInstance());
  763.                 case Calendar.CAL_HEBREW:                     // Hebrew (Lunar) calendar            
  764.                     return (HebrewCalendar.GetDefaultInstance());
  765.             }
  766.             return (GregorianCalendar.GetDefaultInstance());
  767.         }
  768.         
  769.         /*=================================Calendar==========================
  770.         **Action: Return/set the calendar used by this culture.
  771.         **Returns:
  772.         **Arguments:
  773.         **Exceptions:
  774.         **  ArgumentNull_Obj if the set value is null.
  775.         ============================================================================*/
  776.         
  777.         /// <include file=’doc/CultureInfo.uex’ path=’docs/doc[@for=”CultureInfo.Calendar”]/*’ />
  778.         public virtual Calendar Calendar {
  779.             get {
  780.                 if (calendar == null) {
  781.                     lock(this) {
  782.                         if (calendar == null) {
  783.                             // Get the default calendar for this culture.  Note that the value can be
  784.                             // from registry if this is a user default culture.
  785.                             int calType = CultureTable.GetInt32Value(m_dataItem, CultureTable.ICALENDARTYPE, m_useUserOverride);
  786.                             calendar = GetCalendarInstance(calType);
  787.                         }
  788.                     }
  789.                 }
  790.                 return (calendar);
  791.             }
  792.         }
  793.         /*=================================OptionCalendars==========================
  794.         **Action: Return an array of the optional calendar for this culture.
  795.         **Returns: an array of Calendar.
  796.         **Arguments:
  797.         **Exceptions:
  798.         ============================================================================*/
  799.         /// <include file=’doc/CultureInfo.uex’ path=’docs/doc[@for=”CultureInfo.OptionalCalendars”]/*’ />
  800.         public virtual Calendar[] OptionalCalendars {
  801.             get {
  802.                 //
  803.                 // This property always returns a new copy of the calendar array.
  804.                 //
  805.                 int[] calID = ParseGroupString(CultureTable.GetDefaultStringValue(m_dataItem, CultureTable.NLPIOPTIONCALENDAR));
  806.                 Calendar [] cals = new Calendar[calID.Length];
  807.                 for (int i = 0; i < cals.Length; i++) {
  808.                     cals[i] = GetCalendarInstance(calID[i]);
  809.                 }
  810.                 return (cals);
  811.             }
  812.         }        
  813.         /// <include file=’doc/CultureInfo.uex’ path=’docs/doc[@for=”CultureInfo.UseUserOverride”]/*’ />
  814.         public bool UseUserOverride { 
  815.             get {
  816.                 return (m_useUserOverride);
  817.             }
  818.         }        
  819.     
  820.         /// <include file=’doc/CultureInfo.uex’ path=’docs/doc[@for=”CultureInfo.Clone”]/*’ />
  821.         public virtual Object Clone()
  822.         {
  823.             CultureInfo ci = (CultureInfo)MemberwiseClone();
  824.             //If this is exactly our type, we can make certain optimizations so that we don’t allocate NumberFormatInfo or DTFI unless
  825.             //they’ve already been allocated.  If this is a derived type, we’ll take a more generic codepath.
  826.             if (ci.GetType()==typeof(CultureInfo)) {
  827.                 if (dateTimeInfo != null) {
  828.                     ci.dateTimeInfo = (DateTimeFormatInfo)dateTimeInfo.Clone();
  829.                 }
  830.                 if (numInfo != null) {
  831.                     ci.numInfo = (NumberFormatInfo)numInfo.Clone();
  832.                 }
  833.                 ci.m_isReadOnly = false;
  834.             } else {
  835.                 ci.m_isReadOnly = false;
  836.                 ci.DateTimeFormat = (DateTimeFormatInfo)this.DateTimeFormat.Clone();
  837.                 ci.NumberFormat   = (NumberFormatInfo)this.NumberFormat.Clone();
  838.             }
  839.             return (ci);
  840.         }        
  841.         /// <include file=’doc/CultureInfo.uex’ path=’docs/doc[@for=”CultureInfo.ReadOnly”]/*’ />        
  842.         public static CultureInfo ReadOnly(CultureInfo ci) {
  843.             if (ci == null) {
  844.                 throw new ArgumentNullException(“ci”);
  845.             }
  846.             if (ci.IsReadOnly) {
  847.                 return (ci);
  848.             }
  849.             CultureInfo info = (CultureInfo)(ci.MemberwiseClone());
  850.             //If this is exactly our type, we can make certain optimizations so that we don’t allocate NumberFormatInfo or DTFI unless
  851.             //they’ve already been allocated.  If this is a derived type, we’ll take a more generic codepath.
  852.             if (ci.GetType()==typeof(CultureInfo)) {
  853.                 if (ci.dateTimeInfo != null) {
  854.                     info.dateTimeInfo = DateTimeFormatInfo.ReadOnly(ci.dateTimeInfo);
  855.                 }
  856.                 if (ci.numInfo != null) {
  857.                     info.numInfo = NumberFormatInfo.ReadOnly(ci.numInfo);
  858.                 }
  859.             } else {
  860.                 info.DateTimeFormat = DateTimeFormatInfo.ReadOnly(ci.DateTimeFormat);
  861.                 info.NumberFormat = NumberFormatInfo.ReadOnly(ci.NumberFormat);
  862.             }
  863.             // Don’t set the read-only flag too early.
  864.             // We should set the read-only flag here.  Otherwise, info.DateTimeFormat will not be able to set.
  865.             info.m_isReadOnly = true;
  866.             
  867.             return (info);
  868.         }
  869.         /// <include file=’doc/CultureInfo.uex’ path=’docs/doc[@for=”CultureInfo.IsReadOnly”]/*’ />
  870.         public bool IsReadOnly {
  871.             get {
  872.                 return (m_isReadOnly);
  873.             }
  874.         }
  875.         private void VerifyWritable() {
  876.             if (m_isReadOnly) {
  877.                 throw new InvalidOperationException(Environment.GetResourceString(“InvalidOperation_ReadOnly”));
  878.             }
  879.         }        
  880.     }    
  881. }
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/150946.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号