powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / DateTimeToUnix, округление
7 сообщений из 7, страница 1 из 1
DateTimeToUnix, округление
    #39464223
user_a
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Потребовалось переводить дату и время в формат Unix, и столкнулся с тем, что значения иногда округляются, т.е., получается ещё не наступившее время. Точный пример не помню, но, предположим, 00:01:59.997 (ч:м:с:мс) при переводе в Unix-время получалось 00:02:00.000.

Функция DateTimeToUnix задана так:

Код: pascal
1.
2.
3.
4.
function DateTimeToUnix(const AValue: TDateTime): Int64;
begin
  Result := Round((AValue - UnixDateDelta) * SecsPerDay);
end;



Заменил Round на Trunc, всё работало, однако столкнулся с обратным примером.

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
var d:tdatetime;
    dd:int64;
    s:string;
begin
d:=42373.0013888888861;
datetimetostring(s,'yyyy.mm.dd hh:nn:ss.zzz',d);
dd:=datetimetounix(d);
end;



s='2016.01.04 00:02:00.000'
dd=1451865719 , т.е., 2016.01.04 00:01:59

Значение d получено с помощью вышеуказаной функции (с заменой), где-то так:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
var
datetime,datetime_tmp:tdatetime;
datetime_1:int64;
period:integer;

datetime_1:=trunc(datetimetounix(datetime)/60); // перевод в минуты
datetime_1:=trunc(datetime_1/period)*period; // округление до периода, мин
datetime_1:=datetime_1*60; // обратно в формат unix
datetime_tmp:=unixtodatetime(datetime_1); // в datetime



Соответственно, вопрос: как избежать округления в большую сторону в случае 1, и в меньшую сторону в случае 2?
Формат Unix нужен только для удобства расчёта в секундах.
...
Рейтинг: 0 / 0
DateTimeToUnix, округление
    #39464290
Фотография JayDi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
if then else
...
Рейтинг: 0 / 0
DateTimeToUnix, округление
    #39464413
user_a
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Более того, даже при двух последовательных запусках может возвращаться разное значение.

Код: pascal
1.
2.
3.
ddd:=UnixToDateTime(1451865720);
dddd:=datetimetounix(ddd);
memo1.Lines.Add(IntToStr(dddd));



Возвращает то 1451865719, то 1451865720.
...
Рейтинг: 0 / 0
DateTimeToUnix, округление
    #39464747
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: pascal
1.
2.
3.
4.
5.
6.
7.
function SmartTrunc(const AVal: Double; out IsInt: Boolean): Integer;
begin
  Result := Round(AVal + 0.5);
  IsInt := Abs(AVal - Result) < 1E-6;
  if not IsInt then
    Dec(Result);
end;
...
Рейтинг: 0 / 0
DateTimeToUnix, округление
    #39465056
user_a
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо! А там, где у меня в примере "перевод в минуты" и "округление до периода, мин", там тоже нужно через SmartTrunc, или там уже ошибки не может быть? А то что-то уже не соображаю сегодня.
...
Рейтинг: 0 / 0
DateTimeToUnix, округление
    #39465228
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user_a,

Везде.

Почитайте про хранение чисел с плавающей точкой
...
Рейтинг: 0 / 0
DateTimeToUnix, округление
    #39466105
Bred eFeM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user_aБолее того, даже при двух последовательных запусках может возвращаться разное значение.
Код: pascal
1.
2.
3.
ddd:=UnixToDateTime(1451865720);
dddd:=datetimetounix(ddd);
memo1.Lines.Add(IntToStr(dddd));

Возвращает то 1451865719, то 1451865720.Сочувствую!

автор
Код: pascal
1.
2.
d:=42373.0013888888861;
datetimetostring(s,'yyyy.mm.dd hh:nn:ss.zzz',d);

s='2016.01.04 00:02:00.000'Берём счёты и проверяем:

0,0013888888861*86400=119,99999975904... [119] т.е. 00:01:59 !

Формат Unix TFileTime нужен .
только для удобства расчёта в секундах пойдёт и TDateTime .
...
Рейтинг: 0 / 0
7 сообщений из 7, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / DateTimeToUnix, округление
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]