## 14.4 Der Typ »DateTime« Um ein Datum einschließlich einer Zeitangabe in einer Variablen zu speichern, deklarieren Sie die Variable vom Typ DateTime, beispielsweise:
    DateTime myDate  = new DateTime(2003, 12, 6);
    Console.WriteLine(myDate);
Die Ausgabe wird lauten:
    06.12.2003  00:00:00
Mit einer Variablen des Typs DateTime lässt sich ein Datum zwischen dem 1. Januar 01 und dem 31. Dezember 9999 behandeln – nach dem gregorianischen Kalender, um präzise zu sein. ### 14.4.1 Zeitspanne »Tick« Die Zeitmessung erfolgt in Einheiten von 100 Nanosekunden, die als Tick bezeichnet werden. Diese Aussage muss man sich auf der Zunge zergehen lassen: Die .NET-Zeitmessung beginnt am 1.1.0001 um 0:00 Uhr, und es können Intervalle von 0.0000001 Sekunden (in Worten: ein Zehnmillionstel) unterschieden werden. Die Anzahl der Ticks seit Beginn dieser Zeitrechnung kann in einem long gespeichert werden, der groß genug ist, um damit alle Intervalle bis zum Ende des Jahres 9999 abdecken zu können. Wenn Sie das aktuelle Datum und die aktuelle Zeit in Ticks ausgedrückt sehen wollen, dann geben Sie den folgenden Code ein:
    Console.WriteLine(DateTime.Now.Ticks);
Zuerst rufen Sie die statische Methode Now auf, die das aktuelle Systemdatum einschließlich der Zeit als DateTime zurückliefert. Darauf wird die Eigenschaft Ticks angewendet, die Ihnen eine kaum noch fehlerfrei abschreibbare Zahl liefert. Umgekehrt können Sie natürlich auch aus einem long, der als Tick interpretiert werden soll, das Datum und die Zeit ermitteln. Dazu wird die Klasse DateTime instanziiert und dabei ein Konstruktor aufgerufen, der einen long erwartet, der als die Anzahl der Ticks seit Beginn der .NET-Zeitrechnung interpretiert wird.
    DateTime actualDate = new DateTime(631452984963219664);
    Console.WriteLine(actualDate.ToString());
Die Ausgabe lautet:
    30.12.2001 08:41:36
Sie haben jetzt einen ersten Eindruck vom Umgang mit Datum und Uhrzeit gewonnen. Wir wollen uns nun die Details der Klasse DateTime ansehen. ### 14.4.2 Konstruktoren von »DateTime« Wenn Ihnen die Anzahl der Ticks vorliegt, genügt der einparametrige Konstruktor, um ein Objekt zu erzeugen:
    public DateTime(long ticks);
Da in den meisten Fällen vermutlich kaum die Anzahl der Tick-Intervalle bekannt sein dürfte, kommt diesem Konstruktor geringe Bedeutung zu. Wollen Sie mit einem bestimmten Datum operieren, bei dem die Uhrzeit keine Rolle spielt, bietet sich der folgende Konstruktor an:
    public DateTime (int year, int month, int day);
Den Parametern wird das Jahr, der Monat und der Tag jeweils als int übergeben. Dabei ist die Jahresangabe auf die Zahlen zwischen einschließlich 1 und 9999 begrenzt, die Monatsangabe natürlich auf 1 bis 12, und die Anzahl der Tage hängt vom Kalendermonat ab. Da bei diesem Konstruktor auf die Zeitangabe verzichtet wird, bezieht sich das Datum immer auf Mitternacht, also exakt 0:00 Uhr. Im folgenden Beispiel setzen wir diesen Konstruktor ein, um das Datum 12. Mai 1965 abzubilden, und lassen uns an der Konsole die Ticks ausgeben, die dieser Angabe entsprechen:
    DateTime myDate = new DateTime(1965, 5, 12);
    Console.WriteLine("Datum: {0}", myDate);
    Console.WriteLine("Ticks: {0}", myDate.Ticks);
Für eine Präzisierung durch eine zusätzliche Zeitangabe stehen zwei Konstruktoren zur Verfügung. Während der erste zusätzlich zu der Angabe des Datums in drei weiteren Parametern Stunde, Minute und Sekunde entgegennimmt, kann dem anderen in einem siebten Parameter die Anzahl der Millisekunden übergeben werden:
    public DateTime (int year, int month, int day, int h, int min, int sec);
    public DateTime (int year, int month, int day, int h, int min, int sec,
                     int msec);
Für jeden dieser Konstruktoren gibt es noch eine weitere Überladung, die um eine Referenz vom Typ System.Globalization.Calendar ergänzt ist. Damit kann man gegebenenfalls das Kalenderformat vom gregorianischen Kalender auf einen anderen umschalten. Mit DateTime können Sie auch festlegen, auf welcher Basis die Zeitangabe erfolgt. Dazu gibt es drei Möglichkeiten: Die Zeitangabe bezieht sich auf die lokale Systemzeit. Die Zeitangabe legt die koordinierte Weltzeit (UTC) zugrunde. Die Zeitangabe ist nicht genau spezifiziert. Die Festlegung muss bereits bei der Instanziierung erfolgen. Dazu stehen einige Konstruktoren zur Verfügung, denen ein Argument vom Typ DateTimeKind übergeben wird. Bei DateTimeKind handelt es sich um eine Enumeration mit den Elementen Local, Unspecified und Utc. Der Standard ist Unspecified.
    public DateTime (long ticks, DateTimeKind kind);
