Die Klasse Time

1. Aufgabe

Unser erstes Beispiel befasst sich mit einem Datentyp, der Ihnen im Alltag häufig begegnet. Es ist die Rede von einer Uhrzeit, also einem Wert, der aus Stunden, Minuten und Sekunden besteht. Im Prinzip kann man sich ein Objekt dieses Typs aus drei int-Variablen zusammengesetzt vorstellen: einer hour-Variablen, die Werte zwischen 0 und 23 einnimmt, einer minute-Variablen mit Werten zwischen 0 und 59 sowie einer second-Variablen desselben Wertebereichs. Neben geeigneten Konstruktoren und getter- und setter-Methoden sollte die Klasse Time die in Tabelle 1 aufgeführten Methoden unterstützen:

Methode

Beschreibung

Add

public void Add(int second, int minute, int hour);
public void Add(Time time);

Addiert die übergebenen Stunden, Minuten und Sekunden zur aktuellen Uhrzeit. Ein möglicher Überlauf (Uhrzeit größer 23:59:59) ist entsprechend umzurechnen.

Sub

public void Sub(int second, int minute, int hour);
public void Sub(Time time);

Subtrahiert die übergebenen Stunden, Minuten und Sekunden von der aktuellen Uhrzeit. Ein möglicher Unterlauf (Uhrzeit kleiner 00:00:00) ist entsprechend umzurechnen.

Increment

Decrement

public void Increment();
public void Decrement();

Erhöht bzw. erniedrigt die aktuelle Uhrzeit um eine Sekunde.

LessThan

public bool LessThan(Time time);

Vergleich zweier Uhrzeiten. Ist die aktuelle Uhrzeit kleiner oder gleich als die übergebene, wird true zurückzugeben, andernfalls false.

Equals

public bool Equals(Time time);

Vergleich zweier Uhrzeiten auf Gleichheit.

Diff

public Time Diff(Time time);

Berechnet den zeitlichen Abstand zweier Uhrzeiten. Die Differenz ist wiederum als Objekt des Typs Time zurückzugeben.

Reset

public void Reset (int hour, int minute, int second);

Eine Uhrzeit mit den aktuellen Parametern neu setzen.

Print

public void Print ();

Gibt eine Instanz der Klasse Time auf der Konsole im Format hh:mm:ss aus.

Tabelle 1. Methoden der Klasse Time.


Implementieren Sie die Klasse Time und testen Sie ihre Methoden mit einem geeigneten Testrahmen. Möglicherweise ergibt es Sinn, die Klasse Time bei ihrer Realisierung um weitere Hilfsmethoden zu ergänzen, die nur innerhalb der Klasse zur Verfügung stehen. Einige Anregungen hierzu können Sie Tabelle 2 entnehmen:

Methode

Beschreibung

TimeToSeconds

private int TimeToSeconds();

Rechnet das aktuell vorliegende Uhrzeitobjekt in Sekunden um.

SecondsToTime

private void SecondsToTime(int seconds);

Ermittelt zu einem vorgegebenen Sekundenwert (Parameter seconds) eine Uhrzeit.

Tabelle 2. Optionale Hilfsmethoden der Klasse Time.

2. Lösung

Da wir eine Reihe von C#-Sprachelementen noch nicht betrachtet haben, ist die Lösung in Listing 1 nur als Zwischenstufe zu sehen. Sie ist also ausschließlich mit sehr elementaren C#-Sprachkonstrukten erstellt:

