Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.153 Beiträge
 
Delphi 12 Athens
 
#6

AW: Wann beginnt bei einem Jahr x die Sommerzeit ?

  Alt 10. Jan 2014, 20:08
So?

siehe erstes IF im ConvertDate

Delphi-Quellcode:
uses
  Windows, SysUtils, DateUtils, Math;

type
  TTimeZoneInformationHelper = record helper for TTimeZoneInformation
  public const
    CurrentYear = 0;
    NextDates = 1;
  private
    procedure ConvertDate(var Date: TSystemTime; IsDaylight, DoNextDates: Boolean; RelDate: TSystemTime);
    function GetDate(Index: Integer): TDateTime;
    function GetDateStr(Index: Integer): string;
  public
    procedure ReadInfo(Year: Word=NextDates; DoConvertDates: Boolean=True);
    procedure ConvertDates(DoNextDates: Boolean=False); overload;
    procedure ConvertDates(DoNextDates: Boolean; RelDate: TSystemTime); overload;

    property GetStandardDate: TDateTime index 0 read GetDate;
    property GetDaylightDate: TDateTime index 1 read GetDate;
    property GetStandardDateStr: string index 0 read GetDateStr;
    property GetDaylightDateStr: string index 1 read GetDateStr;
  end;

{ TTimeZoneInformationHelper }

procedure TTimeZoneInformationHelper.ConvertDate(var Date: TSystemTime; IsDaylight, DoNextDates: Boolean; RelDate: TSystemTime);
var
  NextZone: TTimeZoneInformation;
  NewDate: TDateTime;
begin
  if Date.wYear = 0 then begin
    Date.wYear := RelDate.wYear;
    if Date.wDay < 5 then
      Date.wDay := DayOf(EncodeDayOfWeekInMonth(Date.wYear, Date.wMonth, Date.wDay, IfThen(Date.wDayOfWeek = 0, 7, Date.wDayOfWeek)))
    else begin
      NewDate := EncodeDayOfWeekInMonth(Date.wYear, Date.wMonth, 1, IfThen(Date.wDayOfWeek = 0, 7, Date.wDayOfWeek));
      while MonthOf(NewDate) = MonthOf(IncWeek(NewDate)) do
        NewDate := IncWeek(NewDate);
      Date.wDay := DayOf(NewDate);
    end;
  end;
  if DoNextDates and (SystemTimeToDateTime(RelDate) > SystemTimeToDateTime(Date)) then begin
    NextZone.ReadInfo(RelDate.wYear + 1, True);
    if IsDaylight then
      Date := NextZone.DaylightDate
    else
      Date := NextZone.StandardDate;
  end;
end;

procedure TTimeZoneInformationHelper.ConvertDates(DoNextDates: Boolean);
var
  Current: TSystemTime;
begin
  GetLocalTime(Current);
  ConvertDates(DoNextDates, Current);
end;

procedure TTimeZoneInformationHelper.ConvertDates(DoNextDates: Boolean; RelDate: TSystemTime);
begin
  ConvertDate(Self.StandardDate, False, DoNextDates, RelDate);
  ConvertDate(Self.DaylightDate, True, DoNextDates, RelDate);
end;

function TTimeZoneInformationHelper.GetDate(Index: Integer): TDateTime;
begin
  if Index = 0 then
    Result := SystemTimeToDateTime(Self.StandardDate)
  else
    Result := SystemTimeToDateTime(Self.DaylightDate);
end;

function TTimeZoneInformationHelper.GetDateStr(Index: Integer): string;
begin
  Result := DateTimeToStr(GetDate(Index));
end;

procedure TTimeZoneInformationHelper.ReadInfo(Year: Word; DoConvertDates: Boolean);
begin
  if Year in [CurrentYear, NextDates] then begin
    if GetTimeZoneInformation(Self) = TIME_ZONE_ID_INVALID then
      RaiseLastOSError;
  end else
    if not GetTimeZoneInformationForYear(Year, nil, Self) then
      RaiseLastOSError;

  if DoConvertDates then
    ConvertDates(Year = NextDates);
end;
Delphi-Quellcode:
var
  TZI: TTimeZoneInformation;
begin
  TZI.ReadInfo;
  ShowMessage('Start: ' + TZI.GetStandardDateStr + sLineBreak + 'Ende: ' + TZI.GetDaylightDateStr);
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu (11. Jan 2014 um 15:28 Uhr)
  Mit Zitat antworten Zitat