Форум: "Основная";
Текущий архив: 2007.06.24;
Скачать: [xml.tar.bz2];
ВнизКак преобразовать строку в дату? Найти похожие ветки
← →
kull (2007-04-23 23:05) [0]Есть дата в виде строки в формате "dd/MMM/yy"
Надо преобразовать ее в TDateTime.
Что то я не могу понять как это сделать?
← →
{RASkov} (2007-04-23 23:22) [1]function StrToDate(const S: string; const FormatSettings: TFormatSettings): TDateTime;
← →
kull (2007-04-23 23:28) [2]При данном формате даты эта функция (StrToDate) не помогает=(
Либо я что-то не так делаю...
из хелпа:
S must consist of two or three numbers, separated by the character defined by the DateSeparator global variable or its TFormatSettings equivalent.
← →
kull (2007-04-23 23:30) [3]А "dd/MMM/yy" в виде даты выглядит так 24/апр/07
← →
{RASkov} (2007-04-24 00:41) [4]> даты выглядит так 24/апр/07
Ну тогда походу только в ручную, день и год проще, а вот месяц анализирую, сравнивай, приводи....
или так:const SDt: String = "24/апр/07";
var S: String;
D: TDate;
FD: TFormatSettings;
begin
FD.DateSeparator:="/";
FD.ShortDateFormat:="dd/mmm/gg";
S:=StringReplace(SDt, "янв", "01", []);
S:=StringReplace(S, "фев", "02", []);
S:=StringReplace(S, "мар", "03", []);
S:=StringReplace(S, "апр", "04", []);
S:=StringReplace(S, "май", "05", []);
S:=StringReplace(S, "июн", "06", []);
S:=StringReplace(S, "июл", "07", []);
S:=StringReplace(S, "авг", "08", []);
S:=StringReplace(S, "сен", "09", []);
S:=StringReplace(S, "окт", "10", []);
S:=StringReplace(S, "ноя", "11", []);
S:=StringReplace(S, "дек", "12", []);
ShowMessage(S);
D:=StrToDate(S, FD);
ShowMessage(DateToStr(D));
end;
← →
kull (2007-04-24 00:48) [5]А я все же надеялся, что обойдется без "в ручную" =)
Спасибо =)
PS:
Есть еще переменная ShortMonthNames...
← →
{RASkov} (2007-04-24 00:55) [6]> Есть еще переменная ShortMonthNames...
ShortMonthNames: array[1..12] of string;
и дальше что? Это для вывода даты, а не для ее "распознования"...
Хотя может все и не так.... но вряд-ли.
← →
Германн © (2007-04-24 01:01) [7]
> kull (23.04.07 23:05)
>
> Есть дата в виде строки в формате "dd/MMM/yy"
> Надо преобразовать ее в TDateTime.
Имхо, это одна из наиболее сложных задач для решения в "общем" случае. Могу только дать несколько рекомендаций. Если Дата/Время вводится пользователем через интерфейс программы, то настоятельно рекомендую использовать для ввода данных компонент, заточенный именно под такую задачу. TDateTimePicker, TMonthCalendar, TDateEdit(RxLib) etc. Если же строка с датой получена извне интерфейса программы, то нужно заранее знать её точный формат. И вот тогда можно применить решение {RASkov} (24.04.07 00:41) [4]. Только с небольшим замечанием. Я не знаю такой overloaded версии StrToDate :( Но я и не знаю Д7.
← →
{RASkov} (2007-04-24 01:05) [8]> [7] Германн © (24.04.07 01:01)
> Я не знаю такой overloaded версии StrToDate :(
function StrToDate(const S: string;
const FormatSettings: TFormatSettings): TDateTime;
begin
if not TryStrToDate(S, Result, FormatSettings) then
ConvertErrorFmt(@SInvalidDate, [S]);
end;
function TryStrToDate(const S: string; out Value: TDateTime;
const FormatSettings: TFormatSettings): Boolean;
var
Pos: Integer;
begin
Pos := 1;
Result := ScanDate(S, Pos, Value, FormatSettings) and (Pos > Length(S));
end;
Дальше не буду :)
В сабже D7.
← →
kull (2007-04-24 01:15) [9]для "распознования" месяца я перегоняю ShortMonthNames в отсортированный TStringlist:
var
i: Integer;
begin
FShortMonths := TStringList.Create;
FShortMonths.Sorted := True;
for i := Low(ShortMonthNames) to High(ShortMonthNames) do
FShortMonths.AddObject(ShortMonthNames[i], TObject(i));
а дальше IndexOf или Find. Для получения номера месяца.
=)
← →
Германн © (2007-04-24 01:15) [10]
> {RASkov} (24.04.07 01:05) [8]
Да верю я, верю. Я только не знаю что происходит с date/time formatting variables при использовании этой функции. Нужно ли их сначала запомнить (до вызова сей функции), а потом восстановить старые значения.
← →
Германн © (2007-04-24 01:21) [11]
> kull (24.04.07 01:15) [9]
>
> для "распознования" месяца я перегоняю ShortMonthNames в
> отсортированный TStringlist:
>
> var
> i: Integer;
> begin
> FShortMonths := TStringList.Create;
> FShortMonths.Sorted := True;
> for i := Low(ShortMonthNames) to High(ShortMonthNames)
> do
> FShortMonths.AddObject(ShortMonthNames[i], TObject(i));
>
>
> а дальше IndexOf или Find. Для получения номера месяца.
> =)
>
МолодЕц! Так держать! :-)
Февраль назначаем последним месяцем в году! Ес-сно, он ведь самый короткий. :-)
← →
{RASkov} (2007-04-24 01:41) [12]> [10] Германн © (24.04.07 01:15)
> Нужно ли их сначала запомнить (до вызова сей функции), а потом восстановить старые значения.
Не надо. Переменную типа TFormatSettings нужно вначале заполнить - GetLocaleFormatSettings(LCID: Integer; var FormatSettings: TFormatSettings); - Это в хелпе рекомендуют.
Т.е. в моем примере нужно было так сделать:
GetLocaleFormatSettings(0, FD);
FD.DateSeparator:="/";
FD.ShortDateFormat:="d/m/g";
.........
D:=StrToDate(S, FD);
Хотя, там и надо-то было сепаратор и расположение.....так, что GetLocaleFormatSettings и не обязательна.... имхо.
> [9] kull (24.04.07 01:15)
> для "распознования" месяца я перегоняю ShortMonthNames в отсортированный TStringlist:
Ты уж тогда лучше его не сортируй, пусть будет как есть :) Хотя в объектах у тебя хранится порядковый номер месяца, но не к чему это. :)
← →
Германн © (2007-04-24 01:52) [13]
> {RASkov} (24.04.07 01:41) [12]
>
> > [10] Германн © (24.04.07 01:15)
> > Нужно ли их сначала запомнить (до вызова сей функции),
> а потом восстановить старые значения.
>
> Не надо. Переменную типа TFormatSettings нужно вначале заполнить
> - GetLocaleFormatSettings(LCID: Integer; var FormatSettings:
> TFormatSettings); - Это в хелпе рекомендуют.
Ну а потом, а потом что будет? С date/time formatting variables?
← →
{RASkov} (2007-04-24 02:05) [14]> Ну а потом, а потом что будет? С date/time formatting variables?
Да ничего с ними не будет.... она нужна только для "формата строки" при "преобразовании"....
Вот F1:
SysUtils
Category
datetime routines
Delphi syntax:
function StrToDate(const S: string): TDateTime; overload;
function StrToDate(const S: string; const FormatSettings: TFormatSettings): TDateTime; overload;
C++ syntax:
extern PACKAGE System::TDateTime __fastcall StrToDate(const AnsiString S);
extern PACKAGE System::TDateTime __fastcall StrToDate(const AnsiString S, const TFormatSettings FormatSettings);
Description
Call StrToDate to parse a string that specifies a date. If S does not contain a valid date, StrToDate raises an EConvertError exception.
S must consist of two or three numbers, separated by the character defined by the DateSeparator global variable or its TFormatSettings equivalent. The order for month, day, and year is determined by the ShortDateFormat global variable or its TFormatSettings equivalent--possible combinations are m/d/y, d/m/y, and y/m/d.
If S contains only two numbers, it is interpreted as a date (m/d or d/m) in the current year.
Year values between 0 and 99 are converted using the TwoDigitYearCenturyWindow. This value is stored either in a global variable (first form) or as a field in the FormatSettings parameter (second form) See "Currency and Date-Time Formatting Variables" for more information.
The first form of StrToDate is not thread-safe, because it uses localization information contained in global variables. The second form of StrToDate, which is thread-safe, refers to localization information contained in the FormatSettings parameter. Before calling the thread-safe form of StrToDate, you must populate FormatSettings with localization information. To populate FormatSettings with a set of default locale values, call GetLocaleFormatSettings.
I"m sorry :)
← →
{RASkov} (2007-04-24 02:10) [15]> [13] Германн © (24.04.07 01:52)
> Ну а потом, а потом что будет? С date/time formatting variables?
Т.е. вот ответ на твой вопрос
TFormatSettings defines a thread-safe string formatting context.
Unit
SysUtils
Delphi syntax:
type
TFormatSettings = record
CurrencyFormat: Byte;
NegCurrFormat: Byte;
ThousandSeparator: Char;
DecimalSeparator: Char;
CurrencyDecimals: Byte;
DateSeparator: Char;
TimeSeparator: Char;
ListSeparator: Char;
CurrencyString: string;
ShortDateFormat: string;
LongDateFormat: string;
TimeAMString: string;
TimePMString: string;
ShortTimeFormat: string;
LongTimeFormat: string;
ShortMonthNames: array[1..12] of string;
LongMonthNames: array[1..12] of string;
ShortDayNames: array[1..7] of string;
LongDayNames: array[1..7] of string;
TwoDigitYearCenturyWindow: Word;
end;
Description
TFormatSettings defines a data structure containing locale information used by string formatting routine. Each member of TFormatSettings is equivalent to the global variable with the same name. A variable of type TFormatSettings defines a thread-safe context that formatting functions can use in place of the default global context, which is not thread-safe.
To create and use the thread-safe environment defined by TFormatSettings, follow these steps:
Define a variable of type TFormatSettings
Call GetLocaleFormatSettings to populate the TFormatSettings variable with locale information.
Pass the TFormatSettings variable as the last parameter of the string formatting routine.
Each routine that accepts a TFormatSettings parameter is thread-safe, and is an overload of an equivalent function that refers to the global formatting variables.
Еще раз I"m sorry :)
← →
Германн © (2007-04-24 02:13) [16]
> The second form of StrToDate, which is thread-safe, refers
> to localization information contained in the FormatSettings
> parameter. Before calling the thread-safe form of StrToDate,
> you must populate FormatSettings with localization information.
> To populate FormatSettings with a set of default locale
> values, call GetLocaleFormatSettings.
> I"m sorry :)
Этот текст ничего не говорит про значения date/time formatting variables.
← →
{RASkov} (2007-04-24 02:26) [17]> [16] Германн © (24.04.07 02:13)
Эх... Германн получим мы... с утра :)
Description
TFormatSettings defines a data structure containing locale information used by string formatting routine. Each member of TFormatSettings is equivalent to the global variable with the same name. A variable of type TFormatSettings defines a thread-safe context that formatting functions can use in place of the default global context, which is not thread-safe.
Описание
TFormatSettings определяет структуру данных, содержащую информацию места действия, используемую строкой, форматирующей рутину. Каждый член TFormatSettings эквивалентен глобальной переменной с тем же самым названием(именем). Переменная типа TFormatSettings определяет безопасный тематикой контекст, который форматирующие функции могут использовать вместо заданного по умолчанию глобального контекста, который - не безопасен тематикой.
Переводил Промтом, так как сам в англ никак.... :(
← →
Германн © (2007-04-24 02:41) [18]
> Переводил Промтом, так как сам в англ никак.... :(
>
Да не надо мне перевода. С аглицкого на русский перевод для меня не проблема.
Может я не "пояснил суть".
Вот пример. Я у себя в программе вывожу (в интерфейс, в лог и т.п.) Дату/время функцией DateTimeToStr (Я то вообще то её и не пользую, предпочитаю FormatDateTime, но это "мой скус"). Сия функция использует "date/time formatting variables". Так вот вопрос. Сия функция будет всегда одинаково выводить строковое представление даты/времени? Не повлияет ли на сей вывод вызов function StrToDate(const S: string; const FormatSettings: TFormatSettings)?
← →
{RASkov} (2007-04-24 02:55) [19]> [18] Германн © (24.04.07 02:41)
var FD: TFormatSettings;
begin
ShowMessage(FD.ShortDateFormat); // ""
ShowMessage(ShortDateFormat); // "dd.MM.yyyy"
FD.ShortDateFormat:="YY/DD/mmmm";
ShowMessage(FD.ShortDateFormat); // "YY/DD/mmmm"
ShowMessage(ShortDateFormat); // "dd.MM.yyyy"
end;
Все нормально.
TFormatSettings; - record "системных переменных" (имена полей и их тип совподают с сис. перем. и только), и на их системные аналоги она не влияет...
← →
Германн © (2007-04-24 03:08) [20]
> Все нормально.
> TFormatSettings; - record "системных переменных" (имена
> полей и их тип совподают с сис. перем. и только), и на их
> системные аналоги она не влияет...
>
Готов поверить. Завтра проверю на BDS2006. Ты не обижайся. Когда пошла такая пьянка, то доверяй, но проверяй! :-)
← →
{RASkov} (2007-04-24 03:24) [21]> [20] Германн © (24.04.07 03:08)
> Завтра проверю на BDS2006. Ты не обижайся.
Извини Германн, даже и не подумаю :) А.... а завтра - это 24 или 25 :)
Расскажешь потом результат проверки...
← →
kull (2007-04-24 11:17) [22]
> Германн © (24.04.07 01:21) [11]
> {RASkov} (24.04.07 01:41) [12]
А подумать? =)MonthNum := Word(FShortMonths.Objects[FShortMonths.IndexOf(MontStr)]);
К примеру...
← →
kull (2007-04-24 11:20) [23]Обычно сортировку используют для ускорения поиска...
← →
kull (2007-04-24 11:24) [24]
> Германн © (24.04.07 01:21) [11]
Еще я не понял почему февраль, а не январь? =)
← →
{RASkov} (2007-04-24 16:32) [25]> kull
> Обычно сортировку используют для ускорения поиска...
> MonthNum := Word(FShortMonths.Objects[FShortMonths.IndexOf(MontStr)]);
Ты думаешь тем самым увеличил скорость поиска в 12 значном списке? :)
← →
{RASkov} (2007-04-24 16:39) [26]Хотя может оно и верно в твоем случае, но с другой точки зрения. С точки зрения - номер месяца не должен зависеть от местоположения имени месяца в массиве месяцев. Ну а скорость... может и выиграешь чуток :)
← →
kull (2007-04-24 23:57) [27]чуток - это в 3 раза, если, например, месяц - декабрь =)
← →
Германн © (2007-04-25 00:14) [28]
> kull (24.04.07 23:57) [27]
>
> чуток - это в 3 раза, если, например, месяц - декабрь =)
>
А в попугаях, то бишь микросекундах, это сколько будет? :)
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2007.06.24;
Скачать: [xml.tar.bz2];
Память: 0.53 MB
Время: 0.038 c