【Delphi】GMT时间与TDateTime转换

说到GMT时间,人们天天都在用,但一般人不会被注意到。

在Http的世界里面,GMT无处不在,不信你抓包看看各种Header里面。

GMT是世界时间,在处理的时候需要处理当前的时区。

算了,我懒得多说,直接贴代码吧。吹吹牛,我这个可以高性能的哦~~~~

const
  Convert: array[0..255] of Integer =
    (
     -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
     -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
     -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
      0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1,
     -1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,
     -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
     -1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,
     -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
     -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
     -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
     -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
     -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
     -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
     -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
     -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
     -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
     );

function PCharToIntDef(const S: PAnsichar; Len: Integer; def: Integer = 0): Integer;
var
  I: Integer;
  v: Integer;
begin
  Result := 0;
  for I := 0 to len-1 do begin
    V := Convert[ord(s[i])];
    if V<0 then begin
      Result := def;
      Exit;
    end;
    result := (result * 10) + V;
  end;
end;

function LocalTimeZoneBias: Integer;
{$IFDEF LINUX}
var
  TV: TTimeval;
  TZ: TTimezone;
begin
  gettimeofday(TV, TZ);
  Result := TZ.tz_minuteswest;
end;
{$ELSE}
var
  TimeZoneInformation: TTimeZoneInformation;
  Bias: Longint;
begin
  case GetTimeZoneInformation(TimeZoneInformation) of
    TIME_ZONE_ID_STANDARD: Bias := TimeZoneInformation.Bias + TimeZoneInformation.StandardBias;
    TIME_ZONE_ID_DAYLIGHT: Bias := TimeZoneInformation.Bias + ((TimeZoneInformation.DaylightBias div 60) * -100);
  else
    Bias := TimeZoneInformation.Bias;
  end;
  Result := Bias;
end;
{$ENDIF}

var
  DLocalTimeZoneBias: Double = 0;

function DateTimeToGMT(const DT: TDateTime): TDateTime; inline;
begin
  Result := DT + DLocalTimeZoneBias;
end;

function GMTToDateTime(const DT: TDateTime): TDateTime; inline;
begin
  Result := DT - DLocalTimeZoneBias;
end;

function DateTimeToGMTRFC822(const DateTime: TDateTime): string;
const
  WEEK: array[1..7] of string = ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat');
  STR_ENGLISH_M: array[1..12] of string = ('Jan', 'Feb', 'Mar', 'Apr', 'May',
    'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');
var
  wWeek, wYear, wMonth, wDay, wHour, wMin, wSec, wMilliSec: Word;
begin
  DecodeDateTime(DateTimeToGMT(DateTime), wYear, wMonth, wDay, wHour, wMin, wSec, wMilliSec);
  wWeek := DayOfWeek(DateTimeToGMT(DateTime));
  Result := Format('%s, %.2d %s %.4d %.2d:%.2d:%.2d GMT',
    [WEEK[wWeek], wDay, STR_ENGLISH_M[wMonth], wYear, wHour, wMin, wSec]);
end;

function GMTRFC822ToDateTime(const pSour: AnsiString): TDateTime;

  function GetMonthDig(const Value: PAnsiChar): Integer;
  const
    STR_ENGLISH_M: array[1..12] of PAnsiChar = ('Jan', 'Feb', 'Mar', 'Apr', 'May',
      'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');
  begin
    for Result := Low(STR_ENGLISH_M) to High(STR_ENGLISH_M) do begin
      if StrLIComp(Value, STR_ENGLISH_M[Result], 3) = 0 then
        Exit;
    end;
    Result := 0;
  end;
var
  P1, P2, PMax: PAnsiChar;
  wDay, wMonth, wYear, wHour, wMinute, wSec: SmallInt;
begin
  Result := 0;
  if Length(pSour) < 25 then Exit;
  P1 := Pointer(pSour);
  P2 := P1;
  PMax := P1 + Length(pSour);
  while (P1 < PMax) and (P1^ <> ',') do Inc(P1); Inc(P1);
  if (P1^ <> #32) and (P1 - P2 < 4) then Exit;
  Inc(P1); P2 := P1;
  while (P1 < PMax) and (P1^ <> #32) do Inc(P1);
  if (P1^ <> #32) then Exit;
  wDay := PCharToIntDef(P2, P1 - P2);
  if wDay = 0 then Exit;  
  Inc(P1); P2 := P1;

  while (P1 < PMax) and (P1^ <> #32) do Inc(P1);
  if (P1^ <> #32) and (P1 - P2 < 3) then Exit;
  wMonth := GetMonthDig(P2);
  Inc(P1); P2 := P1;

  while (P1 < PMax) and (P1^ <> #32) do Inc(P1);
  if (P1^ <> #32) then Exit;
  wYear := PCharToIntDef(P2, P1 - P2);
  if wYear = 0 then Exit;
  Inc(P1); P2 := P1;

  while (P1 < PMax) and (P1^ <> ':') do Inc(P1);
  if (P1^ <> ':') then Exit;
  wHour := PCharToIntDef(P2, P1 - P2);
  if wHour = 0 then Exit;
  Inc(P1); P2 := P1;

  while (P1 < PMax) and (P1^ <> ':') do Inc(P1);
  if (P1^ <> ':') then Exit;
  wMinute := PCharToIntDef(P2, P1 - P2);
  if wMinute = 0 then Exit;
  Inc(P1); P2 := P1;

  while (P1 < PMax) and (P1^ <> #32) do Inc(P1);
  if (P1^ <> #32) then Exit;
  wSec := PCharToIntDef(P2, P1 - P2);
  if wSec = 0 then Exit;

  Result := GMTToDateTime(EnCodeDateTime(wYear, wMonth, wDay, wHour, wMinute, wSec, 0));
end;

initialization
  DLocalTimeZoneBias := LocalTimeZoneBias / 1440;

 

 

分享到: