Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
 Ошибка конвертирования даты и времени ISO8601ToDate()  [new]
X11
Member

Откуда: Kharkiv, Ukraine
Сообщений: 15181
Обрабатываю XML, где есть теги с датами и временем

2021-03-19T04:03:58+03:00
2021-03-28T03:03:58+03:00
2021-03-28T03:03:34+03:00
2021-03-28T03:03:56+03:00
для примера выше указал несколько строк, где первая строка не проблемная, а остальные - проблемные, т.е. в некоторых случаях вываливается exception.

Project raised exception class ELocalTimeInvalid with message 'The given "28.03.2021 3:03:58" local time is invalid (situated within the missing period prior to DST).'.


procedure TImport.SetDt(const sVal: string; MemData: TdxMemData; sFieldName: string);
Var
 d: TDateTime;
begin
  try
    d := System.DateUtils.ISO8601ToDate(Trim(sVal), False);
    MemData.FieldByName(sFieldName).AsDateTime := d;
  except
    on e:exception do begin
      ShowMessage('Ошибка конвертирования даты и времени, ID=' + fIdOffer.ToString + sLineBreak + e.Message);
    end;
  end;
end;

ЧЯДНТ?
Delphi 10.4.2
1 апр 21, 09:26    [22302822]     Ответить | Цитировать Сообщить модератору
 Re: Ошибка конвертирования даты и времени ISO8601ToDate()  [new]
X11
Member

Откуда: Kharkiv, Ukraine
Сообщений: 15181
Я так подразумеваю, что в это время перевод часов был?
1 апр 21, 09:32    [22302831]     Ответить | Цитировать Сообщить модератору
 Re: Ошибка конвертирования даты и времени ISO8601ToDate()  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 12789
X11
Я так подразумеваю, что в это время перевод часов был?
Именно так. Похоже на баг Эмбаркадеры
+
function AdjustDateTime(const ADate: TDateTime; AHourOffset, AMinuteOffset:Integer; IsUTC: Boolean = True): TDateTime;
var
  AdjustDT: TDateTime;
  BiasLocal: Int64;
  BiasTime: Integer;
  BiasHour: Integer;
  BiasMins: Integer;
  BiasDT: TDateTime;
  TZ: TTimeZone;
begin
  Result := ADate;
  if IsUTC then
    .......
  else
  begin
    { Now adjust TDateTime based on any offsets we have and the local bias }
    { There are two possibilities:
        a. The time we have has the same offset as the local bias - nothing to do!!
        b. The time we have and the local bias are different - requiring adjustments }
    TZ := TTimeZone.Local;
    BiasLocal := Trunc(TZ.GetUTCOffset(Result).Negate.TotalMinutes);
    BiasTime  := (AHourOffset * MinsPerHour) + AMinuteOffset;
    if (BiasLocal + BiasTime) = 0 then
      Exit;

    { Here we adjust the Local Bias to make it relative to the Time's own offset
      instead of being relative to GMT }
    BiasLocal := BiasLocal + BiasTime;
    BiasHour := Abs(BiasLocal) div MinsPerHour;
    BiasMins := Abs(BiasLocal) mod MinsPerHour;
    BiasDT := EncodeTime(BiasHour, BiasMins, 0, 0);
    if (BiasLocal > 0) then
      Result := Result - BiasDT
    else
      Result := Result + BiasDT;
  end;
end;
Т.е. они вместо того, чтобы декодированное время сместить в UTC, а потом переместить в текущий часовой пояс, вычисляют смещение указанного времени для текущего часового пояса, а потом смещают на разницу между часовым поясом и смещением, указанном в строке. А т.к времени 2021-03-28T03:03:58 в киевском часовом поясе не существует, то отсюда и исключение
1 апр 21, 10:41    [22302859]     Ответить | Цитировать Сообщить модератору
 Re: Ошибка конвертирования даты и времени ISO8601ToDate()  [new]
Fr0sT-Brutal
Member

Откуда:
Сообщений: 682
По мне, так это заведомо ошибка - перегонять дату+часовой пояс в просто дату. Либо надо это делать через utc, что железно сработает, либо вообще не делать.
1 апр 21, 10:55    [22302876]     Ответить | Цитировать Сообщить модератору
Все форумы / Delphi Ответить