2 // System.Globalization.NumberFormatInfo.cs
5 // Derek Holden (dholden@draper.com)
11 // NumberFormatInfo. One can only assume it is the class gottten
12 // back from a GetFormat() method from an IFormatProvider /
13 // IFormattable implementer. There are some discrepencies with the
14 // ECMA spec and the SDK docs, surprisingly. See my conversation
15 // with myself on it at:
16 // http://lists.ximian.com/archives/public/mono-list/2001-July/000794.html
18 // Other than that this is totally ECMA compliant.
21 namespace System.Globalization {
23 public sealed class NumberFormatInfo : ICloneable, IFormatProvider {
24 private bool readOnly;
26 // Currency Related Format Info
27 private int currencyDecimalDigits;
28 private string currencyDecimalSeparator;
29 private string currencyGroupSeparator;
30 private int[] currencyGroupSizes;
31 private int currencyNegativePattern;
32 private int currencyPositivePattern;
33 private string currencySymbol;
35 private string naNSymbol;
36 private string negativeInfinitySymbol;
37 private string negativeSign;
39 // Number Related Format Info
40 private int numberDecimalDigits;
41 private string numberDecimalSeparator;
42 private string numberGroupSeparator;
43 private int[] numberGroupSizes;
44 private int numberNegativePattern;
46 // Percent Related Format Info
47 private int percentDecimalDigits;
48 private string percentDecimalSeparator;
49 private string percentGroupSeparator;
50 private int[] percentGroupSizes;
51 private int percentNegativePattern;
52 private int percentPositivePattern;
53 private string percentSymbol;
55 private string perMilleSymbol;
56 private string positiveInfinitySymbol;
57 private string positiveSign;
59 internal NumberFormatInfo (int lcid)
63 // The Invariant Culture Info ID.
67 // Currency Related Format Info
68 currencyDecimalDigits = 2;
69 currencyDecimalSeparator = ".";
70 currencyGroupSeparator = ",";
71 currencyGroupSizes = new int[1] { 3 };
72 currencyNegativePattern = 0;
73 currencyPositivePattern = 0;
77 negativeInfinitySymbol = "-Infinity";
80 // Number Related Format Info
81 numberDecimalDigits = 2;
82 numberDecimalSeparator = ".";
83 numberGroupSeparator = ",";
84 numberGroupSizes = new int[1] { 3 };
85 numberNegativePattern = 0;
87 // Percent Related Format Info
88 percentDecimalDigits = 2;
89 percentDecimalSeparator = ".";
90 percentGroupSeparator = ",";
91 percentGroupSizes = new int[1] { 3 };
92 percentNegativePattern = 0;
93 percentPositivePattern = 0;
96 perMilleSymbol = "\u2030";
97 positiveInfinitySymbol = "Infinity";
103 public NumberFormatInfo () : this (0x007f)
107 // =========== Currency Format Properties =========== //
109 public int CurrencyDecimalDigits {
111 return currencyDecimalDigits;
115 if (value < 0 || value > 99)
116 throw new ArgumentOutOfRangeException
117 ("The value specified for the property is less than 0 or greater than 99");
120 throw new InvalidOperationException
121 ("The current instance is read-only and a set operation was attempted");
123 currencyDecimalDigits = value;
127 public string CurrencyDecimalSeparator {
129 return currencyDecimalSeparator;
134 throw new ArgumentNullException
135 ("The value specified for the property is a null reference");
138 throw new InvalidOperationException
139 ("The current instance is read-only and a set operation was attempted");
141 currencyDecimalSeparator = value;
146 public string CurrencyGroupSeparator {
148 return currencyGroupSeparator;
153 throw new ArgumentNullException
154 ("The value specified for the property is a null reference");
157 throw new InvalidOperationException
158 ("The current instance is read-only and a set operation was attempted");
160 currencyGroupSeparator = value;
164 public int[] CurrencyGroupSizes {
166 return currencyGroupSizes;
170 if (value == null || value.Length == 0)
171 throw new ArgumentNullException
172 ("The value specified for the property is a null reference");
175 throw new InvalidOperationException
176 ("The current instance is read-only and a set operation was attempted");
178 // All elements except last need to be in range 1 - 9, last can be 0.
179 int last = value.Length - 1;
181 for (int i = 0; i < last; i++)
182 if (value[i] < 1 || value[i] > 9)
183 throw new ArgumentOutOfRangeException
184 ("One of the elements in the array specified is not between 1 and 9");
186 if (value[last] < 0 || value[last] > 9)
187 throw new ArgumentOutOfRangeException
188 ("Last element in the array specified is not between 0 and 9");
190 currencyGroupSizes = (int[]) value.Clone();
194 public int CurrencyNegativePattern {
196 // See ECMA NumberFormatInfo page 8
197 return currencyNegativePattern;
201 if (value < 0 || value > 15)
202 throw new ArgumentOutOfRangeException
203 ("The value specified for the property is less than 0 or greater than 15");
206 throw new InvalidOperationException
207 ("The current instance is read-only and a set operation was attempted");
209 currencyNegativePattern = value;
213 public int CurrencyPositivePattern {
215 // See ECMA NumberFormatInfo page 11
216 return currencyPositivePattern;
220 if (value < 0 || value > 3)
221 throw new ArgumentOutOfRangeException
222 ("The value specified for the property is less than 0 or greater than 3");
225 throw new InvalidOperationException
226 ("The current instance is read-only and a set operation was attempted");
228 currencyPositivePattern = value;
232 public string CurrencySymbol {
234 return currencySymbol;
239 throw new ArgumentNullException
240 ("The value specified for the property is a null reference");
243 throw new InvalidOperationException
244 ("The current instance is read-only and a set operation was attempted");
246 currencySymbol = value;
250 // =========== Static Read-Only Properties =========== //
252 public static NumberFormatInfo CurrentInfo {
254 // This should be culture specific
255 NumberFormatInfo nfi = new NumberFormatInfo ();
261 public static NumberFormatInfo InvariantInfo {
263 // This uses invariant info, which is same as in the constructor
264 NumberFormatInfo nfi = new NumberFormatInfo ();
270 public bool IsReadOnly {
278 public string NaNSymbol {
285 throw new ArgumentNullException
286 ("The value specified for the property is a null reference");
289 throw new InvalidOperationException
290 ("The current instance is read-only and a set operation was attempted");
296 public string NegativeInfinitySymbol {
298 return negativeInfinitySymbol;
303 throw new ArgumentNullException
304 ("The value specified for the property is a null reference");
307 throw new InvalidOperationException
308 ("The current instance is read-only and a set operation was attempted");
310 negativeInfinitySymbol = value;
314 public string NegativeSign {
321 throw new ArgumentNullException
322 ("The value specified for the property is a null reference");
325 throw new InvalidOperationException
326 ("The current instance is read-only and a set operation was attempted");
328 negativeSign = value;
332 // =========== Number Format Properties =========== //
334 public int NumberDecimalDigits {
336 return numberDecimalDigits;
340 if (value < 0 || value > 99)
341 throw new ArgumentOutOfRangeException
342 ("The value specified for the property is less than 0 or greater than 99");
345 throw new InvalidOperationException
346 ("The current instance is read-only and a set operation was attempted");
348 numberDecimalDigits = value;
352 public string NumberDecimalSeparator {
354 return numberDecimalSeparator;
359 throw new ArgumentNullException
360 ("The value specified for the property is a null reference");
363 throw new InvalidOperationException
364 ("The current instance is read-only and a set operation was attempted");
366 numberDecimalSeparator = value;
371 public string NumberGroupSeparator {
373 return numberGroupSeparator;
378 throw new ArgumentNullException
379 ("The value specified for the property is a null reference");
382 throw new InvalidOperationException
383 ("The current instance is read-only and a set operation was attempted");
385 numberGroupSeparator = value;
389 public int[] NumberGroupSizes {
391 return numberGroupSizes;
395 if (value == null || value.Length == 0)
396 throw new ArgumentNullException
397 ("The value specified for the property is a null reference");
400 throw new InvalidOperationException
401 ("The current instance is read-only and a set operation was attempted");
403 // All elements except last need to be in range 1 - 9, last can be 0.
404 int last = value.Length - 1;
406 for (int i = 0; i < last; i++)
407 if (value[i] < 1 || value[i] > 9)
408 throw new ArgumentOutOfRangeException
409 ("One of the elements in the array specified is not between 1 and 9");
411 if (value[last] < 0 || value[last] > 9)
412 throw new ArgumentOutOfRangeException
413 ("Last element in the array specified is not between 0 and 9");
415 numberGroupSizes = (int[]) value.Clone();
419 public int NumberNegativePattern {
421 // See ECMA NumberFormatInfo page 27
422 return numberNegativePattern;
426 if (value < 0 || value > 4)
427 throw new ArgumentOutOfRangeException
428 ("The value specified for the property is less than 0 or greater than 15");
431 throw new InvalidOperationException
432 ("The current instance is read-only and a set operation was attempted");
434 numberNegativePattern = value;
438 // =========== Percent Format Properties =========== //
440 public int PercentDecimalDigits {
442 return percentDecimalDigits;
446 if (value < 0 || value > 99)
447 throw new ArgumentOutOfRangeException
448 ("The value specified for the property is less than 0 or greater than 99");
451 throw new InvalidOperationException
452 ("The current instance is read-only and a set operation was attempted");
454 percentDecimalDigits = value;
458 public string PercentDecimalSeparator {
460 return percentDecimalSeparator;
465 throw new ArgumentNullException
466 ("The value specified for the property is a null reference");
469 throw new InvalidOperationException
470 ("The current instance is read-only and a set operation was attempted");
472 percentDecimalSeparator = value;
477 public string PercentGroupSeparator {
479 return percentGroupSeparator;
484 throw new ArgumentNullException
485 ("The value specified for the property is a null reference");
488 throw new InvalidOperationException
489 ("The current instance is read-only and a set operation was attempted");
491 percentGroupSeparator = value;
495 public int[] PercentGroupSizes {
497 return percentGroupSizes;
501 if (value == null || value.Length == 0)
502 throw new ArgumentNullException
503 ("The value specified for the property is a null reference");
506 throw new InvalidOperationException
507 ("The current instance is read-only and a set operation was attempted");
509 // All elements except last need to be in range 1 - 9, last can be 0.
510 int last = value.Length - 1;
512 for (int i = 0; i < last; i++)
513 if (value[i] < 1 || value[i] > 9)
514 throw new ArgumentOutOfRangeException
515 ("One of the elements in the array specified is not between 1 and 9");
517 if (value[last] < 0 || value[last] > 9)
518 throw new ArgumentOutOfRangeException
519 ("Last element in the array specified is not between 0 and 9");
521 percentGroupSizes = (int[]) value.Clone();
525 public int PercentNegativePattern {
527 // See ECMA NumberFormatInfo page 8
528 return percentNegativePattern;
532 if (value < 0 || value > 2)
533 throw new ArgumentOutOfRangeException
534 ("The value specified for the property is less than 0 or greater than 15");
537 throw new InvalidOperationException
538 ("The current instance is read-only and a set operation was attempted");
540 percentNegativePattern = value;
544 public int PercentPositivePattern {
546 // See ECMA NumberFormatInfo page 11
547 return percentPositivePattern;
551 if (value < 0 || value > 2)
552 throw new ArgumentOutOfRangeException
553 ("The value specified for the property is less than 0 or greater than 3");
556 throw new InvalidOperationException
557 ("The current instance is read-only and a set operation was attempted");
559 percentPositivePattern = value;
563 public string PercentSymbol {
565 return percentSymbol;
570 throw new ArgumentNullException
571 ("The value specified for the property is a null reference");
574 throw new InvalidOperationException
575 ("The current instance is read-only and a set operation was attempted");
577 percentSymbol = value;
581 public string PerMilleSymbol {
583 return perMilleSymbol;
588 throw new ArgumentNullException
589 ("The value specified for the property is a null reference");
592 throw new InvalidOperationException
593 ("The current instance is read-only and a set operation was attempted");
595 perMilleSymbol = value;
599 public string PositiveInfinitySymbol {
601 return positiveInfinitySymbol;
606 throw new ArgumentNullException
607 ("The value specified for the property is a null reference");
610 throw new InvalidOperationException
611 ("The current instance is read-only and a set operation was attempted");
613 positiveInfinitySymbol = value;
617 public string PositiveSign {
624 throw new ArgumentNullException
625 ("The value specified for the property is a null reference");
628 throw new InvalidOperationException
629 ("The current instance is read-only and a set operation was attempted");
631 positiveSign = value;
635 public object GetFormat (Type formatType)
637 // LAMESPEC: ECMA says we implement IFormatProvider, but doesn't define this
639 // From the .NET Framework SDK
641 // Parameters: formatType The Type of the formatting service required.
643 // Return Value: The current instance of the NumberFormatInfo class, if formatType
644 // is the same as the type of the current instance; otherwise, a null reference
646 // Remarks: This method is invoked by the Format(String, IFormatProvider) method
647 // supported by the base data types when this instance is passed as the
648 // IFormatProvider parameter. It implements IFormatProvider.GetFormat.
650 if (formatType.Equals(this)) // LAMESPEC: Should this be IsInstanceOfType?
655 public object Clone ()
657 NumberFormatInfo clone = (NumberFormatInfo) MemberwiseClone();
658 // clone is not read only
659 clone.readOnly = false;
663 public static NumberFormatInfo ReadOnly (NumberFormatInfo nfi)
665 NumberFormatInfo copy = (NumberFormatInfo)nfi.Clone();
666 copy.readOnly = true;