Преобразование дат туда-обратно

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Преобразование дат туда-обратно

Сообщение Troublemaker » 12.05.2008 15:41:17

Хочу хранить даты во внешнем текстовом файле в универсальном формате: yyyymmddhhnnss.

Есть DateTimeToStr(дата):строка, и есть FormatDateTime(формат,дата):строка.
Присвоение нужной строки longDateFormat и shortDateFormat ничего не дало, поэтому для сохранения в файл использую явное: formatdatetime('yyyymmddhhnnss',дата), здесь всё путем.

Но как произвести обратное форматирование - из строки в этом формате получить дату/время? Нашел только StrToDateTime, которая, в отличие от дельфи, не поддерживает оверлоада с указанием строки форматирования.

Опять свой парсер писать?
Аватара пользователя
Troublemaker
постоялец
 
Сообщения: 292
Зарегистрирован: 16.04.2008 13:00:44
Откуда: Биробиджан, Дальний Восток

Re: Преобразование дат туда-обратно

Сообщение Attid » 12.05.2008 15:47:00

ShortDateFormat ?
Аватара пользователя
Attid
долгожитель
 
Сообщения: 2586
Зарегистрирован: 27.10.2006 17:29:15
Откуда: 44°32′23.63″N 41°2′25.2″E

Re: Преобразование дат туда-обратно

Сообщение Troublemaker » 12.05.2008 15:55:08

Attid писал(а):ShortDateFormat ?

задавал, бесполезно.
Судя по исходникам, там какая-то непонятная обработка, вроде как в формате должен присутствовать разделитель. Сейчас попробую еще одну авантюру...

Добавлено спустя 5 минут 29 секунд:
Из файла читается:
MyIni.Values[ciniElapsedTime]='ElapsedTime=18991230000005'

После установки:
cdtfLongDate='yyyymmdd';
cdtfLongTime='hhnnss';
cdtfLongDateTime='yyyymmddhhnnss';
...
ShortDateFormat:=cdtfLongDate;
LongDateFormat:=cdtfLongDate;
LongTimeFormat:=cdtfLongTime;
ShortTimeFormat:=cdtfLongTime;

StrToDateTime(MyIni.Values[ciniElapsedTime]) ругается на эксепшн: 2008-05-1899 not valid date spec.
Аватара пользователя
Troublemaker
постоялец
 
Сообщения: 292
Зарегистрирован: 16.04.2008 13:00:44
Откуда: Биробиджан, Дальний Восток

Re: Преобразование дат туда-обратно

Сообщение Attid » 12.05.2008 16:25:50

а если попробывать DateSeparator обнулить ? хотя быстрее свой DateTime2Str и Str2DateTime написать =)
Аватара пользователя
Attid
долгожитель
 
Сообщения: 2586
Зарегистрирован: 27.10.2006 17:29:15
Откуда: 44°32′23.63″N 41°2′25.2″E

Re: Преобразование дат туда-обратно

Сообщение Troublemaker » 12.05.2008 16:33:22

DateSeparator:char.
На char(0) не реагирует никак, вылезают те же ошибки, на ' ' (пустая строка, не пробел) ругается компилятор: "нужен чар, а даешь строковую константу"
Аватара пользователя
Troublemaker
постоялец
 
Сообщения: 292
Зарегистрирован: 16.04.2008 13:00:44
Откуда: Биробиджан, Дальний Восток

Re: Преобразование дат туда-обратно

Сообщение alexs » 12.05.2008 16:43:36

Руками распарси указанную строку - формат строго позиционный. Будет даже быстрее, чем использовать стандартные функции.
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4060
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Re: Преобразование дат туда-обратно

Сообщение Sergei I. Gorelkin » 12.05.2008 16:55:48

Когда компоненты даты/времени известны в виде чисел, удобно пользоваться EncodeDate, EncodeTime, ComposeDateTime, ReplaceDate, ReplaceTime.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1406
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: Преобразование дат туда-обратно

Сообщение Troublemaker » 12.05.2008 17:43:27

Sergei I. Gorelkin писал(а):EncodeDate
Спасибо за наводку, так и сделаю, напишу на их основе свои парсеры. Я же помню, что, вроде, были еще в ДОС какие-то менее навороченные функции чем DT2S.

С тоской снова вспоминаю кларион - для дат и времен зашиты возможные форматы (2/4 цифры года, 2 месяца, 2 дня во всех комбинациях - d/m/y, y/m/d, m/d/y), а сами даты и времена хранятся в виде длинных целых - дней от 1.1.1900 и секунд от полуночи. Для форматирования указываешь код формата и желаемый разделитель, и всё, вся суета на этом кончалась.

И плюс его неявное приведение типов, когда:

var a:string; b:byte;

a='123'+32 давало '155' (один пять пять), a
b='123'+32 давало 155 (сто пятьдесят пять)

А то сильно достает мелочевка вроде:

b=StrToInt('123')+32
или
a=IntToStr(StrToInt('123')+32)

(не надо спрашивать, зачем такое может понадобиться. Самое простое: прочесть параметр из ini-файла и изменить его на какую-то величину)
Аватара пользователя
Troublemaker
постоялец
 
Сообщения: 292
Зарегистрирован: 16.04.2008 13:00:44
Откуда: Биробиджан, Дальний Восток

Re: Преобразование дат туда-обратно

Сообщение Sergei I. Gorelkin » 12.05.2008 18:49:14

Troublemaker писал(а):И плюс его неявное приведение типов, когда:

В FPC/Delphi можно воспользоваться Variant - тоже будет неявное приведение типов. Причем, возможно, полные штаны :)

Troublemaker писал(а):(не надо спрашивать, зачем такое может понадобиться. Самое простое: прочесть параметр из ini-файла и изменить его на какую-то величину)

Так у ini-файлов есть методы ReadInteger/WriteInteger для непосредственной работы с целыми числами.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1406
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: Преобразование дат туда-обратно

Сообщение Troublemaker » 12.05.2008 19:28:28

Sergei I. Gorelkin писал(а):у ini-файлов есть методы
А кто сказал, что я работаю со штатными ини? Сейчас у меня делается так:
1. на диске хранится шифрованный ини
2. при запуске он грузится в мемстрим, дешифруется и копируется в stringlist, с которым, собсно, и идет вся работа
3. при завершении stringlist копируется обратно в стрим, шифруется и сбрасывается на диск.

Вот как такой ини
Код: Выделить всё
ElapsedTime=18991230000014
Runs=2
LastRun=20080513022049
выглядит на диске:
Код: Выделить всё
<
000Edt19
05e=2un RaLe98
iRщ1=a20

44Ts=220p3l1
(метод шифрования см. во всё той же ПЗ)

Что до врапперов-парсеров универсального формата, то может быть кому-то сэкономится время (еще не решил, нужны ли будут процедуры, но пока решил оставить и функции и процедуры):
Код: Выделить всё
unit CommonUtils;

interface
uses  SysUtils,strutils;

procedure DT2S(indt:TDateTime;var outs:string);
function DT2S(indt:TDateTime):string;
procedure S2DT(ins:string;var outd:TDateTime);
function S2DT(ins:string):TDateTime;

implementation

//преобразую yyyymmddhhnnss в tdatetime и обратно
function DT2S(indt:TDateTime):string;
begin
  Result:=FormatDateTime('yyyymmddhhnnss',indt);
end;

procedure DT2S(indt:TDateTime;var outs:string);
begin
  outs:=DT2S(indt)
end;

function S2DT(ins:string):TDateTime;
begin
  Result:=EncodeDate(
            StrToInt(LeftStr(ins,4)),
            StrToInt(MidStr(ins,5,2)),
            StrToInt(MidStr(ins,7,2)))+
          EncodeTime(
            StrToInt(MidStr(ins,9,2)),
            StrToInt(MidStr(ins,11,2)),
            StrToInt(LeftStr(ins,2)),
            0);
end;

procedure S2DT(ins:string;var outd:TDateTime);
begin
  outd:=S2DT(ins);
end;

end.


Добавлено спустя 10 минут 12 секунд:
Sergei I. Gorelkin писал(а):В FPC/Delphi можно воспользоваться Variant
Возможно. Вот только в Clarion компилятор выполняет нужные приведения в зависимости от типа результата, без использования неопределенных типов вроде вариант-а.

Особенно мне нравилось (была необходимость) делать примерно такое:

a:long;
b,c:string

a=b+c;

причем в а попадала именно сумма вида

a=strtofloat(b)+strtofloat(c)

А еще здорово не хватает одного очень удобного типа данных. Не помню, чтобы в Паскале я такое встречал - packed decimal. Смысл его в том, что в каждом байте такого числа хранится две цифры. В первом ниббле первого байта этого числа хранился знак, и где-то еще (просто не помню, где именно) - разрядность, позиция десятичной точки и порядок. То есть, число было всегда целым, не нужна была плавающая арифметика, а все арифметические действия производились (RTL-ом, разумеется) по тому же принципу, по которому мы считаем на бумаге в столбик, учитывая положение точки и не заморачиваясь дополнительными кодами для представления дробной части числа. Для бизнес-арифметики - самый подходящий тип данных.
Аватара пользователя
Troublemaker
постоялец
 
