⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iddatetimestamp.pas

📁 Indy控件的使用源代码
💻 PAS
📖 第 1 页 / 共 3 页
字号:
    end else
    begin
      result := '+' + IntToStr(i);   {Do not Localize}
    end;
  end;
  i := GetTimeZoneMinutes;
  if i <= 9 then
  begin
    result := result + '0';    {Do not Localize}
  end;
  result := result + IntToStr(i);
end;

function TIdDateTimeStamp.GetTimeZoneHour: Integer;
begin
  result := FTimeZone div 60;
end;

function TIdDateTimeStamp.GetTimeZoneMinutes: Integer;
begin
  result := Abs(FTimeZone) mod 60;
end;

function TIdDateTimeStamp.GetWeekOfYear;
var
  w : Integer;
  DT : TIdDateTimeStamp;
begin
  DT := TIdDateTimeStamp.Create(Self);
  try
    DT.SetYear(Year);
    w := DT.DayOfWeek; // Get the first day of this year & hence number of
    // days of the first week that are in the previous year
    w := w + Day - 2; // Get complete weeks
    w := w div 7;
    result := w + 1;
  finally
    DT.Free;
  end;
end;

procedure TIdDateTimeStamp.SetFromDOSDateTime(ADate, ATime: Word);
begin
  Zero;
  SetYear(1980);
  AddYears(ADate shr 9);
  AddMonths(((ADate and $1E0) shr 5) - 1);
  AddDays((ADate and $1F) - 1);
  AddHours(ATime shr 11);
  AddMinutes((ATime and $7E0) shr 5);
  AddSeconds((ATime and $1F) - 1);
end;

procedure TIdDateTimeStamp.SetDateFromISO8601(AString: String);
var
  i, week : Integer;
  s : String;
begin
  // AString should be in one of three formats:
  // Calender - YYYY-MM-DD
  // Ordinal - YYYY-XXX  where XXX is the day of the year
  // Week - YYYY-WXX-D  where W is a literal and XX is the week of the year.
  i := IndyPos('-', AString);    {Do not Localize}
  if i > 0 then
  begin
    s := Trim(Copy(AString, 1, i - 1));
    AString := Trim(Copy(AString, i + 1, length(AString)));
    i := FindFirstNotOf('0123456789', s);  {Do not Localize}
    if i = 0 then
    begin
      SetYear(StrToInt(s));
      if length(AString) > 0 then begin

        i := IndyPos('-', AString);     {Do not Localize}

        if (AString[1] = 'W') or (AString[1] = 'w') then  {Do not Localize}
        begin
          // Week format
          s := Trim(Copy(AString, 2, i - 2));
          AString := Trim(Copy(AString, i + 1, length(AString)));

          week := -1;
          i := -1;
          if (length(AString) > 0)
          and (FindFirstNotOf(DIGITS, AString) = 0) then
          begin
            i := StrToInt(AString);
          end;

          if (Length(s) > 0)
          and (FindFirstNotOf(DIGITS, AString) = 0) then
          begin
            week := StrToInt(s);
          end;

          if (week > 0) and (i >= 0) then
          begin
            Dec(week);
            FDay := 1 + (IdDaysInWeek * week);

            // Now have the correct week of the year
            if i < GetDayOfWeek then begin
              SubtractDays(GetDayOfWeek - i);
            end else begin
              AddDays(i - GetDayOfWeek);
            end;
          end;

        end else if i > 0 then
        begin
          // Calender format
          s := Trim(Copy(AString, 1, i - 1));
          AString := Trim(Copy(AString, i + 1, length(AString)));
          // Set the day first due to internal format.
          if (length(AString) > 0)
          and (FindFirstNotOf(DIGITS, s) = 0) then
          begin
            SetDay(StrToInt(AString));
          end;
          
          // Add the months.
          if (length(s) > 0) and (FindFirstNotOf(DIGITS, s) = 0) then
          begin
            AddMonths(StrToInt(s) - 1);
          end;
        end else
        begin
          // Ordinal format
          i := FindFirstNotOf(DIGITS, AString);
          if i = 0 then begin
            SetDay(StrToInt(AString));
          end;
        end;

      end;
    end;
  end;
end;

procedure TIdDateTimeStamp.SetTimeFromISO8601(AString: String);
var
  i : Integer;
  Hour, Minute : String;
begin
  // AString should be in the format of HH:MM:SS where : is a literal.
  i := IndyPos(':', AString);      {Do not Localize}
  Hour := Trim(Copy(AString, 1, i - 1));
  AString := Trim(Copy(AString, i + 1, length(AString)));

  i := IndyPos(':', AString);      {Do not Localize}
  Minute := Trim(Copy(AString, 1, i - 1));
  AString := Trim(Copy(AString, i + 1, Length(Astring)));

  // Set seconds first due to internal format.
  if (length(AString) > 0)
  and (FindFirstNotOf(DIGITS, AString) = 0) then
  begin
    SetSecond(StrToInt(AString));
  end;

  if (length(Minute) > 0)
  and (FindFirstNotOf(DIGITS, Minute) = 0) then
  begin
    AddMinutes(StrToInt(Minute));
  end;  

  if (length(Hour) > 0)
  and (FindFirstNotOf(DIGITS, Hour) = 0) then
  begin
    AddHours(StrToInt(Hour));
  end;
