Des weiteren werden in der kompletten Datenkommunikation immer GMT Zeitangaben benötigt um eine global über die Zeit-Zonen hinaus gültige Angabe zu haben, lokale Zeitangaben sind für den einzelnen Betrachter noch relevant, aber in der Zeit der Globalisierung gibt es sonst keine genaue Vergleichsmöglichkeit. So werden diese Funktionen auch zum Füllen des Meta-Wertes Date im head -Bereich des HTML-Dokumentes benötigt und in Atom-, RSS- Feeds, etc.
gmtutils.pas Pascal (13,02 kByte) 23.02.2014 13:59
unit GMTUtils;
{$mode objfpc} {$H+}
interface
uses
{$ifdef windows} Windows{$endif} , Classes, SysUtils, DateUtils;
type
TFileTimes = set of (ftCreation, ftLastAccess, ftLastWrite);
const
tsRFC = 'ddd, dd mmm yyyy hh:nn:ss "GMT"' ; tsRFC3339 = 'yyyy"-"mm"-"dd"T"hh":"nn":"ss"+00:00"' ; tsAtom = 'yyyy"-"mm"-"dd"T"hh":"nn":"ss"Z"' ; tsW3C = tsRFC3339;
tsiCal = 'yyyymmdd"T"hhnnss"Z"' ; tsGER = 'dd"."mm"."yyyy hh":"mm":"ss"."zzz' ; tsISO8601 = 'yyyy"-"mm"-"dd"T"hh":"nn":"ss"+0000"' ; tsRFC822 = 'ddd", "dd" "mmm" "yy" "hh":"nn":"ss" +0000"' ; tsRFC1036 = tsRFC822;
tsRFC850 = 'dddd", "dd"-"mmm"-"yy" "hh":"nn":"ss" UTC"' ; tsCookie = tsRFC850;
tsRFC1123 = 'ddd", "dd" "mmm" "yyyy" "hh":"nn":"ss" +0000"' ; tsRFC2822 = tsRFC1123;
tsRSS = tsRFC1123;
tsLog = 'yyyy"-"mm"-"dd" "hh":"nn":"ss' ;
GD_LCID = 2057 ;
DE_LCID = 1031 ;
function DateTimeToString (ADateTime: TDateTime; const frmtstr: string = tsRFC; const LCID: integer = GD_LCID): string ;
function StringToDateTime (ADateTime: string ; const frmtstr: string = tsRFC; const LCID: integer = GD_LCID): TDateTime;
function NowGMT (): TDateTime;
function NowGMTStr (const frmtstr: string = tsRFC): string ;
function LocalTimeToGMT (const ALocalDateTime: TDateTime): TDateTime;
function GMTToLocalTime (const AGMTTime: TDateTime): TDateTime;
function LocalTimeToGMTStr (const ALocalDateTime: TDateTime; const frmtstr: string = tsRFC; const LCID: integer = GD_LCID): string ;
function FileTimeGMT (SearchRec: TSearchRec): TDateTime; overload ;
function FileTimeGMT (const AFileTime: TFileTime): TDateTime; overload ;
function FileTimeGMT (AFilename: string ): TDateTime; overload ;
function FileTimeGMTStr (const AFilename: string ; const frmtstr: string = tsRFC; const LCID: integer = GD_LCID): string ;
function FileTimeCopy (const AFrom, ATo: string ): boolean;
function UnixDateTimeToDateTime (const AUnixDateTime: LongInt): TDateTime;
function UnixTimeToDateTime (const UnixTime: integer): TDateTime;
function DateTimeToUnixDateTime (const ADateTime: TDateTIme): Longint;
function DateTimeToUnixTime (const DateTime: TDateTime): integer;
implementation
function DateTimeToString (ADateTime: TDateTime; const frmtstr: string = tsRFC; const LCID: integer = GD_LCID): string ;
var fs: TFormatSettings;
begin
GetLocaleFormatSettings(LCID, fs);
result := FormatDateTime(frmtstr, ADateTime, fs);
end ;
function StringToDateTime (ADateTime: string ; const frmtstr: string = tsRFC; const LCID: integer = GD_LCID): TDateTime;
var fs: TFormatSettings;
begin
GetLocaleFormatSettings(LCID, fs);
if ADateTime= '' then
begin
ADateTime := '01.01.1970 00:00:00' ;
fs.DateSeparator := '.' ;
fs.TimeSeparator := ':' ;
fs.DecimalSeparator := '.' ;
end ;
if frmtstr = tsRFC then
begin
fs.ShortDateFormat := 'ddd", "dd" "mmm" "yyyy' ;
ADateTime := StringReplace(ADateTime, 'T' , ' ' , []);
fs.LongTimeFormat := 'hh":"nn":"ss' ;
ADateTime := StringReplace(ADateTime, ' GMT' , '' , []);
fs.DateSeparator := ' ' ;
end
else if frmtstr = tsRFC822 then
begin
fs.ShortDateFormat := 'ddd", "dd" "mmm" "yy' ;
fs.LongTimeFormat := 'hh":"nn":"ss' ;
ADateTime := StringReplace(ADateTime, ' +0000' , '' , []);
fs.DateSeparator := ' ' ;
end
else if frmtstr = tsRFC850 then
begin
fs.ShortDateFormat := 'dddd", "dd"-"mmm"-"yy' ;
fs.LongTimeFormat := 'hh":"nn":"ss' ;
ADateTime := StringReplace(ADateTime, ' UTC' , '' , []);
fs.DateSeparator := '-' ;
end
else if frmtstr = tsRFC1123 then
begin
fs.ShortDateFormat := 'ddd", "dd" "mmm" "yyyy' ;
fs.LongTimeFormat := 'hh":"nn":"ss' ;
ADateTime := StringReplace(ADateTime, ' +0000' , '' , []);
fs.DateSeparator := ' ' ;
end
else if frmtstr = tsRFC3339 then
begin
fs.ShortDateFormat := 'yyyy"-"mm"-"dd' ;
ADateTime := StringReplace(ADateTime, 'T' , ' ' , []);
fs.LongTimeFormat := 'hh":"nn":"ss' ;
ADateTime := StringReplace(ADateTime, '+00:00' , '' , []);
fs.DateSeparator := '-' ;
end
else if frmtstr = tsISO8601 then
begin
fs.ShortDateFormat := 'yyyy"-"mm"-"dd' ;
ADateTime := StringReplace(ADateTime, 'T' , ' ' , []);
fs.LongTimeFormat := 'hh":"nn":"ss' ;
ADateTime := StringReplace(ADateTime, '+0000' , '' , []);
fs.DateSeparator := '-' ;
end
else if frmtstr = tsGER then
begin
fs.ShortDateFormat := 'dd"."mm"."yyyy' ;
fs.LongTimeFormat := 'hh":"nn":"ss"."zzz' ;
fs.DateSeparator := '.' ;
fs.TimeSeparator := ':' ;
fs.DecimalSeparator := '.' ;
end ;
result := StrToDateTime(ADateTime, fs);
end ;
function NowGMT (): TDateTime;
{$ifdef windows}
var SystemTime: TSystemTime;
begin
GetSystemTime(SystemTime);
result := SystemTimeToDateTime(SystemTime);
end ;
{$else unix}
var
TimeVal: TTimeVal;
TimeZone: PTimeZone;
a: Double;
begin
TimeZone := nil ;
fpGetTimeOfDay(@TimeVal, TimeZone);
a := (TimeVal.tv_sec * 1000.0 ) + (TimeVal.tv_usec / 1000.0 );
result := (a / MSecsPerDay) + UnixDateDelta;
end ;
{$endif}
function NowGMTStr (const frmtstr: string = tsRFC): string ;
begin
result := DateTimeToString (NowGMT (), frmtstr);
end ;
{$ifdef windows}
function CompareSysTime (st1, st2: TSystemTime): integer;
begin
if st1.wMonth < st2.wMonth then result := - 1
else if st1.wMonth > st2.wMonth then result := 1
else if st1.wDayOfWeek < st2.wDayOfWeek then result := - 1
else if st1.wDayOfWeek > st2.wDayOfWeek then result := 1
else if st1.wDay < st2.wDay then result := - 1
else if st1.wDay > st2.wDay then result := 1
else if st1.wHour < st2.wHour then result := - 1
else if st1.wHour > st2.wHour then result := 1
else if st1.wMinute < st2.wMinute then result := - 1
else if st1.wMinute > st2.wMinute then result := 1
else if st1.wSecond < st2.wSecond then result := - 1
else if st1.wSecond > st2.wSecond then result := 1
else if st1.wMilliseconds < st2.wMilliseconds then result := - 1
else if st1.wMilliseconds > st2.wMilliseconds then result := 1
else result := 0 ;
end ;
{$endif}
function GetTZInfoForDateTime (const ADateTime: TDateTime): integer;
var
{$ifdef windows}
SystemTime: TSystemTime;
TZInfo: TTimeZoneInformation;
{$endif}
begin
{$ifdef windows}
GetTimeZoneInformation(TZInfo);
DateTimeToSystemTime(ADateTime, SystemTime);
if (CompareSysTime (SystemTime, TZInfo.DayLightDate)= 1 ) and
(CompareSysTime (SystemTime, TZInfo.StandardDate)= - 1 ) then
result := TZInfo.Bias + TZInfo.DaylightBias
else
result := TZInfo.Bias + TZInfo.StandardBias;
{$else unix}
result := - TZseconds div 60 ;
{$endif}
end ;
function LocalTimeToGMT (const ALocalDateTime: TDateTime): TDateTime;
var TZOffset: integer;
begin
result := ALocalDateTime;
TZOffset := GetTZInfoForDateTime (ALocalDateTime);
if (TZOffset > 0 ) then
result := ALocalDateTime + EncodeTime(TZOffset div 60 , TZOffset mod 60 , 0 , 0 )
else if (TZOffset = 0 ) then
result := ALocalDateTime
else if (TZOffset < 0 ) then
result := ALocalDateTime - EncodeTime(Abs(TZOffset) div 60 , Abs(TZOffset) mod 60 , 0 , 0 );
end ;
function GMTToLocalTime (const AGMTTime: TDateTime): TDateTime;
var TZOffset: Integer;
begin
result := AGMTTime;
TZOffset := GetTZInfoForDateTime (AGMTTime);
if (TZOffset > 0 ) then
result := AGMTTime - EncodeTime(TZOffset div 60 , TZOffset mod 60 , 0 , 0 )
else if (TZOffset = 0 ) then
result := AGMTTime
else if (TZOffset < 0 ) then
result := AGMTTime + EncodeTime(Abs(TZOffset) div 60 , Abs(TZOffset) mod 60 , 0 , 0 );
end ;
function LocalTimeToGMTStr (const ALocalDateTime: TDateTime; const frmtstr: string = tsRFC; const LCID: integer = GD_LCID): string ;
begin
result := DateTimeToString (LocalTimeToGMT (ALocalDateTime), frmtstr, LCID);
end ;
function FileTimeGMT (SearchRec: TSearchRec): TDateTime;
var
{$ifdef windows}
SystemFileTime: TSystemTime;
{$else unix}
TimeVal: TTimeVal;
TimeZone: TTimeZone;
{$endif}
begin
result := 0.0 ;
{$ifdef windows}
{$WARNINGS OFF}
if (SearchRec.FindData.dwFileAttributes and faDirectory) = 0 then
if FileTimeToSystemTime(SearchRec.FindData.ftLastWriteTime, SystemFileTime) then
result := EncodeDate (SystemFileTime.wYear, SystemFileTime.wMonth, SystemFileTime.wDay)
+ EncodeTime (SystemFileTime.wHour, SystemFileTime.wMinute, SystemFileTime.wSecond, SystemFileTime.wMilliseconds);
{$WARNINGS ON}
{$else unix}
if SearchRec.Attr and faDirectory = 0 then
begin
result := FileDateToDateTime(SearchRec.Time);
fpGetTimeOfDay(@TimeVal, @TimeZone);
result := result + TimeZone.tz_minuteswest / (60 * 24 );
end ;
{$endif}
end ;
function FileTimeGMT (const AFileTime: TFileTime): TDateTime;
var
{$ifdef windows}
SystemFileTime: TSystemTime;
{$else unix}
TimeVal: TTimeVal;
TimeZone: TTimeZone;
{$endif}
begin
result := 0.0 ;
{$ifdef windows}
{$WARNINGS OFF}
if FileTimeToSystemTime(AFileTime, SystemFileTime) then
result := EncodeDate (SystemFileTime.wYear, SystemFileTime.wMonth, SystemFileTime.wDay)
+ EncodeTime (SystemFileTime.wHour, SystemFileTime.wMinute, SystemFileTime.wSecond, SystemFileTime.wMilliseconds);
{$WARNINGS ON}
{$else unix}
if SearchRec.Attr and faDirectory = 0 then
begin
result := FileDateToDateTime(AFileTime);
fpGetTimeOfDay(@TimeVal, @TimeZone);
result := result + TimeZone.tz_minuteswest / (60 * 24 );
end ;
{$endif}
end ;
function FileTimeGMT (AFilename: string ): TDateTime;
var sr: TSearchRec;
begin
result := 0.0 ;
if FindFirst (AFilename, faAnyFile, sr) = 0 then
result := FileTimeGMT (sr);
FindClose(sr);
end ;
function FileTimeGMTStr (const AFilename: string ; const frmtstr: string = tsRFC; const LCID: integer = GD_LCID): string ;
begin
result := DateTimeToString (FileTimeGMT (AFilename), frmtstr, LCID);
end ;
function FileTimeCopy (const AFrom, ATo: string ): boolean;
var
{$ifdef windows}
fh : THandle;
fCreationTime, fLastAccessTime, fLastWriteTime: TFileTime;
{$else}
fa : Longint;
{$endif}
begin
result := false ;
if FileExists(AFrom) and FileExists(ATo) then
begin
{$ifdef windows}
fh := FileOpen(AFrom, fmOpenRead or fmShareDenyNone);
if fh > 0 then try
result := GetFileTime(fh, @fCreationTime, @fLastAccessTime, @fLastWriteTime);
finally
FileClose(fh);
end ;
fh := FileOpen(ATo, fmOpenWrite);
if fh > 0 then
try
result := SetFileTime(fh, @fCreationTime, @fLastAccessTime, @fLastWriteTime);
finally
FileClose(fh);
end ;
{$else}
fa := FileAge(AFrom);
if fa<> - 1 then
result := FileSetDate(ATo, FileAge(AFrom)) = 0
else
result := false ;
{$endif}
end ;
end ;
const UnixStartDate: TDateTime = 25569.0 ;
function UnixDateTimeToDateTime (const AUnixDateTime: LongInt): TDateTime;
begin
Result := UnixStartDate + (AUnixDateTime / 86400 );
end ;
function UnixTimeToDateTime (const UnixTime: integer): TDateTime;
var
FileTime: TFileTime;
SystemTime: TSystemTime;
I: Int64;
begin
I := Int64(UnixTime) * Int64(10000000 ) + 116444736000000000 ;
FileTime.dwLowDateTime := DWORD(I);
FileTime.dwHighDateTime := I shr 32 ;
FileTimeToSystemTime(FileTime, SystemTime);
Result := SystemTimeToDateTime(SystemTime);
end ;
function DateTimeToUnixDateTime (const ADateTime: TDateTIme): Longint;
begin
Result := Round((ADateTime - UnixStartDate) * 86400 );
end ;
function DateTimeToUnixTime (const DateTime: TDateTime): integer;
var
FileTime: TFileTime;
SystemTime: TSystemTime;
I: Int64;
begin
DateTimeToSystemTime(DateTime, SystemTime);
SystemTimeToFileTime(SystemTime, FileTime);
I := Int64(FileTime.dwHighDateTime) shl 32 + FileTime.dwLowDateTime;
Result := (I - 116444736000000000 ) div Int64(10000000 );
end ;
end .