Поле типа TimeStamp.

Clarion, Clarion 7

Модератор: Дед Пахом

Правила форума
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
Ответить
kreator
✯ Ветеран ✯
Сообщения: 4960
Зарегистрирован: 28 Май 2009, 15:54
Откуда: Москва
Благодарил (а): 6 раз
Поблагодарили: 19 раз

Поле типа TimeStamp.

Сообщение kreator »

C10. Мне нужно сравнивать Дату+Время. Одна величина приходит с SQL сервера (но это не принипиально), вторая - текущее время через date() и clock(). Хочу просто типа так:

Код: Выделить всё

if (date()+clock())>(Date1+Time1)
...
end

Что можно сделать? Может через группу? Может через int64?
Вдруг у кого была такая задача.
We are hard at work… for you. :)
Аватара пользователя
RaFaeL
✯ Ветеран ✯
Сообщения: 1376
Зарегистрирован: 24 Март 2009, 17:59
Откуда: НН
Благодарил (а): 7 раз
Поблагодарили: 1 раз
Контактная информация:

Поле типа TimeStamp.

Сообщение RaFaeL »

Вряд ли у тебя кода получится меньше, чем просто два сравнения сделать
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 7323
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 13 раз
Поблагодарили: 48 раз

Поле типа TimeStamp.

Сообщение Игорь Столяров »

kreator писал(а): Что можно сделать? Может через группу? Может через int64?
Можно попробовать не изобретать велосипед, а сделать как например Java Script ...
Там любое временное событие (дата / время) - это кол-во тысячных долей секунды с 01.01.1970 г.
Соответственно нужны две простые функции преобразования кларионовских и SQL дат/времени стандарту JS.
И будет, что-то вроде:

Код: Выделить всё

If ClaDateTimeToJava(ToDay(),Clock()) > SQLDateTimeToJava(Date1,Time1)
...
end
За теми кто отстал - не возвращаться. (С) Кодекс
Аватара пользователя
Дед Пахом
Старичок
Сообщения: 3131
Зарегистрирован: 07 Июль 2005, 16:51
Откуда: Москва, Россия
Благодарил (а): 10 раз
Поблагодарили: 28 раз
Контактная информация:

Поле типа TimeStamp.

Сообщение Дед Пахом »

Я вот такими функциями пользуюсь, перевод Clarion date/time в тип OLEDATE (REAL).

Код: Выделить всё

msxml::ConvertClaDateTimetoDATE   PROCEDURE(LONG pDate, LONG pTime = 0)
Date0                               LONG, AUTO
ClaMaxTime                          REAL(8640000.0)
oleDate                             TOLEDATE
  CODE
  Date0 = DATE(12, 30, 1899)

  !-- date part
  oleDate = pDate - Date0
  
  !-- time part
  IF pTime
    IF oleDate => 0
      oleDate += (pTime - 1.0) / ClaMaxTime
    ELSE
      oleDate = ABS(oleDate)
      oleDate += (pTime * 1.0) / ClaMaxTime
      oleDate = -oleDate
    END
  END
  
  RETURN oleDate

msxml::ConvertStrDateTimetoDATE   PROCEDURE(STRING pDateTimeStr)
!-- pDateTimeStr in '1997-07-31T00:00:00' format
nTPos                               LONG, AUTO
nDate                               LONG, AUTO
nTime                               LONG, AUTO
  CODE
  IF NOT pDateTimeStr
    RETURN 0
  END
  
  nTPos = INSTRING('T', pDateTimeStr, 1, 1)
  ASSERT(nTPos)
  IF NOT nTPos
    msxml::DebugInfo('Invalid DateTime string: '& pDateTimeStr)
    RETURN 0
  END
  
  nDate = DEFORMAT(pDateTimeStr[1 : nTPos - 1], @d10-)
  nTime = DEFORMAT(pDateTimeStr[nTPos + 1 : LEN(CLIP(pDateTimeStr))], @t04)

  RETURN msxml::ConvertClaDateTimetoDATE(nDate, nTime)
С уважением, ДП
Аватара пользователя
Дед Пахом
Старичок
Сообщения: 3131
Зарегистрирован: 07 Июль 2005, 16:51
Откуда: Москва, Россия
Благодарил (а): 10 раз
Поблагодарили: 28 раз
Контактная информация:

Поле типа TimeStamp.

Сообщение Дед Пахом »

Код: Выделить всё

!-- The DATE type is implemented using an 8-byte floating-point number. 
!-- Days are represented by whole number increments starting with 30 December 1899, midnight as time zero. 
!-- Hour values are expressed as the absolute value of the fractional part of the number.
TOLEDATE                      EQUATE(REAL)

С уважением, ДП
kreator
✯ Ветеран ✯
Сообщения: 4960
Зарегистрирован: 28 Май 2009, 15:54
Откуда: Москва
Благодарил (а): 6 раз
Поблагодарили: 19 раз

Поле типа TimeStamp.

Сообщение kreator »

По мотивам обсуждения вот такой вариант:

Код: Выделить всё

LOC:Test64_Group      group(uint64)
                      end
LOC:Test64_2_Group    group(uint64)
                      end
LOC:Test64            Real, over(LOC:Test64_Group)
LOC:Test64_2          Real, over(LOC:Test64_2_Group)