end;

procedure TIdDateTimeStamp.SetFromISO8601(AString: String);
var
  i : Integer;
begin
  Zero;
  i := IndyPos('T', AString);  {Do not Localize}
  if i > 0 then
  begin
    SetDateFromISO8601(Trim(Copy(AString, 1, i - 1)));
    SetTimeFromISO8601(Trim(Copy(AString, i + 1, length(AString))));
  end else
  begin
    SetDateFromISO8601(AString);
    SetTimeFromISO8601(AString);
  end;
end;

procedure TIdDateTimeStamp.SetFromRFC822(AString: String);
begin
  SetFromTDateTime(StrInternetToDateTime(AString))
end;

procedure TIdDateTimeStamp.SetFromTDateTime;
begin
  SetFromTTimeStamp(DateTimeToTimeStamp(ADateTime));
end;

procedure TIdDateTimeStamp.SetFromTTimeStamp;
begin
  SetYear(1);
  SetDay(1);
  SetSecond(0);
  SetMillisecond(ATimeStamp.Time);
  SetDay(ATimeStamp.Date);
end;

procedure TIdDateTimeStamp.SetDay;
begin
  if ANumber > 0 then begin
    FDay := 0;
    AddDays(ANumber);
  end else begin
    FDay := 1;
  end;
end;

procedure TIdDateTimeStamp.SetMillisecond;
begin
  FMillisecond := 0;
  AddMilliseconds(ANumber);
end;

procedure TIdDateTimeStamp.SetSecond;
begin
  FSecond := 0;
  AddSeconds(ANumber);
end;

procedure TIdDateTimeStamp.SetTimeZone(const Value: Integer);
begin
  FTimeZone := Value;
end;

procedure TIdDateTimeStamp.SetYear;
begin
  If ANumber = 0 then begin
    FYear := 1;
  end else begin
    FYear := ANumber;
  end;
  CheckLeapYear;
end;

procedure TIdDateTimeStamp.SubtractDays;
var
  i : Integer;
begin
  if ANumber = 0 then exit;

  // First remove the number of days in this year.  As with AddDays this
  // is both an optimisation and a fix for calculations that begin in leap years.
  if ANumber >= Cardinal(FDay - 1) then begin
    ANumber := ANumber - Cardinal(FDay - 1);
    FDay := 1;
  end else begin
    FDay := FDay - Integer(ANumber);
  end;

  // Subtract the number of whole leap year cycles = 400 years
  if ANumber >= IdDaysInLeapYearCycle then begin
    i := ANumber div IdDaysInLeapYearCycle;
    SubtractYears(i * IdYearsInLeapYearCycle);
    ANumber := ANumber - Cardinal(i * IdDaysInLeapYearCycle);
  end;

  // Next subtract the centuries, checking for the century that is passed through
  if ANumber >= IdDaysInLeapCentury then begin
    while ANumber >= IdDaysInLeapCentury do begin
      i := FYear div 100;

      if i mod 4 = 0 then begin
        // Going back through a 'leap' century    {Do not Localize}
        SubtractYears(IdYearsInCentury);
        ANumber := ANumber - Cardinal(IdDaysInLeapCentury);
      end else begin
        SubtractYears(IdYearsInCentury);
        ANumber := ANumber - Cardinal(IdDaysInCentury);
      end;
    end;
  end;

  // Subtract multiples of 4 ("Short" Leap year cycle)
  if ANumber >= IdDaysInShortLeapYearCycle then begin
    while ANumber >= IdDaysInShortLeapYearCycle do begin

      // Round off current year to nearest four.
      i := (FYear shr 2) shl 2;

      if SysUtils.IsLeapYear(i) then begin
        // Normal
        SubtractYears(IdYearsInShortLeapYearCycle);
        ANumber := ANumber - Cardinal(IdDaysInShortLeapYearCycle);
      end else begin
        // Subtraction crosses a 100-year (but not 400-year) boundary. Add the
        // same number of years, but one less day.
        SubtractYears(IdYearsInShortLeapYearCycle);
        ANumber := ANumber - Cardinal(IdDaysInShortNonLeapYearCycle);
      end;
    end;
  end;

  // Now the individual years
  while ANumber > Cardinal(DaysInYear) do begin
    SubtractYears(1);
    Dec(ANumber, DaysInYear);
    if Self.IsLeapYear then begin
      // Correct the assumption of a non-leap year
      AddDays(1);
    end;
  end;

  // and finally the remainders
  if ANumber >= Cardinal(FDay) then begin
    SubtractYears(1);
    ANumber := ANumber - Cardinal(FDay);
    Day := DaysInYear - Integer(ANumber);
  end else begin
    Dec(FDay, ANumber);
  end;

