RegionInfo.cs 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the MIT license.
  3. // See the LICENSE file in the project root for more information.
  4. using System.Diagnostics;
  5. namespace System.Globalization
  6. {
  7. /// <summary>
  8. /// This class represents settings specified by de jure or de facto
  9. /// standards for a particular country/region. In contrast to
  10. /// CultureInfo, the RegionInfo does not represent preferences of the
  11. /// user and does not depend on the user's language or culture.
  12. /// </summary>
  13. public class RegionInfo
  14. {
  15. // Name of this region (ie: es-US): serialized, the field used for deserialization
  16. private string _name;
  17. // The CultureData instance that we are going to read data from.
  18. private readonly CultureData _cultureData;
  19. // The RegionInfo for our current region
  20. internal static volatile RegionInfo? s_currentRegionInfo;
  21. public RegionInfo(string name)
  22. {
  23. if (name == null)
  24. {
  25. throw new ArgumentNullException(nameof(name));
  26. }
  27. // The InvariantCulture has no matching region
  28. if (name.Length == 0)
  29. {
  30. throw new ArgumentException(SR.Argument_NoRegionInvariantCulture, nameof(name));
  31. }
  32. // For CoreCLR we only want the region names that are full culture names
  33. _cultureData = CultureData.GetCultureDataForRegion(name, true) ??
  34. throw new ArgumentException(SR.Format(SR.Argument_InvalidCultureName, name), nameof(name));
  35. // Not supposed to be neutral
  36. if (_cultureData.IsNeutralCulture)
  37. {
  38. throw new ArgumentException(SR.Format(SR.Argument_InvalidNeutralRegionName, name), nameof(name));
  39. }
  40. _name = _cultureData.RegionName;
  41. }
  42. public RegionInfo(int culture)
  43. {
  44. // The InvariantCulture has no matching region
  45. if (culture == CultureInfo.LOCALE_INVARIANT)
  46. {
  47. throw new ArgumentException(SR.Argument_NoRegionInvariantCulture);
  48. }
  49. if (culture == CultureInfo.LOCALE_NEUTRAL)
  50. {
  51. // Not supposed to be neutral
  52. throw new ArgumentException(SR.Format(SR.Argument_CultureIsNeutral, culture), nameof(culture));
  53. }
  54. if (culture == CultureInfo.LOCALE_CUSTOM_DEFAULT)
  55. {
  56. // Not supposed to be neutral
  57. throw new ArgumentException(SR.Format(SR.Argument_CustomCultureCannotBePassedByNumber, culture), nameof(culture));
  58. }
  59. _cultureData = CultureData.GetCultureData(culture, true);
  60. _name = _cultureData.RegionName;
  61. if (_cultureData.IsNeutralCulture)
  62. {
  63. // Not supposed to be neutral
  64. throw new ArgumentException(SR.Format(SR.Argument_CultureIsNeutral, culture), nameof(culture));
  65. }
  66. }
  67. internal RegionInfo(CultureData cultureData)
  68. {
  69. _cultureData = cultureData;
  70. _name = _cultureData.RegionName;
  71. }
  72. /// <summary>
  73. /// This instance provides methods based on the current user settings.
  74. /// These settings are volatile and may change over the lifetime of the
  75. /// </summary>
  76. public static RegionInfo CurrentRegion
  77. {
  78. get
  79. {
  80. RegionInfo? temp = s_currentRegionInfo;
  81. if (temp == null)
  82. {
  83. temp = new RegionInfo(CultureInfo.CurrentCulture._cultureData);
  84. // Need full name for custom cultures
  85. temp._name = temp._cultureData.RegionName;
  86. s_currentRegionInfo = temp;
  87. }
  88. return temp;
  89. }
  90. }
  91. /// <summary>
  92. /// Returns the name of the region (ie: en-US)
  93. /// </summary>
  94. public virtual string Name
  95. {
  96. get
  97. {
  98. Debug.Assert(_name != null, "Expected RegionInfo._name to be populated already");
  99. return _name;
  100. }
  101. }
  102. /// <summary>
  103. /// Returns the name of the region in English. (ie: United States)
  104. /// </summary>
  105. public virtual string EnglishName => _cultureData.EnglishCountryName;
  106. /// <summary>
  107. /// Returns the display name (localized) of the region. (ie: United States
  108. /// if the current UI language is en-US)
  109. /// </summary>
  110. public virtual string DisplayName => _cultureData.LocalizedCountryName;
  111. /// <summary>
  112. /// Returns the native name of the region. (ie: Deutschland)
  113. /// WARNING: You need a full locale name for this to make sense.
  114. /// </summary>
  115. public virtual string NativeName => _cultureData.NativeCountryName;
  116. /// <summary>
  117. /// Returns the two letter ISO region name (ie: US)
  118. /// </summary>
  119. public virtual string TwoLetterISORegionName => _cultureData.TwoLetterISOCountryName;
  120. /// <summary>
  121. /// Returns the three letter ISO region name (ie: USA)
  122. /// </summary>
  123. public virtual string ThreeLetterISORegionName => _cultureData.ThreeLetterISOCountryName;
  124. /// <summary>
  125. /// Returns the three letter windows region name (ie: USA)
  126. /// </summary>
  127. public virtual string ThreeLetterWindowsRegionName => ThreeLetterISORegionName;
  128. /// <summary>
  129. /// Returns true if this region uses the metric measurement system
  130. /// </summary>
  131. public virtual bool IsMetric => _cultureData.MeasurementSystem == 0;
  132. public virtual int GeoId => _cultureData.GeoId;
  133. /// <summary>
  134. /// English name for this region's currency, ie: Swiss Franc
  135. /// </summary>
  136. public virtual string CurrencyEnglishName => _cultureData.CurrencyEnglishName;
  137. /// <summary>
  138. /// Native name for this region's currency, ie: Schweizer Franken
  139. /// WARNING: You need a full locale name for this to make sense.
  140. /// </summary>
  141. public virtual string CurrencyNativeName => _cultureData.CurrencyNativeName;
  142. /// <summary>
  143. /// Currency Symbol for this locale, ie: Fr. or $
  144. /// </summary>
  145. public virtual string CurrencySymbol => _cultureData.CurrencySymbol;
  146. /// <summary>
  147. /// ISO Currency Symbol for this locale, ie: CHF
  148. /// </summary>
  149. public virtual string ISOCurrencySymbol => _cultureData.ISOCurrencySymbol;
  150. /// <summary>
  151. /// Implements Object.Equals(). Returns a boolean indicating whether
  152. /// or not object refers to the same RegionInfo as the current instance.
  153. /// RegionInfos are considered equal if and only if they have the same name
  154. /// (ie: en-US)
  155. /// </summary>
  156. public override bool Equals(object? value)
  157. {
  158. return value is RegionInfo otherRegion
  159. && Name.Equals(otherRegion.Name);
  160. }
  161. public override int GetHashCode() => Name.GetHashCode();
  162. public override string ToString() => Name;
  163. }
  164. }