LOC:Test64_Group.hi = clock()
LOC:Test64_Group.lo = today()
LOC:Test64_2_Group.hi = LOC:Test64_Group.hi - 1000
LOC:Test64_2_Group.lo = today()
stop(LOC:Test64 & '  ' & LOC:Test64_2)
if LOC:Test64>LOC:Test64_2
  stop('ОК')
else 
  stop('Всё плохо')
end 
Предварительное тестирование даёт правильный результат. Но, если честно, непонятно почему. В работу отдавать страшно :D .
We are hard at work… for you. :)
Shur
Ветеран
Сообщения: 384
Зарегистрирован: 02 Июль 2011, 18:49

Поле типа TimeStamp.

Сообщение Shur »

Для сравнения дат+времени удобно использовать POSIX (UNIX) формат времени -- это количество секунд, прошедших с 1 января 1970 года. Удобство состоит в том, что эта величина помещается (на сегодняшний день :) ) в поле типа ULONG, которые сравниваются за одно сравнение. Также время в формате POSIX ввиду компактности можно хранить в СУБД, не имеющих datetime формата.

Код: Выделить всё

Date2Posix             PROCEDURE(LONG,<LONG>,*ULONG)   !!Clarion Standard Date & Time --> Posix Time
Posix2Date             PROCEDURE(ULONG,*LONG,*LONG)   !!Posix Time --> Clarion Standard Date & Time

Date2Posix           PROCEDURE  (Date1,Time1,PosixTime)    ! Declare Procedure
  CODE
   ! 1 day = 86400 seconds
   if Date1 or Time1 then
      POSIXTime = (Date1 - 38101)
      POSIXTime *= 86400
      POSIXTime = POSIXTime + (5*3600 + 24*60 + 16)
      if ~omitted(2) then
         POSIXTime += (Time1 / 100)
      else                            ! если пропущен 2-й параметр (время),
         POSIXTime += 86400           ! то добавить полные сутки
      .
   else
      clear(PosixTime)
   .
 
Posix2Date           PROCEDURE  (PosixTime,Date1,Time1)    ! Declare Procedure
  CODE
!  1 day = 86400 seconds
   if POSIXTime then
      POSIXTime = POSIXTime - (5*3600 + 24*60 + 16)
      Date1 = POSIXTime / 86400 + 38101
      Time1 = (POSIXTime % 86400) * 100 + 1
   else
      clear(Date1)
      clear(Time1)
   .  
Только проверьте, ничего ли я не напутал с вычислениями. Уже не помню, для чего делается коррекция на 5:24:16. Проще это выкинуть совсем.
Аватара пользователя
Admin
Администратор
Сообщения: 3959
Зарегистрирован: 05 Июль 2005, 15:59
Откуда: Хабаровск
Благодарил (а): 25 раз
Поблагодарили: 22 раза
Контактная информация:

Поле типа TimeStamp.

Сообщение Admin »

Не понял откуда взялось число 38101
По моему оно должно быть 61730. Разница в днях между 28-12-1800 и 01-01-1970
Рай совершает ошибки ничуть не реже чем ад. Просто у него хорошая пресса
Аватара пользователя
vic7tar
Ветеран
Сообщения: 365
Зарегистрирован: 09 Февраль 2017, 20:12

Поле типа TimeStamp.

Сообщение vic7tar »

А я вот не пойму, где спрятан смысл в неиспользовании в if-е , действительно, просто двух сравнений?
C10, Win10x64
Аватара пользователя
vic7tar
Ветеран
Сообщения: 365
Зарегистрирован: 09 Февраль 2017, 20:12

Поле типа TimeStamp.

Сообщение vic7tar »

Внесу и свою маленькую лептушку:

Код: Выделить всё

  map
    module('CLib')
           StrCmp(*cstring, *cstring), signed, raw, name('_strcmp')
    end
  end

  code
  ...
  dt1 = format(d1,@N07) & format(t1,@N07)         ! dt1   cstring(15)
  dt2 = format(d2,@N07) & format(t2,@N07)         ! dt1   cstring(15)

 ! или так, для визуального контроля
 ! dt1 = format(d1,@d12) & format(t1,@t5)
 ! dt2 = format(d2,@d12) & format(t2,@t5)
 
  if  StrCmp(dt1, dt2)                   !     =0  ->  dt1=dt2     0<  ->  dt1>dt2     <0  ->  dt1<dt2
  ...
  end
C10, Win10x64
Yufil
Ветеран движения
Сообщения: 1277
Зарегистрирован: 16 Май 2006, 14:34
Контактная информация:

Поле типа TimeStamp.

Сообщение Yufil »

Ещё надо, наверное, иметь в виду, что кларионовское время считается с шагом 0.01 секунды. Поэтому два равных времени могут и отличаться.

У меня в одной из задач требуется скопировать ( и, возможно, преобразовать при этом - например, AVI в MP4 ) пачку файлов, причём в выходном каталоге файлы-копии уже могут существовать. Чтобы ускорить процесс, после копирования/преобразования выходному файлу присваивается в точности те же самые дата и время, что и исходному, так что если целевой файл уже существует и дата/время исходного и целевого файла совпадают, копирование не выполняется ( длина может и не совпадать ) .

Вдруг выяснилось, что исходный файл и копия с одинаковой датой и временем таковыми не считаются, причём, естественно, этого никаким боком не видно. В самом деле, дата и время считывались кларионовской DIRECTORY - и слегка отличались от истинных... Поэтому отличие времени менее 0.01 секунды ( возможно, и больше) следует тихо игнорировать...
Ответить