| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702 |
- // System.Globalization.DateTimeFormatInfo
- //
- // Some useful functions are missing in the ECMA specs.
- // They have been added following MS SDK Beta2
- //
- // Martin Weindel ([email protected])
- //
- // (C) Martin Weindel ([email protected])
- //
- // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
- //
- // Permission is hereby granted, free of charge, to any person obtaining
- // a copy of this software and associated documentation files (the
- // "Software"), to deal in the Software without restriction, including
- // without limitation the rights to use, copy, modify, merge, publish,
- // distribute, sublicense, and/or sell copies of the Software, and to
- // permit persons to whom the Software is furnished to do so, subject to
- // the following conditions:
- //
- // The above copyright notice and this permission notice shall be
- // included in all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- //
- using System;
- using System.Collections;
- using System.Threading;
- namespace System.Globalization
- {
- [Serializable]
- [MonoTODO ("Fix serialization compatibility with MS.NET")]
- public sealed class DateTimeFormatInfo : ICloneable, IFormatProvider {
- private static readonly string MSG_READONLY = "This instance is read only";
- private static readonly string MSG_ARRAYSIZE_MONTH = "An array with exactly 13 elements is needed";
- private static readonly string MSG_ARRAYSIZE_DAY = "An array with exactly 7 elements is needed";
- private static readonly string[] INVARIANT_ABBREVIATED_DAY_NAMES
- = new string[7] { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
- private static readonly string[] INVARIANT_DAY_NAMES
- = new string[7] { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
- private static readonly string[] INVARIANT_ABBREVIATED_MONTH_NAMES
- = new string[13] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", ""};
- private static readonly string[] INVARIANT_MONTH_NAMES
- = new string[13] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", ""};
- private static readonly string[] INVARIANT_ERA_NAMES = {"A.D."};
- private static DateTimeFormatInfo theInvariantDateTimeFormatInfo;
- private bool readOnly;
- private string _AMDesignator;
- private string _PMDesignator;
- private string _DateSeparator;
- private string _TimeSeparator;
- private string _ShortDatePattern;
- private string _LongDatePattern;
- private string _ShortTimePattern;
- private string _LongTimePattern;
- private string _MonthDayPattern;
- private string _YearMonthPattern;
- private string _FullDateTimePattern;
- private string _RFC1123Pattern;
- private string _SortableDateTimePattern;
- private string _UniversalSortableDateTimePattern;
- private DayOfWeek _FirstDayOfWeek;
- private Calendar _Calendar;
- private CalendarWeekRule _CalendarWeekRule;
- private string[] _AbbreviatedDayNames;
- private string[] _DayNames;
- private string[] _MonthNames;
- private string[] _AbbreviatedMonthNames;
- // FIXME: not supported other than invariant
- private string [] _ShortDatePatterns;
- private string [] _LongDatePatterns;
- private string [] _ShortTimePatterns;
- private string [] _LongTimePatterns;
- private string [] _MonthDayPatterns;
- private string [] _YearMonthPatterns;
- public DateTimeFormatInfo()
- {
- readOnly = false;
- _AMDesignator = "AM";
- _PMDesignator = "PM";
- _DateSeparator = "/";
- _TimeSeparator = ":";
- _ShortDatePattern = "MM/dd/yyyy";
- _LongDatePattern = "dddd, dd MMMM yyyy";
- _ShortTimePattern = "HH:mm";
- _LongTimePattern = "HH:mm:ss";
- _MonthDayPattern = "MMMM dd";
- _YearMonthPattern = "yyyy MMMM";
- _FullDateTimePattern = "dddd, dd MMMM yyyy HH:mm:ss";
- // FIXME: for the following three pattern: "The
- // default value of this property is derived
- // from the calendar that is set for
- // CultureInfo.CurrentCulture or the default
- // calendar of CultureInfo.CurrentCulture."
- // Actually, no predefined culture has different values
- // than those default values.
- _RFC1123Pattern = "ddd, dd MMM yyyy HH':'mm':'ss 'GMT'";
- _SortableDateTimePattern = "yyyy'-'MM'-'dd'T'HH':'mm':'ss";
- _UniversalSortableDateTimePattern = "yyyy'-'MM'-'dd HH':'mm':'ss'Z'";
- _FirstDayOfWeek = DayOfWeek.Sunday;
- _Calendar = new GregorianCalendar();
- _CalendarWeekRule = CalendarWeekRule.FirstDay;
- _AbbreviatedDayNames = INVARIANT_ABBREVIATED_DAY_NAMES;
- _DayNames = INVARIANT_DAY_NAMES;
- _AbbreviatedMonthNames = INVARIANT_ABBREVIATED_MONTH_NAMES;
- _MonthNames = INVARIANT_MONTH_NAMES;
- }
-
- // LAMESPEC: this is not in ECMA specs
- public static DateTimeFormatInfo GetInstance(IFormatProvider provider)
- {
- if (provider != null) {
- DateTimeFormatInfo dtfi;
- dtfi = (DateTimeFormatInfo)provider.GetFormat(typeof(DateTimeFormatInfo));
- if (dtfi != null)
- return dtfi;
- }
-
- return CurrentInfo;
- }
- public bool IsReadOnly {
- get {
- return readOnly;
- }
- }
- public static DateTimeFormatInfo ReadOnly(DateTimeFormatInfo dtfi)
- {
- DateTimeFormatInfo copy = (DateTimeFormatInfo)dtfi.Clone();
- copy.readOnly = true;
- return copy;
- }
- public object Clone ()
- {
- DateTimeFormatInfo clone = (DateTimeFormatInfo) MemberwiseClone();
- // clone is not read only
- clone.readOnly = false;
- return clone;
- }
- public object GetFormat(Type formatType)
- {
- return (formatType == GetType()) ? this : null;
- }
- public string GetAbbreviatedEraName (int era)
- {
- if (era < 0 || era >= _Calendar.AbbreviatedEraNames.Length)
- throw new ArgumentOutOfRangeException ("era", era.ToString ());
- return _Calendar.AbbreviatedEraNames [era];
- }
- public string GetAbbreviatedMonthName(int month)
- {
- if (month < 1 || month > 13) throw new ArgumentOutOfRangeException();
- return _AbbreviatedMonthNames[month-1];
- }
- public int GetEra (string eraName)
- {
- if (eraName == null)
- throw new ArgumentNullException ();
- string [] eras = _Calendar.EraNames;
- for (int i = 0; i < eras.Length; i++)
- if (CultureInfo.InvariantCulture.CompareInfo
- .Compare (eraName, eras [i],
- CompareOptions.IgnoreCase) == 0)
- return i;
- return -1;
- }
- public string GetEraName (int era)
- {
- if (era < 0 || era > _Calendar.EraNames.Length)
- throw new ArgumentOutOfRangeException ("era", era.ToString ());
- return _Calendar.EraNames [era - 1];
- }
- public string GetMonthName(int month)
- {
- if (month < 1 || month > 13) throw new ArgumentOutOfRangeException();
- return _MonthNames[month-1];
- }
- public string[] AbbreviatedDayNames
- {
- get
- {
- return (string[]) _AbbreviatedDayNames.Clone();
- }
- set
- {
- if (IsReadOnly) throw new InvalidOperationException(MSG_READONLY);
- if (value == null) throw new ArgumentNullException();
- if (value.GetLength(0) != 7) throw new ArgumentException(MSG_ARRAYSIZE_DAY);
- _AbbreviatedDayNames = (string[]) value.Clone();
- }
- }
- public string[] AbbreviatedMonthNames
- {
- get
- {
- return (string[]) _AbbreviatedMonthNames.Clone();
- }
- set
- {
- if (IsReadOnly) throw new InvalidOperationException(MSG_READONLY);
- if (value == null) throw new ArgumentNullException();
- if (value.GetLength(0) != 13) throw new ArgumentException(MSG_ARRAYSIZE_MONTH);
- _AbbreviatedMonthNames = (string[]) value.Clone();
- }
- }
- public string[] DayNames
- {
- get
- {
- return (string[]) _DayNames.Clone();
- }
- set
- {
- if (IsReadOnly) throw new InvalidOperationException(MSG_READONLY);
- if (value == null) throw new ArgumentNullException();
- if (value.GetLength(0) != 7) throw new ArgumentException(MSG_ARRAYSIZE_DAY);
- _DayNames = (string[]) value.Clone();
- }
- }
- public string[] MonthNames
- {
- get
- {
- return (string[]) _MonthNames.Clone();
- }
- set
- {
- if (IsReadOnly) throw new InvalidOperationException(MSG_READONLY);
- if (value == null) throw new ArgumentNullException();
- if (value.GetLength(0) != 13) throw new ArgumentException(MSG_ARRAYSIZE_MONTH);
- _MonthNames = (string[]) value.Clone();
- }
- }
- public string AMDesignator
- {
- get
- {
- return _AMDesignator;
- }
- set
- {
- if (IsReadOnly) throw new InvalidOperationException(MSG_READONLY);
- if (value == null) throw new ArgumentNullException();
- _AMDesignator = value;
- }
- }
- public string PMDesignator
- {
- get
- {
- return _PMDesignator;
- }
- set
- {
- if (IsReadOnly) throw new InvalidOperationException(MSG_READONLY);
- if (value == null) throw new ArgumentNullException();
- _PMDesignator = value;
- }
- }
- public string DateSeparator
- {
- get
- {
- return _DateSeparator;
- }
- set
- {
- if (IsReadOnly) throw new InvalidOperationException(MSG_READONLY);
- if (value == null) throw new ArgumentNullException();
- _DateSeparator = value;
- }
- }
- public string TimeSeparator
- {
- get
- {
- return _TimeSeparator;
- }
- set
- {
- if (IsReadOnly) throw new InvalidOperationException(MSG_READONLY);
- if (value == null) throw new ArgumentNullException();
- _TimeSeparator = value;
- }
- }
- public string LongDatePattern
- {
- get
- {
- return _LongDatePattern;
- }
- set
- {
- if (IsReadOnly) throw new InvalidOperationException(MSG_READONLY);
- if (value == null) throw new ArgumentNullException();
- _LongDatePattern = value;
- }
- }
- public string ShortDatePattern
- {
- get
- {
- return _ShortDatePattern;
- }
- set
- {
- if (IsReadOnly) throw new InvalidOperationException(MSG_READONLY);
- if (value == null) throw new ArgumentNullException();
- _ShortDatePattern = value;
- }
- }
- public string ShortTimePattern
- {
- get
- {
- return _ShortTimePattern;
- }
- set
- {
- if (IsReadOnly) throw new InvalidOperationException(MSG_READONLY);
- if (value == null) throw new ArgumentNullException();
- _ShortTimePattern = value;
- }
- }
- public string LongTimePattern
- {
- get
- {
- return _LongTimePattern;
- }
- set
- {
- if (IsReadOnly) throw new InvalidOperationException(MSG_READONLY);
- if (value == null) throw new ArgumentNullException();
- _LongTimePattern = value;
- }
- }
- public string MonthDayPattern
- {
- get
- {
- return _MonthDayPattern;
- }
- set
- {
- if (IsReadOnly) throw new InvalidOperationException(MSG_READONLY);
- if (value == null) throw new ArgumentNullException();
- _MonthDayPattern = value;
- }
- }
- public string YearMonthPattern
- {
- get
- {
- return _YearMonthPattern;
- }
- set
- {
- if (IsReadOnly) throw new InvalidOperationException(MSG_READONLY);
- if (value == null) throw new ArgumentNullException();
- _YearMonthPattern = value;
- }
- }
- public string FullDateTimePattern
- {
- get
- {
- if(_FullDateTimePattern!=null) {
- return _FullDateTimePattern;
- } else {
- return(_LongDatePattern + " " + _LongTimePattern);
- }
- }
- set
- {
- if (IsReadOnly) throw new InvalidOperationException(MSG_READONLY);
- if (value == null) throw new ArgumentNullException();
- _FullDateTimePattern = value;
- }
- }
- public static DateTimeFormatInfo CurrentInfo
- {
- get
- {
- return Thread.CurrentThread.CurrentCulture.DateTimeFormat;
- }
- }
- public static DateTimeFormatInfo InvariantInfo
- {
- get
- {
- if (theInvariantDateTimeFormatInfo == null) {
- theInvariantDateTimeFormatInfo =
- DateTimeFormatInfo.ReadOnly(new DateTimeFormatInfo());
- theInvariantDateTimeFormatInfo.FillInvariantPatterns ();
- }
- return theInvariantDateTimeFormatInfo;
- }
- }
- // LAMESPEC: this is not in ECMA specs
- public DayOfWeek FirstDayOfWeek
- {
- get
- {
- return _FirstDayOfWeek;
- }
- set
- {
- if (IsReadOnly) throw new InvalidOperationException(MSG_READONLY);
- if ((int) value < 0 || (int) value > 6) throw new ArgumentOutOfRangeException();
- _FirstDayOfWeek = value;
- }
- }
- // LAMESPEC: this is not in ECMA specs
- public Calendar Calendar
- {
- get
- {
- return _Calendar;
- }
- set
- {
- if (IsReadOnly) throw new InvalidOperationException(MSG_READONLY);
- if (value == null) throw new ArgumentNullException();
- _Calendar = value;
- }
- }
- public CalendarWeekRule CalendarWeekRule
- {
- get
- {
- return _CalendarWeekRule;
- }
- set
- {
- if (IsReadOnly) throw new InvalidOperationException(MSG_READONLY);
- _CalendarWeekRule = value;
- }
- }
- // LAMESPEC: this is not in ECMA specs
- public string RFC1123Pattern
- {
- get
- {
- return _RFC1123Pattern;
- }
- }
- // LAMESPEC: this is not in ECMA specs
- public string SortableDateTimePattern
- {
- get
- {
- return _SortableDateTimePattern;
- }
- }
- // LAMESPEC: this is not in ECMA specs
- public string UniversalSortableDateTimePattern
- {
- get
- {
- return _UniversalSortableDateTimePattern;
- }
- }
-
- // LAMESPEC: this is not in ECMA specs
- [MonoTODO ("Not complete depending on GetAllDateTimePatterns(char)")]
- public string[] GetAllDateTimePatterns()
- {
- FillAllDateTimePatterns ();
- return (string []) all_date_time_patterns.Clone ();
- }
- // Same as above, but with no cloning, because we know that
- // clients are friendly
- internal string [] GetAllDateTimePatternsInternal ()
- {
- FillAllDateTimePatterns ();
- return all_date_time_patterns;
- }
-
- // Prevent write reordering
- volatile string [] all_date_time_patterns;
-
- void FillAllDateTimePatterns (){
- if (all_date_time_patterns != null)
- return;
-
- ArrayList al = new ArrayList ();
- foreach (string s in GetAllDateTimePatterns ('d'))
- al.Add (s);
- foreach (string s in GetAllDateTimePatterns ('D'))
- al.Add (s);
- foreach (string s in GetAllDateTimePatterns ('g'))
- al.Add (s);
- foreach (string s in GetAllDateTimePatterns ('G'))
- al.Add (s);
- foreach (string s in GetAllDateTimePatterns ('f'))
- al.Add (s);
- foreach (string s in GetAllDateTimePatterns ('F'))
- al.Add (s);
- // Yes, that is very meaningless, but that is what MS
- // is doing (LAMESPEC: Since it is documented that
- // 'M' and 'm' are equal, they should not cosider
- // that there is a possibility that 'M' and 'm' are
- // different.)
- foreach (string s in GetAllDateTimePatterns ('m'))
- al.Add (s);
- foreach (string s in GetAllDateTimePatterns ('M'))
- al.Add (s);
- foreach (string s in GetAllDateTimePatterns ('r'))
- al.Add (s);
- foreach (string s in GetAllDateTimePatterns ('R'))
- al.Add (s);
- foreach (string s in GetAllDateTimePatterns ('s'))
- al.Add (s);
- foreach (string s in GetAllDateTimePatterns ('t'))
- al.Add (s);
- foreach (string s in GetAllDateTimePatterns ('T'))
- al.Add (s);
- foreach (string s in GetAllDateTimePatterns ('u'))
- al.Add (s);
- foreach (string s in GetAllDateTimePatterns ('U'))
- al.Add (s);
- foreach (string s in GetAllDateTimePatterns ('y'))
- al.Add (s);
- foreach (string s in GetAllDateTimePatterns ('Y'))
- al.Add (s);
- // all_date_time_patterns needs to be volatile to prevent
- // reordering of writes here and still avoid any locking.
- all_date_time_patterns = (string []) al.ToArray (typeof (string)) as string [];
- }
- // LAMESPEC: this is not in ECMA specs
- [MonoTODO ("We need more culture data in locale-builder")]
- public string[] GetAllDateTimePatterns (char format)
- {
- string [] list;
- switch (format) {
- // Date
- case 'D':
- if (_LongDatePatterns != null && _LongDatePatterns.Length > 0)
- return _LongDatePatterns.Clone () as string [];
- return new string [] {LongDatePattern};
- case 'd':
- if (_ShortDatePatterns != null && _ShortDatePatterns.Length > 0)
- return _ShortDatePatterns.Clone () as string [];
- return new string [] {ShortDatePattern};
- // Time
- case 'T':
- if (_LongTimePatterns != null && _LongTimePatterns.Length > 0)
- return _LongTimePatterns.Clone () as string [];
- return new string [] {LongTimePattern};
- case 't':
- if (_ShortTimePatterns != null && _ShortTimePatterns.Length > 0)
- return _ShortTimePatterns.Clone () as string [];
- return new string [] {ShortTimePattern};
- // {Short|Long}Date + {Short|Long}Time
- // FIXME: they should be the agglegation of the
- // combination of the Date patterns and Time patterns.
- case 'G':
- list = PopulateCombinedList (_ShortDatePatterns, _LongTimePatterns);
- if (list != null && list.Length > 0)
- return list;
- return new string [] {ShortDatePattern + " " + LongTimePattern};
- case 'g':
- list = PopulateCombinedList (_ShortDatePatterns, _ShortTimePatterns);
- if (list != null && list.Length > 0)
- return list;
- return new string [] {ShortDatePattern + " " + ShortTimePattern};
- // The 'U' pattern strings are always the same as 'F'.
- // (only differs in assuming UTC or not.)
- case 'U':
- case 'F':
- list = PopulateCombinedList (_LongDatePatterns, _LongTimePatterns);
- if (list != null && list.Length > 0)
- return list;
- return new string [] {LongDatePattern + " " + LongTimePattern};
- case 'f':
- list = PopulateCombinedList (_LongDatePatterns, _ShortTimePatterns);
- if (list != null && list.Length > 0)
- return list;
- return new string [] {LongDatePattern + " " + ShortTimePattern};
- // MonthDay
- case 'm':
- case 'M':
- if (_MonthDayPatterns != null && _MonthDayPatterns.Length > 0)
- return _MonthDayPatterns.Clone () as string [];
- return new string [] {MonthDayPattern};
- // YearMonth
- case 'Y':
- case 'y':
- if (_YearMonthPatterns != null && _YearMonthPatterns.Length > 0)
- return _YearMonthPatterns.Clone () as string [];
- return new string [] {YearMonthPattern};
- // RFC1123
- case 'r':
- case 'R':
- return new string [] {RFC1123Pattern};
- case 's':
- return new string [] {SortableDateTimePattern};
- case 'u':
- return new string [] {UniversalSortableDateTimePattern};
- }
- throw new ArgumentException ("Format specifier was invalid.");
- }
- // LAMESPEC: this is not in ECMA specs
- public string GetDayName(DayOfWeek dayofweek)
- {
- int index = (int) dayofweek;
- if (index < 0 || index > 6) throw new ArgumentOutOfRangeException();
- return _DayNames[index];
- }
- // LAMESPEC: this is not in ECMA specs
- public string GetAbbreviatedDayName(DayOfWeek dayofweek)
- {
- int index = (int) dayofweek;
- if (index < 0 || index > 6) throw new ArgumentOutOfRangeException();
- return _AbbreviatedDayNames[index];
- }
- private void FillInvariantPatterns ()
- {
- _ShortDatePatterns = new string [] {"MM/dd/yyyy"};
- _LongDatePatterns = new string [] {"dddd, dd MMMM yyyy"};
- _LongTimePatterns = new string [] {"HH:mm:ss"};
- _ShortTimePatterns = new string [] {
- "HH:mm",
- "hh:mm tt",
- "H:mm",
- "h:mm tt"
- };
- _MonthDayPatterns = new string [] {"MMMM dd"};
- _YearMonthPatterns = new string [] {"yyyy MMMM"};
- }
- private string [] PopulateCombinedList (string [] dates, string [] times)
- {
- if (dates != null && times != null) {
- string [] list = new string [dates.Length * times.Length];
- int i = 0;
- foreach (string d in dates)
- foreach (string t in times)
- list [i++] = d + " " + t;
- return list;
- }
- return null;
- }
- }
- }
|