Преобразование дат туда-обратно
Модератор: Модераторы
- Troublemaker
- постоялец
- Сообщения: 292
- Зарегистрирован: 16.04.2008 13:00:44
- Откуда: Биробиджан, Дальний Восток
- Контактная информация:
Преобразование дат туда-обратно
Хочу хранить даты во внешнем текстовом файле в универсальном формате: yyyymmddhhnnss.
Есть DateTimeToStr(дата):строка, и есть FormatDateTime(формат,дата):строка.
Присвоение нужной строки longDateFormat и shortDateFormat ничего не дало, поэтому для сохранения в файл использую явное: formatdatetime('yyyymmddhhnnss',дата), здесь всё путем.
Но как произвести обратное форматирование - из строки в этом формате получить дату/время? Нашел только StrToDateTime, которая, в отличие от дельфи, не поддерживает оверлоада с указанием строки форматирования.
Опять свой парсер писать?
Есть DateTimeToStr(дата):строка, и есть FormatDateTime(формат,дата):строка.
Присвоение нужной строки longDateFormat и shortDateFormat ничего не дало, поэтому для сохранения в файл использую явное: formatdatetime('yyyymmddhhnnss',дата), здесь всё путем.
Но как произвести обратное форматирование - из строки в этом формате получить дату/время? Нашел только StrToDateTime, которая, в отличие от дельфи, не поддерживает оверлоада с указанием строки форматирования.
Опять свой парсер писать?
- Troublemaker
- постоялец
- Сообщения: 292
- Зарегистрирован: 16.04.2008 13:00:44
- Откуда: Биробиджан, Дальний Восток
- Контактная информация:
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
- Откуда: Биробиджан, Дальний Восток
- Контактная информация:
DateSeparator:char.
На char(0) не реагирует никак, вылезают те же ошибки, на ' ' (пустая строка, не пробел) ругается компилятор: "нужен чар, а даешь строковую константу"
На char(0) не реагирует никак, вылезают те же ошибки, на ' ' (пустая строка, не пробел) ругается компилятор: "нужен чар, а даешь строковую константу"
- Sergei I. Gorelkin
- энтузиаст
- Сообщения: 1409
- Зарегистрирован: 24.07.2005 14:40:41
- Откуда: Зеленоград
Когда компоненты даты/времени известны в виде чисел, удобно пользоваться EncodeDate, EncodeTime, ComposeDateTime, ReplaceDate, ReplaceTime.
- Troublemaker
- постоялец
- Сообщения: 292
- Зарегистрирован: 16.04.2008 13:00:44
- Откуда: Биробиджан, Дальний Восток
- Контактная информация:
Спасибо за наводку, так и сделаю, напишу на их основе свои парсеры. Я же помню, что, вроде, были еще в ДОС какие-то менее навороченные функции чем DT2S.Sergei I. Gorelkin писал(а):EncodeDate
С тоской снова вспоминаю кларион - для дат и времен зашиты возможные форматы (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-файла и изменить его на какую-то величину)
- Sergei I. Gorelkin
- энтузиаст
- Сообщения: 1409
- Зарегистрирован: 24.07.2005 14:40:41
- Откуда: Зеленоград
Troublemaker писал(а):И плюс его неявное приведение типов, когда:
В FPC/Delphi можно воспользоваться Variant - тоже будет неявное приведение типов. Причем, возможно, полные штаны
Troublemaker писал(а):(не надо спрашивать, зачем такое может понадобиться. Самое простое: прочесть параметр из ini-файла и изменить его на какую-то величину)
Так у ini-файлов есть методы ReadInteger/WriteInteger для непосредственной работы с целыми числами.
- Troublemaker
- постоялец
- Сообщения: 292
- Зарегистрирован: 16.04.2008 13:00:44
- Откуда: Биробиджан, Дальний Восток
- Контактная информация:
А кто сказал, что я работаю со штатными ини? Сейчас у меня делается так:Sergei I. Gorelkin писал(а):у ini-файлов есть методы
1. на диске хранится шифрованный ини
2. при запуске он грузится в мемстрим, дешифруется и копируется в stringlist, с которым, собсно, и идет вся работа
3. при завершении stringlist копируется обратно в стрим, шифруется и сбрасывается на диск.
Вот как такой ини
Код: Выделить всё
ElapsedTime=18991230000014
Runs=2
LastRun=20080513022049
Код: Выделить всё
<
000Edt19
05e=2unRaLe98
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 секунд:
Возможно. Вот только в Clarion компилятор выполняет нужные приведения в зависимости от типа результата, без использования неопределенных типов вроде вариант-а.Sergei I. Gorelkin писал(а):В FPC/Delphi можно воспользоваться Variant
Особенно мне нравилось (была необходимость) делать примерно такое:
a:long;
b,c:string
a=b+c;
причем в а попадала именно сумма вида
a=strtofloat(b)+strtofloat(c)
А еще здорово не хватает одного очень удобного типа данных. Не помню, чтобы в Паскале я такое встречал - packed decimal. Смысл его в том, что в каждом байте такого числа хранится две цифры. В первом ниббле первого байта этого числа хранился знак, и где-то еще (просто не помню, где именно) - разрядность, позиция десятичной точки и порядок. То есть, число было всегда целым, не нужна была плавающая арифметика, а все арифметические действия производились (RTL-ом, разумеется) по тому же принципу, по которому мы считаем на бумаге в столбик, учитывая положение точки и не заморачиваясь дополнительными кодами для представления дробной части числа. Для бизнес-арифметики - самый подходящий тип данных.
- Sergei I. Gorelkin
- энтузиаст
- Сообщения: 1409
- Зарегистрирован: 24.07.2005 14:40:41
- Откуда: Зеленоград
Troublemaker писал(а):А кто сказал, что я работаю со штатными ини? Сейчас у меня делается так:
У TMemIniFile есть методы GetStrings и SetStrings, которые сохраняют его в TStrings и загружают из TStrings, соответственно. Эти TStrings можно шифровать, в то же время не теряя возможности работать штатными средствами с ini file.
Troublemaker писал(а):А еще здорово не хватает одного очень удобного типа данных. Не помню, чтобы в Паскале я такое встречал - packed decimal.
Есть и такое, это модуль FmtBcd. Только этот тип данных не является встроенным в язык, а реализован в коде. Кроме того, он довольно удобно отображается все в тот же Variant. Кстати, Variant всегда имеет определенный тип, но этот тип может изменяться во время выполнения.
- Troublemaker
- постоялец
- Сообщения: 292
- Зарегистрирован: 16.04.2008 13:00:44
- Откуда: Биробиджан, Дальний Восток
- Контактная информация:
Sergei I. Gorelkin писал(а):Эти TStrings можно шифровать
Речь, как я понимаю, о шифровании только значений и имен параметров, с сохранением общей структуры файла, что-то вроде:
было:
param=value
стало:
$%^@!=&^%#$
Так?
А где этот MemIniFile берут? В описании RTL (rtl.pdf от августа 2007) его нет.
Да-да, именно BCD - название вылетело из головы.Sergei I. Gorelkin писал(а):FmtBcd
- alexs
- долгожитель
- Сообщения: 4069
- Зарегистрирован: 15.05.2005 23:17:07
- Откуда: г.Ставрополь
- Контактная информация:
Лучше используй фичи паскаля, чем пытаться подогнать его к другому языку (тем более интерпретируемому). Variant - самый худшый выбор о быстродействию и контролю ошибок. Не явное преобразование типов - 100% путь к трудноотлавливаемым ошибкам.
Если у тебя все тетсты хранятся в виде струдкут в оперативке - зачем их приводить к текстовому виду (хоть и зхашифрованному) на диске? пиши эти структуры напрямую на диск. И проблем меньше и быстрее.
Если у тебя все тетсты хранятся в виде струдкут в оперативке - зачем их приводить к текстовому виду (хоть и зхашифрованному) на диске? пиши эти структуры напрямую на диск. И проблем меньше и быстрее.
- Troublemaker
- постоялец
- Сообщения: 292
- Зарегистрирован: 16.04.2008 13:00:44
- Откуда: Биробиджан, Дальний Восток
- Контактная информация:
Ошибочка, сэр. Язык компилируемый, с созданием нормальных obj и exe. (хотя в ДОС-версиях в комплекте был и интерпретатор шитого кода, который было удобно использовать для отладки)alexs писал(а):интерпретируемому
Да и подгонять не пытаюсь, просто незнакомое лучше осваивается, если его можно как-то привязать к имеющейся базе.
Отрабатываю общую методику работы. Готовлюсь к хранению более серьезных данных. На этом ini выловил большинство подводных камней, которые могли бы здорово осложнить жизнь на более сложных структурах и б́́ольших объемах данных.alexs писал(а):ачем их приводить к текстовому виду (хоть и зхашифрованному) на диске?
Получилось что-то вроде лабораторной работы перед работой на производстве.
Добавлено спустя 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 писал(а):Программа (без всяких сжатий, standalone exe), выводит стандартный msgbox - в аттаче. Сколько займет аналогичная на Lazarus? Не холивара ради...
~15 метров на лазаре и ~2 метра на чистом fpc.
