2001-08-01 Dietmar Maurer <dietmar@ximian.com>
[mono.git] / mcs / class / corlib / System / DateTime.cs
1 //
2 // System.DateTime.cs
3 //
4 // author:
5 //   Marcel Narings (marcel@narings.nl)
6 //
7 //   (C) 2001 Marcel Narings
8
9 using System.Globalization ;
10 namespace System
11 {
12
13         public struct DateTime : IComparable //, IFormattable, IConvertible
14         {
15                 long ticks;
16
17                 public static readonly DateTime MaxValue = new DateTime(3155378975999999999L);
18                 public static readonly DateTime MinValue = new DateTime(0L);
19                 
20                 private enum Which 
21                 {
22                         Day,
23                         DayYear,
24                         Month,
25                         Year
26                 };
27
28                 // Constructors
29                 public DateTime (long newticks) 
30                 {
31                         ticks = newticks;
32                 
33                         if ( newticks < MinValue.ticks || newticks > MaxValue.ticks)
34                                 throw new ArgumentOutOfRangeException ();
35                 }
36
37                 public DateTime (int year, int month, int day)
38                         : this (year, month, day,0,0,0,0) {}
39
40                 public DateTime (int year, int month, int day, int hour, int minute, int second)
41                         : this (year, month, day, hour, minute, second, 0)      {}
42
43                 public DateTime (int year, int month, int day, int hour, int minute, int second, int millisecond)
44                 {
45                         if ( year < 1 || year > 9999 || 
46                                 month < 1 || month >12  ||
47                                 day < 1 || day > DaysInMonth(year, month) ||
48                                 hour < 0 || hour > 23 ||
49                                 minute < 0 || minute > 59 ||
50                                 second < 0 || second > 59 )
51                                 throw new ArgumentOutOfRangeException() ;
52                                 
53                         ticks = AbsoluteDays(year,month,day) * TimeSpan.TicksPerDay + 
54                                 hour * TimeSpan.TicksPerHour + 
55                                 minute * TimeSpan.TicksPerMinute + 
56                                 second * TimeSpan.TicksPerSecond + 
57                                 millisecond * TimeSpan.TicksPerMillisecond ; 
58                         
59                         if (ticks < MinValue.ticks || ticks > MaxValue.ticks )
60                                 throw new ArgumentException() ;
61                 }
62
63                 public DateTime (int year, int month, int day, Calendar calendar)
64                         : this (year, month, day, 0, 0, 0, 0, calendar) {}
65
66                 
67                 public DateTime (int year, int month, int day, int hour, int minute, int second, Calendar calendar)
68                         : this (year, month, day, hour, minute, second, 0, calendar)    {}
69
70
71                 public DateTime (int year, int month, int day, int hour, int minute, int second, int millisecond, Calendar calendar)
72                         : this(year, month, day, hour, minute, second, millisecond) 
73                 {
74                         // TODO implement calendar
75                 }
76
77
78                 /* Properties  */
79                  
80                 public DateTime Date 
81                 {
82                         get     
83                         { 
84                                 return new DateTime(ticks - (ticks % TimeSpan.TicksPerDay )) ; 
85                         }
86                 }
87         
88                 public int Day
89                 {
90                         get 
91                         { 
92                                 return FromTicks(Which.Day); 
93                         }
94                 }
95
96                 public DayOfWeek DayOfWeek 
97                 {
98                         get 
99                         { 
100                                 return (DayOfWeek) (((ticks / TimeSpan.TicksPerDay)+1) % 7); 
101                         }
102                 }
103
104                 public int DayOfYear 
105                 {
106                         get 
107                         { 
108                                 return FromTicks(Which.DayYear); 
109                         }
110                 }
111
112                 public int Hour 
113                 {
114                         get 
115                         { 
116                                 return (int) ((ticks % TimeSpan.TicksPerDay) / TimeSpan.TicksPerHour);  
117                         }
118                 }
119
120                 public int Millisecond 
121                 {
122                         get 
123                         { 
124                                 return (int) (ticks % TimeSpan.TicksPerSecond / TimeSpan.TicksPerMillisecond); 
125                         }
126                 }
127                 
128                 public int Minute 
129                 {
130                         get 
131                         { 
132                                 return (int) (ticks % TimeSpan.TicksPerHour / TimeSpan.TicksPerMinute); 
133                         }
134                 }
135
136                 public int Month 
137                 {
138                         get 
139                         { 
140                                 return FromTicks(Which.Month); 
141                         }
142                 }
143
144                 // TODO IMPLEMENT ME 
145                 //public static DateTime Now {get;}
146
147                 public int Second 
148                 {
149                         get 
150                         { 
151                                 return (int) (ticks % TimeSpan.TicksPerMinute / TimeSpan.TicksPerSecond); 
152                         }
153                 }
154
155                 public long Ticks
156                 { 
157                         get 
158                         { 
159                                 return ticks ; 
160                         }
161                 }
162         
163                 public TimeSpan TimeOfDay 
164                 {
165                         get 
166                         { 
167                                 return new TimeSpan(ticks % TimeSpan.TicksPerDay );
168                         }
169                         
170                 }
171
172                 //TODO implement
173                 //public static DateTime Today {get;}
174
175                 //TODO implement
176                 //public static DateTime UtcNow {get;}
177
178                 public int Year 
179                 {
180                         get 
181                         { 
182                                 return FromTicks(Which.Year); 
183                         }
184                 }
185
186
187                 /* methods */
188
189                 public DateTime AddTicks( long t )
190                 {
191                         return new DateTime(ticks + t);
192                 }
193
194                 // FIXME: Implement me.
195                 public DateTime AddDays( double days )
196                 {
197                         return new DateTime (0);
198                 }
199
200                 // TODO: Implement me.
201                 public DateTime AddHours( double hours )
202                 {
203                         return new DateTime (0);
204                 }
205
206                 // TODO: Implement me.
207                 public DateTime AddMilliseconds( double ms      )
208                 {
209                         return new DateTime (0);
210                 }
211
212                 // TODO: Implement me.
213                 public DateTime AddMinutes(     double minutes )
214                 {
215                         return new DateTime (0);
216                 }
217                 
218                 // TODO: Implement me.
219                 public DateTime AddMonths( int months )
220                 {
221                         return new DateTime (0);
222                 }
223
224                 // TODO: Implement me.
225                 public DateTime AddSeconds(double seconds )
226                 {
227                         return new DateTime (0);
228                 }
229
230                 // TODO: Implement me.
231                 public DateTime AddYears(int years )
232                 {
233                         return new DateTime (0);
234                 }
235
236                 public static int Compare( DateTime t1, DateTime t2     )
237                 {
238                         if (t1.ticks < t2.ticks) 
239                                 return -1;
240                         else if (t1.ticks > t2.ticks) 
241                                 return 1;
242                         else
243                                 return 0;
244                 }
245
246                 // FIXME check this
247                 public int CompareTo (object v)
248                 {
249                         if ( v == null)
250                                 return 1 ;
251
252                         if (!(v is System.DateTime))
253                                 throw new ArgumentException ("Value is not a System.DateTime");
254
255                         return Compare (this , (DateTime) v);
256                 }
257
258                 public static int DaysInMonth(int year, int month)
259                 {
260                         int[] dayspermonth = new int[13] { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; 
261
262                         if (month < 1 || month >12)
263                                 throw new ArgumentOutOfRangeException ();
264                  
265                         if (month == 2 && IsLeapYear(year))
266                                 return 29;
267                         else
268                                 return dayspermonth[month];                     
269                 }
270
271                 
272                 public override bool Equals (object o)
273                 {
274                         if (!(o is System.DateTime))
275                                 return false;
276
277                         return ((DateTime) o).ticks == ticks;
278                 }
279
280                 public static new bool Equals(DateTime t1, DateTime t2 )
281                 {
282                         return (t1.ticks == t2.ticks );
283                 }
284
285                 // TODO: Implement me.
286                 public static DateTime FromFileTime(long fileTime) 
287                 {
288                         return new DateTime(0);
289                 }
290
291                 // TODO: Implement me.
292                 public static DateTime FromOADate(double d)
293                 {
294                         return new DateTime(0);
295                 }
296                 
297                 // TODO: Implement me.
298                 //public string[] GetDateTimeFormats();
299
300                 //TODO: implement me 
301                 //public string[] GetDateTimeFormats(   char format     )
302                 
303                 // TODO: implement me 
304                 //public string[] GetDateTimeFormats(   IFormatProvider provider)
305
306                 //TODO: implement me 
307                 //public string[] GetDateTimeFormats(char format,IFormatProvider provider       )
308
309
310                 public override int GetHashCode ()
311                 {
312                         return (int) ticks;
313                 }
314
315                 public TypeCode GetTypeCode ()
316                 {
317                         return TypeCode.DateTime;
318                 }
319
320                 public static bool IsLeapYear(int year)
321                 {
322                         return ( !(year %4 > 0 ) && (year %100 > 0) || !(year %400 > 0) ) ;
323                 }
324
325                 public static DateTime Parse (string s)
326                 {
327                         // TODO: Implement me
328                         return new DateTime (0);
329                 }
330
331                 public static DateTime Parse (string s, IFormatProvider fp)
332                 {
333                         // TODO: Implement me
334                         return new DateTime (0);
335                 }
336
337                 public static DateTime Parse (string s, NumberStyles style, IFormatProvider fp)
338                 {
339                         // TODO: Implement me
340                         return new DateTime (0);
341                 }
342
343                 public static DateTime ParseExact(string s,     string format, IFormatProvider provider )
344                 {
345                         // TODO: Implement me
346                         return new DateTime (0);
347                 }
348
349                 public static DateTime ParseExact(      string s, string format, IFormatProvider provider,      DateTimeStyles style )
350                 {
351                         // TODO: Implement me
352                         return new DateTime (0);
353                 
354                 }
355
356                 public static DateTime ParseExact( string s, string[] formats, IFormatProvider provider, DateTimeStyles style )
357                 {
358                         // TODO: Implement me
359                         return new DateTime (0);
360                 
361                 }
362                 
363                 public TimeSpan Subtract(DateTime dt )
364                 {   //TODO : implement me
365                         return new TimeSpan(ticks - dt.ticks );
366                 }
367
368                 public DateTime Subtract(TimeSpan ts)
369                 {       // TODO : implement me 
370                         return new DateTime(ticks - ts.Ticks );
371                 }
372
373                 public long ToFileTime()
374                 {
375                                 // TODO: Implement me
376                         return 0 ;
377                 }
378
379                 public DateTime ToLocalTime()
380                 {
381                         // TODO Implement me 
382                         return new DateTime (0);
383                 }
384
385                 public string ToLongDateString()
386                 {
387                         // TODO implement me 
388                         return "";
389                 }
390
391                 public string ToLongTimeString()
392                 {
393                         // TODO implement me 
394                         return "";
395                 }
396
397                 public double ToOADate()
398                 {
399                         // TODO implement me 
400                         return 0;
401                 }
402
403                 public string ToShortDateString()
404                 {
405                         // TODO implement me 
406                         return "";
407                 }
408
409                 public string ToShortTimeString()
410                 {
411                         // TODO implement me
412                         return "";
413                 }
414         
415
416                 public override string ToString ()
417                 {
418                         // TODO: Implement me
419
420                         return "";
421                 }
422
423                 public string ToString (IFormatProvider fp)
424                 {
425                         // TODO: Implement me.
426                         return "";
427                 }
428
429                 public string ToString (string format)
430                 {
431                         // TODO: Implement me.
432                         return "";
433                 }
434
435                 public string ToString (string format, IFormatProvider fp)
436                 {
437                         // TODO: Implement me.
438                         return "";
439                 }
440
441                 public DateTime ToUniversalTime()
442                 {
443                         // TODO: implement me 
444                         return new DateTime(0);
445                 }
446
447                 /*  OPERATORS */
448
449                 public static DateTime operator +( DateTime d,  TimeSpan t )
450                 {
451                         return new DateTime (d.ticks + t.Ticks );
452                 }
453
454                 public static bool operator ==( DateTime d1, DateTime d2 )
455                 {
456                         return (d1.ticks == d2.ticks );
457                 }
458
459                 public static bool operator >(DateTime t1,DateTime t2)
460                 {
461                         return (t1.ticks > t2.ticks );
462                 }
463
464                 public static bool operator >=( DateTime t1,DateTime t2 )
465                 {
466                         return (t1.ticks >= t2.ticks);
467                 }
468
469                 public static bool operator !=( DateTime d1, DateTime d2)
470                 {
471                         return (d1.ticks != d2.ticks );
472                 }
473
474                 public static bool operator <( DateTime t1,     DateTime t2     )
475                 {
476                         return (t1.ticks < t2.ticks );
477                 }
478
479                 public static bool operator <=( DateTime t1,DateTime t2 )
480                 {
481                         return (t1.ticks <= t2.ticks );
482                 }
483
484                 public static TimeSpan operator -(DateTime d1,DateTime d2)
485                 {
486                         return new TimeSpan(d1.ticks - d2.ticks );
487                 }
488
489                 public static DateTime operator -(DateTime d,TimeSpan t )
490                 {
491                         return new DateTime (d.ticks - t.Ticks );
492                 }
493
494
495
496                 private static long AbsoluteDays (int year, int month, int day)
497                 {
498                         int[] days = new int[13] { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; 
499                         int temp = 0, m=1 ;
500                 
501                         if (IsLeapYear(year))
502                                 days[2] = 29;
503                         while (m < month)
504                                 temp += days[m++];
505                         return ((day-1) + temp + (365* (year-1)) + ((year-1)/4) - ((year-1)/100) + ((year-1)/400));
506                         
507                 }
508
509                 private  int FromTicks(Which what)
510                 {
511                         const int dp400 = 146097;
512                         const int dp100 = 36524;
513                         const int dp4 = 1461;
514                 
515                         int[] days = new int[13] { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; 
516                         int totaldays = (int) (ticks / TimeSpan.TicksPerDay );
517                 
518                         int num400 = (totaldays / dp400);
519                         totaldays -=  num400 * dp400;
520                 
521                         int num100 = (totaldays / dp100);
522                         if (num100 == 4)   // leap
523                                 num100 = 3;
524                         totaldays -= (num100 * dp100);
525
526                         int num4 = totaldays / dp4;
527                         totaldays -= (num4 * dp4);
528
529                         int numyears = totaldays / 365 ;
530                         
531                         if (numyears == 4)  //leap
532                                 numyears =3 ;
533                         if (what == Which.Year )
534                                 return num400*400 + num100*100 + num4*4 + numyears + 1;
535
536                         totaldays -= (numyears * 365) ;
537                         if (what ==Which.DayYear )
538                                 return totaldays + 1;
539                         
540                         if  ((numyears==3) && ((num100 == 3) || !(num4 == 24)) ) //31 dec leapyear
541                                 days[2] = 29;
542                 
543                 
544                         int M =1;
545                         while (totaldays >= days[M])
546                                 totaldays -= days[M++];
547
548                         if (what == Which.Month )
549                                 return M;
550
551                         return totaldays +1;
552                 }
553
554         }
555 }
556 namespace System
557 {
558         public enum DayOfWeek
559         {
560                 Sunday,
561                 Monday,
562                 Tuesday,
563                 Wednesday,
564                 Thursday,
565                 Friday,
566                 Saturday
567         }
568 }
569
570