Liegt ein DateTime-Objekt vor, lässt sich die Zeitbasis nicht mehr verändern. Sie können die Einstellung jedoch mit der Eigenschaft Kind jederzeit auswerten. ### 14.4.3 Eigenschaften von »DateTime« Liegt ein gültiges Datum vor, lassen sich daraus vom Jahr bis zu den Millisekunden sämtliche Informationen extrahieren. Die Namen der Eigenschaften sind sehr einprägsam: Year, Month, Day, Hour, Minute, Second und Millisecond. Nehmen wir an, wir wollen das aktuelle Systemdatum, das wir mit der Eigenschaft Now ermitteln können, in seine Detailinformationen zerlegen, dann könnte das so erfolgen:
    DateTime newDate = DateTime.Now;
    Console.WriteLine("Jahr      = {0}", newDate.Year);
    Console.WriteLine("Monat     = {0}", newDate.Month);
    Console.WriteLine("Tag       = {0}", newDate.Day);
    Console.WriteLine(" ({0})", newDate.DayOfWeek.ToString());
    Console.WriteLine("Stunde    = {0}", newDate.Hour);
    Console.WriteLine("Minute    = {0}", newDate.Minute);
    Console.WriteLine("Sekunde   = {0}", newDate.Second);
    Console.WriteLine("MilliSek. = {0}", newDate.Millisecond);
Weil die Ausgabe der Eigenschaft Day nur das aktuelle Tagesdatum liefert, ohne den Wochentag anzugeben, bietet sich eine weitere Eigenschaft von DateTime an, die aus einem gegebenen Datum sogar den Wochentag ermittelt: DayOfWeek. Der Rückgabewert ist vom Typ DayOfWeek, einer Enumeration des System-Namespace, die für den Sonntag 0 festlegt, für Montag 1 usw. Mit dem Aufruf von ToString auf DayOfWeek erhalten wir die Zeichenfolge, die der Konstanten entspricht. Bedauerlich ist, dass es keine gleichwertige Auflistung für die Monate gibt. Wenn Sie daher auch den Monatsnamen in der Ausgabe als Text und nicht nur als Zahl lesen wollen, müssen Sie die Zahlen 1–12 selbst den Monatsnamen zuordnen, beispielsweise mittels eines switch-Statements. Now liefert die aktuelle Systemzeit und hängt damit unter Windows-Plattformen von der Einstellung in der Systemsteuerung ab. Eine sehr ähnliche Eigenschaft ist UtcNow, die aus den Einstellungen in der Systemsteuerung die Greenwich Mean Time (GMT) ermittelt. Wenn auf die Zeitangabe, die uns Now liefert, verzichtet werden kann oder muss, können Sie auch auf die statische Eigenschaft Today zurückgreifen, die das Datum ohne Zeitangabe liefert. Diese wird auf 00:00:00 gesetzt. ### 14.4.4 Methoden der Klasse »DateTime« Nahezu alle Methoden lassen sich in zwei operativen Gruppen zusammenfassen: Methoden, die der Ausgabeformatierung dienen in der Gruppe der Add-Methoden, mit der zu einem gegebenen Datum eine Zeitspanne addiert oder subtrahiert werden kann #### Allgemeine Methoden Mit insgesamt vier vordefinierten Methoden lässt sich die Textausgabe eines DateTime-Objekts verändern: ToLongDateString und ToShortDateString ToLongTimeString und ToShortTimeString Wir können den Effekt dieser Methoden am besten anhand von Beispielen sehen. Dazu deklarieren wir eine Variable vom Typ DateTime und führen darauf alle vier Methoden aus:
    // Datum = 3.Februar 2006 5:25:30
    DateTime myDate = new DateTime(2006, 2, 3, 5, 25, 30);
    Console.WriteLine(myDate.ToLongDateString());
    // Ausgabe: Mittwoch, 3. Februar 2006
    Console.WriteLine(myDate.ToShortDateString());
    // Ausgabe: 03.02.2006
    Console.WriteLine(myDate.ToLongTimeString());
    // Ausgabe: 05:25:30
    Console.WriteLine(myDate.ToShortTimeString());
    // Ausgabe: 05:25
Weitaus interessanter als diese Formatmethoden ist eine andere, die ihre Leistungsfähigkeit erst auf den zweiten Blick offenbart: ToFileTime.
    public long ToFileTime();
Der Rückgabewert vom Typ long enthält die Anzahl der Ticks seit dem 1. Januar 1601, 12 Uhr. Welchen Hintergrund diese scheinbar zufällige Jahreszahl hat, verrät uns die Dokumentation nicht. Das soll uns aber auch nicht weiter interessieren, viel wichtiger ist die Tatsache, dass wir mit dieser Methode ein Mittel in den Händen halten, das es uns ermöglicht, die Zeitspanne zwischen zwei Ereignissen zu messen – und dafür brauchen wir einen präzise definierten, gleichermaßen gültigen Ursprung, egal wie er definiert ist. #### Rechenoperationen mit »DateTime«-Objekten Die Add-Methoden decken alle Bedürfnisse hinsichtlich der Änderung eines Datums oder einer Zeit ab. Aus dem Bezeichner ist sofort zu erkennen, welche Einheit zu einem DateTime-Objekt addiert werden soll: AddDays AddHours AddMonths ... Allen Methoden wird ein Wert vom Typ int bzw. double übergeben, und der Rückgabewert ist vom Typ DateTime, zum Beispiel:
    public DateTime AddSeconds(double);
Im folgenden Codefragment wird ein DateTime-Objekt erzeugt, das das Datum 2. August 1995 und die Zeit 23:00 Uhr beschreibt. Davon werden mit der Methode AddHours 30 Stunden subtrahiert:
    DateTime now = new DateTime(1995, 8, 2, 23, 0, 0);
    now = now.AddHours(-30);
    Console.WriteLine(now);
An der Konsole wird
    01.08.1995 17:00:00