Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.275 Beiträge
Delphi 10.4 Sydney
|
AW: Wann beginnt bei einem Jahr x die Sommerzeit ?
13. Jan 2014, 18:28
Hallo,
ich hole mir nichts aus Windows.
Die Einstellungen werden vom Nutzer konfiguriert.
Da unser Produkt nur in good old Germany läuft, kann ich mir das leisten
Delphi-Quellcode:
function ErmitteltLetztenSonntagDesMonats(const AJahr, AMonat: Word): TDateTime;
const
C_So = 7;
var
tdtDatum : TDateTime;
begin
Result := 0.0;
{ Start = letzter Tag des Monats }
tdtDatum := EncodeDate(AJahr, AMonat, DaysInAMonth(AJahr, AMonat));
if DayOfTheWeek(tdtDatum)=C_So then
begin
Result := tdtDatum;
end
else
begin
repeat
tdtDatum := tdtDatum-1.0;
if DayOfTheWeek(tdtDatum)=C_So then
begin
Result := tdtDatum;
break;
end;
until False;
end;
end { ErmitteltLetztenSonntagDesMonats } ;
procedure ErmittleSommerzeit(const AJahr: Word; out tdtStart, tdtEnde: TDateTime);
begin
tdtStart := ErmitteltLetztenSonntagDesMonats(AJahr, 3);
tdtEnde := ErmitteltLetztenSonntagDesMonats(AJahr, 10);
end { ErmittleSommerzeit } ;
{*
Zeit nach GMT (Greenwich Mean Time) konvertieren
in der Sommerzeit wird eine Stunde abgezogen
@param ADateTime gegebenes Datum/Uhrzeit
@return GMT-Zeit
}
function DateTimeNachGMT(const ADateTime: TDateTime): TDateTime;
var
wJahr : Word;
wDummy : Word;
tdtDatum : TDateTime;
tdtSommerzeitStart : TDateTime;
tdtSommerzeitEnde : TDateTime;
begin
DecodeDate(ADateTime, wJahr, wDummy, wDummy);
tdtDatum := DateOf(ADateTime);
ErmittleSommerzeit(wJahr, tdtSommerzeitStart, tdtSommerzeitEnde);
if (tdtDatum>=tdtSommerzeitStart) and
(tdtDatum<=tdtSommerzeitEnde) then
begin
Result := IncHour(ADateTime, -1);
end
else
begin
Result := ADateTime;
end;
end { DateTimeNachGMT } ;
procedure TTestCaseX.ErmittleSommerzeit;
var
wJahr : Word;
tdtStart : TDateTime;
tdtEnde : TDateTime;
begin
wJahr := 2000;
MyDateUtils.ErmittleSommerzeit(wJahr, tdtStart, tdtEnde);
Check(tdtStart=EncodeDate(2000,3,26));
Check(tdtEnde=EncodeDate(2000,10,29));
wJahr := 2014;
MyDateUtils.ErmittleSommerzeit(wJahr, tdtStart, tdtEnde);
Check(tdtStart=EncodeDate(2014,3,30));
Check(tdtEnde=EncodeDate(2014,10,26));
end;
procedure TTestCaseX.DateTimeNachGMT;
var
tdtDateTime1 : TDateTime;
tdtDateTime2 : TDateTime;
tdtDateTime3 : TDateTime;
begin
{ vor der Sommerzeit }
tdtDateTime1 := EncodeDate(2000,3,25)+EncodeTime(22,0,0,0);
tdtDateTime2 := MyDateUtils.DateTimeNachGMT(tdtDateTime1);
Check(tdtDateTime2=tdtDateTime1);
{ erster Tag der Sommerzeit }
tdtDateTime1 := EncodeDate(2000,3,26)+EncodeTime(22,0,0,0);
tdtDateTime2 := MyDateUtils.DateTimeNachGMT(tdtDateTime1);
tdtDateTime3 := EncodeDate(2000,3,26)+EncodeTime(21,0,0,0);
Check(tdtDateTime2=tdtDateTime3);
{ vorletzter Tag der Sommerzeit }
tdtDateTime1 := EncodeDate(2000,10,28)+EncodeTime(22,0,0,0);
tdtDateTime2 := MyDateUtils.DateTimeNachGMT(tdtDateTime1);
tdtDateTime3 := EncodeDate(2000,10,28)+EncodeTime(21,0,0,0);
Check(tdtDateTime2=tdtDateTime3);
{ letzter Tag der Sommerzeit }
tdtDateTime1 := EncodeDate(2000,10,29)+EncodeTime(22,0,0,0);
tdtDateTime2 := MyDateUtils.DateTimeNachGMT(tdtDateTime1);
tdtDateTime3 := EncodeDate(2000,10,29)+EncodeTime(21,0,0,0);
Check(tdtDateTime2=tdtDateTime3);
{ erster Tag der Winterzeit }
tdtDateTime1 := EncodeDate(2000,10,30)+EncodeTime(22,0,0,0);
tdtDateTime2 := MyDateUtils.DateTimeNachGMT(tdtDateTime1);
tdtDateTime3 := EncodeDate(2000,10,30)+EncodeTime(22,0,0,0);
Check(tdtDateTime2=tdtDateTime3);
end { DateTimeNachGMT } ;
Die Performance-"Problem" mit der Schleife sind verglichen mit dem Code,
der noch dahintersteckt, minimal.
Unit-Tests laufen über DUnit.
Ich habe das gekürzt:
Check(tdtDateTime2=tdtDateTime3); heisst eigentlich Check(tdtDateTime2=tdtDateTime3, 'Fehler XXX'); usw.
Heiko
Heiko
Geändert von hoika (13. Jan 2014 um 18:32 Uhr)
|