end;

procedure TIdDateTimeStamp.SubtractHours;
var
  i : Cardinal;
begin
  i := ANumber div IdHoursInDay;
  SubtractDays(i);
  Dec(ANumber, i * IdHoursInDay);

  SubtractSeconds(ANumber * IdSecondsInHour);
end;

procedure TIdDateTimeStamp.SubtractMilliseconds;
var
  i : Cardinal;
begin
  if ANumber = 0 then exit;

  i := ANumber div IdMillisecondsInDay;
  SubtractDays(i);
  Dec(ANumber, i * IdMillisecondsInDay);

  i := ANumber div IdMillisecondsInSecond;
  SubtractSeconds(i);
  Dec(ANumber, i * IdMillisecondsInSecond);

  Dec(FMillisecond, ANumber);
  while FMillisecond <= 0 do begin
    SubtractSeconds(1);
    // FMillisecond is already negative, so add it.
    FMillisecond := IdMillisecondsInSecond + FMillisecond;
  end; 
end;

procedure TIdDateTimeStamp.SubtractMinutes(ANumber : Cardinal);
begin
  // Down size to seconds
  while ANumber > MaxMinutesAdd do begin
    SubtractSeconds(MaxMinutesAdd * IdSecondsInMinute);
    Dec(ANumber, MaxMinutesAdd);
  end;
  SubtractSeconds(ANumber * IdSecondsInMinute);
end;

procedure TIdDateTimeStamp.SubtractMonths;
var
  i : Integer;
begin
  i := ANumber div IdMonthsInYear;
  SubtractYears(i);
  Dec(ANumber, i * IdMonthsInYear);

  while ANumber > 0 do begin
    i := MonthOfYear;
    if i = 1 then begin
      i := 13;
    end;
    if (i = 3) and (IsLeapYear) then begin
      SubtractDays(IdDaysInMonth[2] + 1);
    end else begin
      SubtractDays(IdDaysInMonth[i - 1]);
    end;
    Dec(ANumber);
  end;
end;

procedure TIdDateTimeStamp.SubtractSeconds(ANumber : Cardinal);
var
  i : Cardinal;
begin
  if ANumber = 0 then exit;

  i := ANumber div IdSecondsInDay;
  SubtractDays(i);
  Dec(ANumber, i * IdSecondsInDay);

  Dec(FSecond, ANumber);
  If FSecond < 0 then begin
    SubtractDays(1);
    FSecond := IdSecondsInDay + FSecond;
  end;
end;

procedure TIdDateTimeStamp.SubtractTDateTime;
begin
  SubtractTTimeStamp(DateTimeToTimeStamp(ADateTime));
end;

procedure TIdDateTimeStamp.SubtractTIdDateTimeStamp;
begin
  { TODO : Check for accuracy }
  SubtractYears(AIdDateTime.Year);
  SubtractDays(AIdDateTime.Day);
  SubtractSeconds(AIdDateTime.Second);
  SubtractMilliseconds(AIdDateTime.Millisecond);
end;

procedure TIdDateTimeStamp.SubtractTTimeStamp;
var
  TId : TIdDateTimeStamp;
begin
  TId := TIdDateTimeStamp.Create(Self);
  try
    TId.SetFromTTimeStamp(ATimeStamp);
    Self.SubtractTIdDateTimeStamp(TId);
  finally
    TId.Free;
  end;
end;

procedure TIdDateTimeStamp.SubtractWeeks(ANumber : Cardinal);
begin
  if ANumber = 0 then exit;

  // Down size to subtracting Days
  while ANumber > MaxWeekAdd do begin
    SubtractDays(MaxWeekAdd * IdDaysInWeek);
    Dec(ANumber, MaxWeekAdd * IdDaysInWeek);
  end;
  SubtractDays(ANumber * IdDaysInWeek);
end;

procedure TIdDateTimeStamp.SubtractYears;
begin
  if (FYear > 0) and (ANumber >= Cardinal(FYear)) then begin
    Inc(ANumber);
  end;

  FYear := FYear - Integer(ANumber);
  CheckLeapYear;
end;

procedure TIdDateTimeStamp.Zero;
begin
  ZeroDate;
  ZeroTime;
  FTimeZone := 0;
end;

procedure TIdDateTimeStamp.ZeroDate;
begin
  SetYear(1);
  SetDay(1);
end;

procedure TIdDateTimeStamp.ZeroTime;
begin
  SetSecond(0);
  SetMillisecond(0);
end;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -