2003-12-06 Dick Porter <dick@ximian.com>
[mono.git] / mcs / class / corlib / System.Globalization / DateTimeFormatInfo.cs
1 // System.Globalization.DateTimeFormatInfo
2 //
3 // Some useful functions are missing in the ECMA specs.
4 // They have been added following MS SDK Beta2
5 //
6 // Martin Weindel (martin.weindel@t-online.de)
7 //
8 // (C) Martin Weindel (martin.weindel@t-online.de)
9
10 using System;
11 using System.Threading;
12
13 namespace System.Globalization
14 {
15         [Serializable]
16         public sealed class DateTimeFormatInfo : ICloneable, IFormatProvider {
17                 private static readonly string MSG_READONLY = "This instance is read only";
18                 private static readonly string MSG_ARRAYSIZE_MONTH = "An array with exactly 13 elements is needed";
19                 private static readonly string MSG_ARRAYSIZE_DAY = "An array with exactly 7 elements is needed";
20                 private static readonly string[] INVARIANT_ABBREVIATED_DAY_NAMES
21                         = new string[7] { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
22                 private static readonly string[] INVARIANT_DAY_NAMES
23                         = new string[7] { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
24                 private static readonly string[] INVARIANT_ABBREVIATED_MONTH_NAMES
25                         = new string[13] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", ""};
26                 private static readonly string[] INVARIANT_MONTH_NAMES
27                         = new string[13] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", ""};
28                 private static readonly string[] INVARIANT_ERA_NAMES = {"A.D."};
29
30                 internal static DateTimeFormatInfo theInvariantDateTimeFormatInfo;
31
32                 private bool readOnly;
33                 private string _AMDesignator;
34                 private string _PMDesignator;
35                 private string _DateSeparator;
36                 private string _TimeSeparator;
37                 private string _ShortDatePattern;
38                 private string _LongDatePattern;
39                 private string _ShortTimePattern;
40                 private string _LongTimePattern;
41                 private string _MonthDayPattern;
42                 private string _YearMonthPattern;
43                 private string _FullDateTimePattern;
44                 private string _RFC1123Pattern;
45                 private string _SortableDateTimePattern;
46                 private string _UniversalSortableDateTimePattern;
47                 private DayOfWeek _FirstDayOfWeek;
48                 private Calendar _Calendar;
49                 private CalendarWeekRule _CalendarWeekRule;
50                 private string[] _AbbreviatedDayNames;
51                 private string[] _DayNames;
52                 private string[] _MonthNames;
53                 private string[] _AbbreviatedMonthNames;
54
55                 public DateTimeFormatInfo()
56                 {
57                         readOnly = false;
58                         _AMDesignator = "AM";
59                         _PMDesignator = "PM";
60                         _DateSeparator = "/";
61                         _TimeSeparator = ":";
62                         _ShortDatePattern = "MM/dd/yyyy";
63                         _LongDatePattern = "dddd, dd MMMM yyyy";
64                         _ShortTimePattern = "HH:mm";
65                         _LongTimePattern = "HH:mm:ss";
66                         _MonthDayPattern = "MMMM dd";
67                         _YearMonthPattern = "yyyy MMMM";
68                         _FullDateTimePattern = "dddd, dd MMMM yyyy HH:mm:ss";
69
70                         // FIXME for the following three pattern: "The
71                         // default value of this property is derived
72                         // from the calendar that is set for
73                         // CultureInfo.CurrentCulture or the default
74                         // calendar of CultureInfo.CurrentCulture."
75
76                         _RFC1123Pattern = "ddd, dd MMM yyyy HH':'mm':'ss 'GMT'"; 
77                         _SortableDateTimePattern = "yyyy'-'MM'-'dd'T'HH':'mm':'ss";
78                         _UniversalSortableDateTimePattern = "yyyy'-'MM'-'dd HH':'mm':'ss'Z'";
79
80                         _FirstDayOfWeek = DayOfWeek.Sunday;
81                         _Calendar = new GregorianCalendar();
82                         _CalendarWeekRule = CalendarWeekRule.FirstDay;
83
84                         _AbbreviatedDayNames = INVARIANT_ABBREVIATED_DAY_NAMES;
85                         _DayNames = INVARIANT_DAY_NAMES;
86                         _AbbreviatedMonthNames = INVARIANT_ABBREVIATED_MONTH_NAMES;
87                         _MonthNames = INVARIANT_MONTH_NAMES;
88                 }
89                                 
90                 // LAMESPEC: this is not in ECMA specs
91                 public static DateTimeFormatInfo GetInstance(IFormatProvider provider)
92                 {
93                         if (provider != null) {
94                                 DateTimeFormatInfo dtfi;
95                                 dtfi = (DateTimeFormatInfo)provider.GetFormat(typeof(DateTimeFormatInfo));
96                                 if (dtfi != null)
97                                         return dtfi;
98                         }
99                         
100                         return CurrentInfo;
101                 }
102
103                 public bool IsReadOnly {
104                         get {
105                                 return readOnly;
106                         }
107                 }
108
109                 public static DateTimeFormatInfo ReadOnly(DateTimeFormatInfo dtfi)
110                 {
111                         DateTimeFormatInfo copy = (DateTimeFormatInfo)dtfi.Clone();
112                         copy.readOnly = true;
113                         return copy;
114                 }                       
115
116                 public object Clone () 
117                 {
118                         DateTimeFormatInfo clone = (DateTimeFormatInfo) MemberwiseClone();
119                         // clone is not read only
120                         clone.readOnly = false;
121                         return clone;
122                 }
123
124                 public object GetFormat(Type formatType)
125                 {
126                         return (formatType == GetType()) ? this : null;
127                 }
128
129                 [MonoTODO]
130                 public string GetAbbreviatedEraName(int era)
131                 {
132                         if (era < _Calendar.Eras.Length || era >= _Calendar.Eras.Length)
133                                 throw new ArgumentOutOfRangeException();
134                         notImplemented();
135                         //FIXME: implement me
136                         return null;
137                 }
138
139                 public string GetAbbreviatedMonthName(int month)
140                 {
141                         if (month < 1 || month > 13) throw new ArgumentOutOfRangeException();
142                         return _AbbreviatedMonthNames[month-1];
143                 }
144
145                 [MonoTODO]
146                 public int GetEra(string eraName)
147                 {
148                         if (eraName == null) throw new ArgumentNullException();
149                         eraName = eraName.ToUpper();
150                         notImplemented();
151                         //FIXME: implement me
152                         return -1;
153                 }
154
155                 [MonoTODO]
156                 public string GetEraName(int era)
157                 {
158 //                      if (era < _Calendar.Eras.Length || era >= _Calendar.Eras.Length)
159 //                              throw new ArgumentOutOfRangeException();
160                         try {
161                                 return INVARIANT_ERA_NAMES[era - 1];
162                         }
163                         catch {
164                                 //FIXME: implement me
165                                 notImplemented();
166                                 return null;
167                         }
168                 }
169
170                 public string GetMonthName(int month)
171                 {
172                         if (month < 1 || month > 13) throw new ArgumentOutOfRangeException();
173                         return _MonthNames[month-1];
174                 }
175
176                 public string[] AbbreviatedDayNames
177                 {
178                         get
179                         {
180                                 return (string[]) _AbbreviatedDayNames.Clone();
181                         }
182                         set
183                         {
184                                 if (IsReadOnly) throw new InvalidOperationException(MSG_READONLY);
185                                 if (value == null) throw new ArgumentNullException();
186                                 if (value.GetLength(0) != 7) throw new ArgumentException(MSG_ARRAYSIZE_DAY);
187                                 _AbbreviatedDayNames = (string[]) value.Clone();
188                         }
189                 }
190
191                 public string[] AbbreviatedMonthNames
192                 {
193                         get
194                         {
195                                 return (string[]) _AbbreviatedMonthNames.Clone();
196                         }
197                         set
198                         {
199                                 if (IsReadOnly) throw new InvalidOperationException(MSG_READONLY);
200                                 if (value == null) throw new ArgumentNullException();
201                                 if (value.GetLength(0) != 13) throw new ArgumentException(MSG_ARRAYSIZE_MONTH);
202                                 _AbbreviatedMonthNames = (string[]) value.Clone();
203                         }
204                 }
205
206                 public string[] DayNames
207                 {
208                         get
209                         {
210                                 return (string[]) _DayNames.Clone();
211                         }
212                         set
213                         {
214                                 if (IsReadOnly) throw new InvalidOperationException(MSG_READONLY);
215                                 if (value == null) throw new ArgumentNullException();
216                                 if (value.GetLength(0) != 7) throw new ArgumentException(MSG_ARRAYSIZE_DAY);
217                                 _DayNames = (string[]) value.Clone();
218                         }
219                 }
220
221                 public string[] MonthNames
222                 {
223                         get
224                         {
225                                 return (string[]) _MonthNames.Clone();
226                         }
227                         set
228                         {
229                                 if (IsReadOnly) throw new InvalidOperationException(MSG_READONLY);
230                                 if (value == null) throw new ArgumentNullException();
231                                 if (value.GetLength(0) != 13) throw new ArgumentException(MSG_ARRAYSIZE_MONTH);
232                                 _MonthNames = (string[]) value.Clone();
233                         }
234                 }
235
236                 public string AMDesignator
237                 {
238                         get
239                         {
240                                 return _AMDesignator;
241                         }
242                         set
243                         {
244                                 if (IsReadOnly) throw new InvalidOperationException(MSG_READONLY);
245                                 if (value == null) throw new ArgumentNullException();
246                                 _AMDesignator = value;
247                         }
248                 }
249
250                 public string PMDesignator
251                 {
252                         get
253                         {
254                                 return _PMDesignator;
255                         }
256                         set
257                         {
258                                 if (IsReadOnly) throw new InvalidOperationException(MSG_READONLY);
259                                 if (value == null) throw new ArgumentNullException();
260                                 _PMDesignator = value;
261                         }
262                 }
263
264                 public string DateSeparator
265                 {
266                         get
267                         {
268                                 return _DateSeparator;
269                         }
270                         set
271                         {
272                                 if (IsReadOnly) throw new InvalidOperationException(MSG_READONLY);
273                                 if (value == null) throw new ArgumentNullException();
274                                 _DateSeparator = value;
275                         }
276                 }
277
278                 public string TimeSeparator
279                 {
280                         get
281                         {
282                                 return _TimeSeparator;
283                         }
284                         set
285                         {
286                                 if (IsReadOnly) throw new InvalidOperationException(MSG_READONLY);
287                                 if (value == null) throw new ArgumentNullException();
288                                 _TimeSeparator = value;
289                         }
290                 }
291
292                 public string LongDatePattern
293                 {
294                         get
295                         {
296                                 return _LongDatePattern;
297                         }
298                         set
299                         {
300                                 if (IsReadOnly) throw new InvalidOperationException(MSG_READONLY);
301                                 if (value == null) throw new ArgumentNullException();
302                                 _LongDatePattern = value;
303                         }
304                 }
305
306                 public string ShortDatePattern
307                 {
308                         get
309                         {
310                                 return _ShortDatePattern;
311                         }
312                         set
313                         {
314                                 if (IsReadOnly) throw new InvalidOperationException(MSG_READONLY);
315                                 if (value == null) throw new ArgumentNullException();
316                                 _ShortDatePattern = value;
317                         }
318                 }
319
320                 public string ShortTimePattern
321                 {
322                         get
323                         {
324                                 return _ShortTimePattern;
325                         }
326                         set
327                         {
328                                 if (IsReadOnly) throw new InvalidOperationException(MSG_READONLY);
329                                 if (value == null) throw new ArgumentNullException();
330                                 _ShortTimePattern = value;
331                         }
332                 }
333
334                 public string LongTimePattern
335                 {
336                         get
337                         {
338                                 return _LongTimePattern;
339                         }
340                         set
341                         {
342                                 if (IsReadOnly) throw new InvalidOperationException(MSG_READONLY);
343                                 if (value == null) throw new ArgumentNullException();
344                                 _LongTimePattern = value;
345                         }
346                 }
347
348                 public string MonthDayPattern
349                 {
350                         get
351                         {
352                                 return _MonthDayPattern;
353                         }
354                         set
355                         {
356                                 if (IsReadOnly) throw new InvalidOperationException(MSG_READONLY);
357                                 if (value == null) throw new ArgumentNullException();
358                                 _MonthDayPattern = value;
359                         }
360                 }
361
362                 public string YearMonthPattern
363                 {
364                         get
365                         {
366                                 return _YearMonthPattern;
367                         }
368                         set
369                         {
370                                 if (IsReadOnly) throw new InvalidOperationException(MSG_READONLY);
371                                 if (value == null) throw new ArgumentNullException();
372                                 _YearMonthPattern = value;
373                         }
374                 }
375
376                 public string FullDateTimePattern
377                 {
378                         get
379                         {
380                                 if(_FullDateTimePattern!=null) {
381                                         return _FullDateTimePattern;
382                                 } else {
383                                         return(_LongDatePattern + " " + _LongTimePattern);
384                                 }
385                         }
386                         set
387                         {
388                                 if (IsReadOnly) throw new InvalidOperationException(MSG_READONLY);
389                                 if (value == null) throw new ArgumentNullException();
390                                 _FullDateTimePattern = value;
391                         }
392                 }
393
394                 public static DateTimeFormatInfo CurrentInfo
395                 {
396                         get
397                         {
398                                 return Thread.CurrentThread.CurrentCulture.DateTimeFormat;
399                         }
400                 }
401
402                 public static DateTimeFormatInfo InvariantInfo
403                 {
404                         get
405                         {
406                                 if (theInvariantDateTimeFormatInfo == null)
407                                 {
408                                         theInvariantDateTimeFormatInfo = 
409                                                 DateTimeFormatInfo.ReadOnly(new DateTimeFormatInfo());
410                                 }
411                                 return theInvariantDateTimeFormatInfo;
412                         }
413                 }
414
415                 // LAMESPEC: this is not in ECMA specs
416                 public DayOfWeek FirstDayOfWeek
417                 {
418                         get
419                         {
420                                 return _FirstDayOfWeek;
421                         }
422                         set
423                         {
424                                 if (IsReadOnly) throw new InvalidOperationException(MSG_READONLY);
425                                 if ((int) value < 0 || (int) value > 6) throw new ArgumentOutOfRangeException();
426                                 _FirstDayOfWeek = value;
427                         }
428                 }
429
430                 // LAMESPEC: this is not in ECMA specs
431                 public Calendar Calendar
432                 {
433                         get
434                         {
435                                 return _Calendar;
436                         }
437                         set
438                         {
439                                 if (IsReadOnly) throw new InvalidOperationException(MSG_READONLY);
440                                 if (value == null) throw new ArgumentNullException();
441                                 _Calendar = value;
442                         }
443                 }
444
445                 public CalendarWeekRule CalendarWeekRule
446                 {
447                         get
448                         {
449                                 return _CalendarWeekRule;
450                         }
451                         set
452                         {
453                                 if (IsReadOnly) throw new InvalidOperationException(MSG_READONLY);
454                                 _CalendarWeekRule = value;
455                         }
456                 }
457
458                 // LAMESPEC: this is not in ECMA specs
459                 public string RFC1123Pattern
460                 {
461                         get
462                         {
463                                 return _RFC1123Pattern;
464                         }
465                 }
466
467                 // LAMESPEC: this is not in ECMA specs
468                 public string SortableDateTimePattern
469                 {
470                         get
471                         {
472                                 return _SortableDateTimePattern;
473                         }
474                 }
475
476                 // LAMESPEC: this is not in ECMA specs
477                 public string UniversalSortableDateTimePattern
478                 {
479                         get
480                         {
481                                 return _UniversalSortableDateTimePattern;
482                         }
483                 }
484                 
485                 // LAMESPEC: this is not in ECMA specs
486                 [MonoTODO]
487                 public string[] GetAllDateTimePatterns()
488                 {
489                         notImplemented();
490                         //FIXME: implement me
491                         return null;
492                 }
493
494                 // LAMESPEC: this is not in ECMA specs
495                 [MonoTODO]
496                 public string[] GetAllDateTimePatterns(char format)
497                 {
498                         notImplemented();
499                         //FIXME: implement me
500                         return null;
501                 }
502
503                 // LAMESPEC: this is not in ECMA specs
504                 public string GetDayName(DayOfWeek dayofweek)
505                 {
506                         int index = (int) dayofweek;
507                         if (index < 0 || index > 6) throw new ArgumentOutOfRangeException();
508                         return _DayNames[index];
509                 }
510
511                 // LAMESPEC: this is not in ECMA specs
512                 public string GetAbbreviatedDayName(DayOfWeek dayofweek)
513                 {
514                         int index = (int) dayofweek;
515                         if (index < 0 || index > 6) throw new ArgumentOutOfRangeException();
516                         return _AbbreviatedDayNames[index];
517                 }
518
519                 private static void notImplemented()
520                 {
521                         throw new Exception("Not implemented");
522                 }
523         }
524 }