001: class Time
002: {
003:     // member data
004:     private int second;
005:     private int minute;
006:     private int hour;
007: 
008:     // c'tors
009:     public Time()
010:     {
011:         // default c'tor
012:         this.second = 0;
013:         this.minute = 0;
014:         this.hour = 0;
015:     }
016: 
017:     public Time(int second, int minute, int hour)
018:     {
019:         // user-defined c'tor
020:         this.second = (0 <= second && second < 60) ? second : 0;
021:         this.minute = (0 <= minute && minute < 60) ? minute : 0;
022:         this.hour = (0 <= hour && hour < 24) ? hour : 0;
023:     }
024: 
025:     public Time(int seconds) : this()
026:     {
027:         if (0 <= seconds && seconds <= 24 * 60 * 60)
028:         {
029:             this.SecondsToTime(seconds);
030:         }
031:     }
032: 
033:     // properties
034:     public int Second
035:     {
036:         get
037:         {
038:             return this.second;
039:         }
040: 
041:         set
042:         {
043:             this.second = (0 <= value && value < 60) ? value : 0;
044:         }
045:     }
046: 
047:     public int Minute
048:     {
049:         get
050:         {
051:             return this.minute;
052:         }
053: 
054:         set
055:         {
056:             this.minute = (0 <= value && value < 60) ? value : 0;
057:         }
058:     }
059: 
060:     public int Hour
061:     {
062:         get
063:         {
064:             return this.hour;
065:         }
066: 
067:         set
068:         {
069:             this.hour = (0 <= value && value < 24) ? value : 0;
070:         }
071:     }
072: 
073:     public int Seconds
074:     {
075:         get
076:         {
077:             return this.TimeToSeconds();
078:         }
079:     }
080: 
081:     // public interface
082:     public void Reset()
083:     {
084:         this.second = 0;
085:         this.minute = 0;
086:         this.hour = 0;
087:     }
088: 
089:     public void Add(int second, int minute, int hour)
090:     {
091:         this.second += second;
092:         this.minute += minute;
093:         this.hour += hour;
094: 
095:         // normalize object
096:         this.minute += this.second / 60;
097:         this.hour += this.minute / 60;
098:         this.second = this.second % 60;
099:         this.minute = this.minute % 60;
100:         this.hour = this.hour % 24;
101:     }
102: 
103:     public void Add(Time time)
104:     {
105:         this.Add(time.second, time.minute, time.hour);
106:     }
107: 
108:     public void Sub(int second, int minute, int hour)
109:     {
110:         int seconds =
111:             this.TimeToSeconds() -
112:             (hour * 3600 + minute * 60 + second);
113: 
114:         if (seconds < 0)
115:             seconds += 24 * 60 * 60;
116: 
117:         // transform total seconds into hour, minutes and seconds
118:         this.SecondsToTime(seconds);
119:     }
120: 
121:     public void Sub(Time time)
122:     {
123:         this.Sub(time.second, time.minute, time.hour);
124:     }
125: 
126:     public Time Diff(Time time)
127:     {
128:         Time tmp;
129:         if (this.LessThan(time) || this.Equals(time))
130:         {
131:             tmp = new Time(time.second, time.minute, time.hour);
132:             tmp.Sub(this);
133:         }
134:         else
135:         {
136:             tmp = new Time(this.second, this.minute, this.hour);
137:             tmp.Sub(time);
138:         }
139: 
140:         return tmp;
141:     }
142: 
143:     public void Increment()
144:     {
145:         this.second++;
146:         if (this.second >= 60)
147:         {
148:             this.second = 0;
149:             this.minute++;
150:             if (this.minute >= 60)
151:             {
152:                 this.minute = 0;
153:                 this.hour++;
154:                 if (this.hour >= 24)
155:                 {
156:                     this.hour = 0;
157:                 }
158:             }
159:         }
160:     }
161: 
162:     public void Decrement()
163:     {
164:         this.second--;
165:         if (this.second < 0)
166:         {
167:             this.second = 59;
168:             this.minute--;
169:             if (this.minute < 0)
170:             {
171:                 this.minute = 59;
172:                 this.hour--;
173:                 if (this.hour < 0)
174:                 {
175:                     this.hour = 23;
176:                 }
177:             }
178:         }
179:     }
180: 
181:     // comparison methods
182:     public bool LessThan(Time time)
183:     {
184:         if (this.hour < time.hour)
185:             return true;
186: 
187:         if (this.hour == time.hour && this.minute < time.minute)
188:             return true;
189: 
190:         if (this.hour == time.hour &&
191:             this.minute == time.minute &&
192:             this.second < time.second)
193:                 return true;
194: 
195:         return false;
196:     }
197: 
198:     public bool Equals(Time time)
199:     {
200:         return
201:             this.second == time.second &&
202:             this.minute == time.minute &&
203:             this.hour == time.hour;
204:     }
205: 
206:     // console output
207:     public void Print()
208:     {
209:         Console.WriteLine("{0:00}:{1:00}:{2:00}",
210:             this.hour, this.minute, this.second);
211:     }
212: 
213:     // helper methods
214:     private int TimeToSeconds()
215:     {
216:         return this.hour * 3600 + this.minute * 60 + this.second;
217:     }
218: 
219:     private void SecondsToTime(int seconds)
220:     {
221:         this.hour = seconds / 3600;
222:         seconds = seconds % 3600;
223:         this.minute = seconds / 60;
224:         this.second = seconds % 60;
225:     }
226: }

Beispiel 1. Eine Implementierung der Klasse Time.


Formatspezifizierer wie etwa "{0:00}" (siehe Zeile 209 von Listing 1) bewirken, dass für die Ausgabe einer ganzen Zahl zwei Stellen verwendet werden und Zahlen kleiner 10 mit einer führenden Null ausgegeben werden. Wir schließen den Lösungsabschnitt mit zwei Beispielen zur Klasse Time ab:

Beispiel:

public static void Main()
{
    // testing 'Add'
    Time t1 = new Time(0, 0, 12);
    Time t2 = new Time(33, 33, 3);

    for (int i = 0; i < 5; i++)
    {
        t1.Add(t2);
        t1.Print();
    }
}

Ausgabe:

15:33:33
19:07:06
22:40:39
02:14:12
05:47:45

Die Diff-Methode wird durch das folgende Beispiel getestet:

Beispiel:

public static void Main()
{
    // testing 'Diff'
    Time t1 = new Time();
    Time t2 = new Time(59, 59, 23);
    Time t3 = t1.Diff(t2);
    t3.Print();
    t3 = t2.Diff(t1);
    t3.Print();
}

Ausgabe:

23:59:59
23:59:59