					   // Kapitel 5 - Programm 11 - DATUM.CPP

// Diese Datei enthält die Implementation der Klasse Datum.

#include <stdio.h>	 // Prototyp für sprintf
#include <time.h>        // Prototypen für das aktuelle Datum
#include "datum.h"

char Datum::Format;		// Definition des statischen Datenelements
char Datum::AusStrom[25];	// Definition der statischen Zeichenkette

	// Konstruktor - Setze das Datum auf das aktuelle Datum
	//		     und das Format auf 1
Datum::Datum(void)
{
time_t ZeitDatum;
struct tm *AktuellesDatum;

   ZeitDatum = time(NULL);				// Systemaufruf
   AktuellesDatum = localtime(&ZeitDatum);	// Systemaufruf
   Monat = AktuellesDatum->tm_mon + 1;
   Tag = AktuellesDatum->tm_mday;
   Jahr = AktuellesDatum->tm_year + 1900;
   Format = 1;
}

	// Setze das Datum auf diese Parameter
	//  Rückgabewert = 0 ---> Alle Daten ok
	//  Rückgabewert = 1 ---> Etwas außerhalb des Erlaubten
int Datum::SetzeDatum(int EinMonat, int EinTag, int EinJahr)
{
int Temp = 0;
int MaxTage;
			// Die Einschränkung beim Jahr ist willkürlich
   if (EinJahr < 1500)		     // Sicherstellen, daß das Jahr zwischen
   {	Jahr = 1500;		     //  1500 und 2200 liegt
	Temp = 1;
   }
   else
   {
	if (EinJahr > 2200)
	{
	   Jahr = 2200;
	   Temp = 1;
	}
	else
	{
	   Jahr = EinJahr;
	}
   }

   if(EinMonat < 1)		     // Sicherstellen, daß das Monat zwischen
   {					     //  1 und 12 liegt
	Monat = Temp = 1;
   }
   else
   {
	if (EinMonat > 12)
	{
	   Monat = 12;
	   Temp = 1;
	}
	else
	{
	   Monat = EinMonat;
	}
   }

   MaxTage = TageImMonat();
   if (EinTag < 1)		     // Sicherstellen, daß der Tag zwischen
   {					     //  1 und MaxTage liegt
	Tag = Temp = 1;
   }
   else
   {
	if (EinTag > MaxTage)
	{
	   Tag = MaxTage;
	   Temp = 1;
	}
	else
	{
	   Tag = EinTag;
	}
   }

   return Temp;
}

static char *MonatsName[13] = {" ", "Jan", "Feb", "Mar", "Apr",
						  "Mai", "Jun", "Jul", "Aug",
						  "Sep", "Okt", "Nov", "Dez"};

	// Gib Jan Feb Mar Apr etc. zurück
char *Datum::HoleMonatsName(void)
{
   return MonatsName[Monat];
}

	// Gib eine ASCII-Z Zeichenfolge mit dem gespeicherten Fromat zurück
	//   Format = 1	Aug 29, 1991
	//   Format = 2	29.8.91
	//   Format = 3	29.8.1991
	//   Format = 4	29 Aug 1991       Militärsiche Zeit
	//   Format = ?	Alles andere wird als Format 1 interpretiert
char *Datum::HoleFormatiertesDatum(void)
{
   switch (Format)
   {				// Diese Ausgabe nimmt an, dass das Jahr
				// zwischen 1970 und 2069 liegt
	case 2  : sprintf(AusStrom, "%02d.%02d.%02d",
							  Tag, Monat, Jahr - 1970);
		    break;

	case 3  : sprintf(AusStrom, "%02d.%02d.%04d",
								   Tag, Monat, Jahr);
		    break;

	case 4  : sprintf(AusStrom, "%d %s %04d",
						   Tag, MonatsName[Monat], Jahr);
		    break;

	case 1  : // Weiter zu default
	default : sprintf(AusStrom, "%s %d, %04d",
						   MonatsName[Monat], Tag, Jahr);
		    break;
   }
   return AusStrom;
}

int Tage[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

	// Da dies im privaten Teil der header-Datei deklariert wurde
	//  kann es nur innerhalb der Klasse verwendet werden.
	//  Es ist vor der Außenwelt versteckt.
int Datum::TageImMonat(void)
{
   if (Monat != 2)
	return Tage[Monat];

   if (Jahr % 4)	     // Kein Schaltjahr
	return 28;
   if (Jahr % 100)     // Schaltjahr
	return 29;
   if (Jahr % 400)     // Kein Schaltjahr
	return 28;
   return 29;	     // Schaltjahr
}