Сообщения: 292
Зарегистрирован: 16.04.2008 13:00:44
Откуда: Биробиджан, Дальний Восток

Re: Преобразование дат туда-обратно

Сообщение Sergei I. Gorelkin » 12.05.2008 21:07:15

Troublemaker писал(а):А кто сказал, что я работаю со штатными ини? Сейчас у меня делается так:

У TMemIniFile есть методы GetStrings и SetStrings, которые сохраняют его в TStrings и загружают из TStrings, соответственно. Эти TStrings можно шифровать, в то же время не теряя возможности работать штатными средствами с ini file.

Troublemaker писал(а):А еще здорово не хватает одного очень удобного типа данных. Не помню, чтобы в Паскале я такое встречал - packed decimal.

Есть и такое, это модуль FmtBcd. Только этот тип данных не является встроенным в язык, а реализован в коде. Кроме того, он довольно удобно отображается все в тот же Variant. Кстати, Variant всегда имеет определенный тип, но этот тип может изменяться во время выполнения.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1406
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: Преобразование дат туда-обратно

Сообщение Troublemaker » 13.05.2008 07:30:14

Sergei I. Gorelkin писал(а):Эти TStrings можно шифровать

Речь, как я понимаю, о шифровании только значений и имен параметров, с сохранением общей структуры файла, что-то вроде:

было:
param=value

стало:
$%^@!=&^%#$

Так?

А где этот MemIniFile берут? В описании RTL (rtl.pdf от августа 2007) его нет.
Sergei I. Gorelkin писал(а):FmtBcd
Да-да, именно BCD - название вылетело из головы.
Аватара пользователя
Troublemaker
постоялец
 
Сообщения: 292
Зарегистрирован: 16.04.2008 13:00:44
Откуда: Биробиджан, Дальний Восток

Re: Преобразование дат туда-обратно

Сообщение alexs » 13.05.2008 07:46:18

Лучше используй фичи паскаля, чем пытаться подогнать его к другому языку (тем более интерпретируемому). Variant - самый худшый выбор о быстродействию и контролю ошибок. Не явное преобразование типов - 100% путь к трудноотлавливаемым ошибкам.
Если у тебя все тетсты хранятся в виде струдкут в оперативке - зачем их приводить к текстовому виду (хоть и зхашифрованному) на диске? пиши эти структуры напрямую на диск. И проблем меньше и быстрее.
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4060
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Re: Преобразование дат туда-обратно

Сообщение Troublemaker » 13.05.2008 08:25:36

alexs писал(а):интерпретируемому
Ошибочка, сэр. Язык компилируемый, с созданием нормальных obj и exe. (хотя в ДОС-версиях в комплекте был и интерпретатор шитого кода, который было удобно использовать для отладки)
Да и подгонять не пытаюсь, просто незнакомое лучше осваивается, если его можно как-то привязать к имеющейся базе.
alexs писал(а):ачем их приводить к текстовому виду (хоть и зхашифрованному) на диске?
Отрабатываю общую методику работы. Готовлюсь к хранению более серьезных данных. На этом ini выловил большинство подводных камней, которые могли бы здорово осложнить жизнь на более сложных структурах и б́́ольших объемах данных.
Получилось что-то вроде лабораторной работы перед работой на производстве. :wink:

Добавлено спустя 1 час 14 минут 7 секунд:
Про интерпретацию.

hello.prj
Код: Выделить всё
-- Hello
#noedit
#system win32
#model clarion lib
#set RELEASE = on
#pragma debug(vid=>off)
#pragma optimize(cpu=>386)
#compile "hello.clw"
#link "hello.exe"


hello.clw
Код: Выделить всё
hello   program
    map !список процедур в данном модуле, сейчас он пуст, но требуется обязательно
    end

    code
    message('Hello world!','Привет, мир!')


Программа (без всяких сжатий, standalone exe), выводит стандартный msgbox - в аттаче. Сколько займет аналогичная на Lazarus? Не холивара ради... :)
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Аватара пользователя
Troublemaker
постоялец
 
Сообщения: 292
Зарегистрирован: 16.04.2008 13:00:44
Откуда: Биробиджан, Дальний Восток

Re: Преобразование дат туда-обратно

Сообщение B4rr4cuda » 13.05.2008 09:57:13

Troublemaker писал(а):Программа (без всяких сжатий, standalone exe), выводит стандартный msgbox - в аттаче. Сколько займет аналогичная на Lazarus? Не холивара ради...

~15 метров на лазаре и ~2 метра на чистом fpc.
Аватара пользователя
B4rr4cuda
энтузиаст
 
Сообщения: 693
Зарегистрирован: 28.12.2007 07:48:35

След.

Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: Yandex [Bot] и гости: 6

Рейтинг@Mail.ru