Преобразование строки в TDateTime на основе произвольного формата

Есть ли способ в Delphi 5 преобразовать строку в TDateTime, где вы можете указать фактический формат для использования?

Я работаю на jobprocessor, который принимает задания от различных рабочих станций. Задачи имеют ряд параметров, некоторые из которых являются даты, но (к сожалению, и вне моего контроля), они передаются как строки. Поскольку рабочие места могут поступать из различных рабочих станций, фактический формат даты и времени используется для форматирования даты как строка может (и, конечно же, фактическая <ет> сделать ) различаются.

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

Я мог бы скопировать код библиотеки из модуля SysUtils в свои собственные методы и настроить их для работы с указанным форматом вместо глобальных переменных, но мне просто интересно, есть ли что-то более подходящее, что я пропустил.

С наилучшими пожеланиями, и заранее спасибо,

Виллем

ОБНОВЛЕНИЕ

Выражаясь более кратко:

Мне нужно что-то вроде StrToDate (или StrToDateTime), с дополнительной возможностью указания точного формата, который следует использовать, чтобы преобразовать строку в TDateTime.


person Willem van Rumpt    schedule 24.09.2010    source источник
comment
возможно дубликат обратной функции FormatDateTime   -  person NGLN    schedule 28.03.2012


Ответы (8)


Я создал такую ​​подпрограмму для модуля dateutils FreePascal, и ее легко портировать, если портирование вообще необходимо.

Код:

http://svn.freepascal.org/cgi-bin/viewvc.cgi/trunk/packages/rtl-objpas/src/inc/dateutil.inc?revision=30628&view=co

(Код последней (большой) процедура в конце файла)

документация:

http://www.freepascal.org/docs-html/rtl/dateutils/scandatetime.html

Обратите внимание, что это не полный обратный FormatDateTime, и она имеет некоторые расширения:

  • Обратный FormatDateTime не на 100% обратном, просто потому, что можно положить, например, время жетоны дважды в строке формата, и scandatetime не будет знать чего выбрать.

  • Строки, как кп не могут быть отменены безопасно. Например. 1:2 (2 минуты после 1) выдает 12, которое анализируется как 12:00, а затем пропускает символы для части «n».

    • trailing characters are ignored.
    • нет поддержки для Восточной Азии символов форматирования, так как они только окно.
    • нет поддержки MBCS.
  • Расширения

    • #9 eats whitespace.
    • пробелы в конце узора является необязательным.
    • ? соответствует любому символу.
    • Цитировать вышеуказанные символы действительно соответствуют полукокса.

(Я считаю, что эти комментарии немного устарели в смысле шляпу некоторая азиатская поддержка была добавлена ​​позже, но я не уверен)

person Marco van de Voort    schedule 24.09.2010
comment
Спасибо :) Я пойду по коду. Я знаю, что строка даты преобразования в ад, мягко говоря, так что я не ожидал показатель успеха 100%, всегда есть что-то не хватает (военных часовых поясов кто-нибудь;)). Только достойный способ, принимая DateTime в виде строки и разумный формат. - person Willem van Rumpt; 24.09.2010
comment
Еще раз спасибо. Несмотря на то, что я не использовал свой метод (ы) (выбирая вместо копирования из библиотеки коды), ваши было единственным жизнеспособным другим решением. Мое объяснение в том, что если бы я собирался скопировать код делаю в основном так же, как StrToDate с добавленной возможностью определения формата вместо того, чтобы использовать глобальную переменный, я предпочитаю это делать точно так же, как встроенный в один, просто не иметь это использовать глобальную переменную. Таким образом, как для меня, как и для моих нынешних работодателей, конечный результат ISIN соответствии с их окружающей средой, и более детерминированным (в тестировании, например). - person Willem van Rumpt; 24.09.2010
comment
Обновлена ​​ссылка. Тем временем файл был перемещен в SVN. - person Marco van de Voort; 18.06.2015

Используйте VarToDateTime вместо этого. Он поддерживает множество форматов дат более в строке и преобразует их автоматически.

var
  DateVal: TDateTime;
begin
  DateVal := VarToDateTime('23 Sep 2010');
  ShowMessage(DateToStr(DateVal));
end;

Я вижу, что вы используете Delphi 5. Некоторые версии Delphi необходимо добавить Варианты в пункте использования; большинство более поздних версий добавляют его для вас. Я не помню, какая категория Delphi 5 упал в.

person Ken White    schedule 24.09.2010
comment
Благодаря Кен, я не пробовал еще, но это звучит многообещающе. Все, что позволит избежать прокатки собственные преобразования (будь то вручную или путем копирования), безусловно, вариант. - person Willem van Rumpt; 24.09.2010
comment
Благодаря Кен, ты спас мой день тоже! - person Abdullah Ilgaz; 02.04.2018
comment
VarToDateTime будет работы для большинства настроек региона, но не в состоянии в стране, как Индонезия с помощью запятой (,), как DecimalSeparator и точка (.) как ThousandSeparator - person Chau Chee Yang; 10.10.2018
comment
Здорово! Он работает со строкой как Jul 29, 2019 5:37:55 AM - person Edwin Yip; 29.07.2019
comment
Thankyou, на использовании в XE3 является System.Variants - person Márcio Rossato; 22.08.2019

Более поздние версии Delphi могут принять дополнительную TFormatSettings аргумент функции преобразования строки. TFormatSettings представляет собой структуру, содержащую различные форматы глобальные переменные (ShortDateFormat, LongDateFormat, и т.д.). Таким образом, вы можете изменить эти значения в поточно-образом и даже для одного вызова.

Я не помню, в какой версии Delphi это было введено, но я почти уверен, что это было после Delphi 5.

Так что да, насколько я знаю, вы либо нужно синхронизировать каждый доступ к ShortDateFormat, или использовать другую функцию.

person Ken Bourassa    schedule 24.09.2010
comment
Вот чего я боялся. Уве сказали функциональность Я хочу есть от Delphi 7 и выше. К сожалению, это вне моего контроля. Другая функция будет :) - person Willem van Rumpt; 24.09.2010

Вот функция, и два его помощники, я написал разобрать строку с помощью точно DATETIME формата. А поскольку Stackoverflow также код-вики: вот все код:

class function TDateTimeUtils.TryStrToDateExact(const S, DateFormat: string; PivotYear: Integer;
        out Value: TDateTime): Boolean;
var
    Month, Day, Year: Integer;
    Tokens: TStringDynArray;
    CurrentToken: string;
    i, n: Integer;
    Partial: string;
    MaxValue: Integer;
    nCurrentYear: Integer;

    function GetCurrentYear: Word;
    var
        y, m, d: Word;
    begin
        DecodeDate(Now, y, m, d);
        Result := y;
    end;
begin
    Result := False;
{
    M/dd/yy

    Valid pictures codes are

        d       Day of the month as digits without leading zeros for single-digit days.
        dd      Day of the month as digits with leading zeros for single-digit days.
        ddd Abbreviated day of the week as specified by a LOCALE_SABBREVDAYNAME* value, for example, "Mon" in English (United States).
                Windows Vista and later: If a short version of the day of the week is required, your application should use the LOCALE_SSHORTESTDAYNAME* constants.
        dddd    Day of the week as specified by a LOCALE_SDAYNAME* value.

        M       Month as digits without leading zeros for single-digit months.
        MM      Month as digits with leading zeros for single-digit months.
        MMM Abbreviated month as specified by a LOCALE_SABBREVMONTHNAME* value, for example, "Nov" in English (United States).
        MMMM    Month as specified by a LOCALE_SMONTHNAME* value, for example, "November" for English (United States), and "Noviembre" for Spanish (Spain).

        y       Year represented only by the last digit.
        yy      Year represented only by the last two digits. A leading zero is added for single-digit years.
        yyyy    Year represented by a full four or five digits, depending on the calendar used. Thai Buddhist and Korean calendars have five-digit years. The "yyyy" pattern shows five digits for these two calendars, and four digits for all other supported calendars. Calendars that have single-digit or two-digit years, such as for the Japanese Emperor era, are represented differently. A single-digit year is represented with a leading zero, for example, "03". A two-digit year is represented with two digits, for example, "13". No additional leading zeros are displayed.
        yyyyy   Behaves identically to "yyyy".

        g, gg   Period/era string formatted as specified by the CAL_SERASTRING value.
                The "g" and "gg" format pictures in a date string are ignored if there is no associated era or period string.


        PivotYear
                The maximum year that a 1 or 2 digit year is assumed to be.
                The Microsoft de-factor standard for y2k is 2029. Any value greater
                than 29 is assumed to be 1930 or higher.

                e.g. 2029:
                    1930, ..., 2000, 2001,..., 2029

                If the PivotYear is between 0 and 99, then PivotYear is assumed to be
                a date range in the future. e.g. (assuming this is currently 2010):

                    Pivot   Range
                    0       1911..2010  (no future years)
                    1       1912..2011
                    ...
                    98      2009..2108
                    99      2010..2099  (no past years)

                0 ==> no years in the future
                99 ==> no years in the past
}
    if Length(S) = 0 then
        Exit;
    if Length(DateFormat) = 0 then
        Exit;

    Month := -1;
    Day := -1;
    Year := -1;

    Tokens := TDateTimeUtils.TokenizeFormat(DateFormat);
    n := 1; //input string index
    for i := Low(Tokens) to High(Tokens) do
    begin
        CurrentToken := Tokens[i];
        if CurrentToken = 'MMMM' then
        begin
            //Long month names, we don't support yet (you're free to write it)
            Exit;
        end
        else if CurrentToken = 'MMM' then
        begin
            //Short month names, we don't support yet (you're free to write it)
            Exit;
        end
        else if CurrentToken = 'MM' then
        begin
            //Month, with leading zero if needed
            if not ReadDigitString(S, n, 2{MinDigits}, 2{MaxDigits}, 1{MinValue}, 12{MaxValue}, {var}Month) then Exit;
        end
        else if CurrentToken = 'M' then
        begin
            //months
            if not ReadDigitString(S, n, 1{MinDigits}, 2{MaxDigits}, 1{MinValue}, 12{MaxValue}, {var}Month) then Exit;
        end
        else if CurrentToken = 'dddd' then
        begin
            Exit; //Long day names, we don't support yet (you're free to write it)
        end
        else if CurrentToken = 'ddd' then
        begin
            Exit; //Short day names, we don't support yet (you're free to write it);
        end
        else if CurrentToken = 'dd' then
        begin
            //If we know what month it is, and even better if we know what year it is, limit the number of valid days to that
            if (Month >= 1) and (Month <= 12) then
            begin
                if Year > 0 then
                    MaxValue := MonthDays[IsLeapYear(Year), Month]
                else
                    MaxValue := MonthDays[True, Month]; //we don't know the year, assume it's a leap year to be more generous
            end
            else
                MaxValue := 31; //we don't know the month, so assume it's the largest

            if not ReadDigitString(S, n, 2{MinDigits}, 2{MaxDigits}, 1{MinValue}, MaxValue{MaxValue}, {var}Day) then Exit;
        end
        else if CurrentToken = 'd' then
        begin
            //days
            //If we know what month it is, and even better if we know what year it is, limit the number of valid days to that
            if (Month >= 1) and (Month <= 12) then
            begin
                if Year > 0 then
                    MaxValue := MonthDays[IsLeapYear(Year), Month]
                else
                    MaxValue := MonthDays[True, Month]; //we don't know the year, assume it's a leap year to be more generous
            end
            else
                MaxValue := 31; //we don't know the month, so assume it's the largest

            if not ReadDigitString(S, n, 1{MinDigits}, 2{MaxDigits}, 1{MinValue}, MaxValue{MaxValue}, {var}Day) then Exit;
        end
        else if (CurrentToken = 'yyyy') or (CurrentToken = 'yyyyy') then
        begin
            //Year represented by a full four or five digits, depending on the calendar used.
            {
                Thai Buddhist and Korean calendars have five-digit years.
                The "yyyy" pattern shows five digits for these two calendars,
                    and four digits for all other supported calendars.
                Calendars that have single-digit or two-digit years, such as for
                    the Japanese Emperor era, are represented differently.
                    A single-digit year is represented with a leading zero, for
                    example, "03". A two-digit year is represented with two digits,
                    for example, "13". No additional leading zeros are displayed.
            }
            if not ReadDigitString(S, n, 4{MinDigits}, 4{MaxDigits}, 0{MinValue}, 9999{MaxValue}, {var}Year) then Exit;
        end
        else if CurrentToken = 'yyy' then
        begin
            //i'm not sure what this would look like, so i'll ignore it
            Exit;
        end
        else if CurrentToken = 'yy' then
        begin
            //Year represented only by the last two digits. A leading zero is added for single-digit years.
            if not ReadDigitString(S, n, 2{MinDigits}, 2{MaxDigits}, 0{MinValue}, 99{MaxValue}, {var}Year) then Exit;

            nCurrentYear := GetCurrentYear;
            Year := (nCurrentYear div 100 * 100)+Year;

            if (PivotYear < 100) and (PivotYear >= 0) then
            begin
                //assume pivotyear is a delta from this year, not an absolute value
                PivotYear := nCurrentYear+PivotYear;
            end;

            //Check the pivot year value
            if Year > PivotYear then
                Year := Year - 100;
        end
        else if CurrentToken = 'y' then
        begin
            //Year represented only by the last digit.
            if not ReadDigitString(S, n, 1{MinDigits}, 1{MaxDigits}, 0{MinValue}, 9{MaxValue}, {var}Year) then Exit;

            nCurrentYear := GetCurrentYear;
            Year := (nCurrentYear div 10 * 10)+Year;

            if (PivotYear < 100) and (PivotYear >= 0) then
            begin
                //assume pivotyear is a delta from this year, not an absolute value
                PivotYear := nCurrentYear+PivotYear;
            end;

            //Check the pivot year value
            if Year > PivotYear then
                Year := Year - 100;
        end
        else
        begin
            //The input string should contains CurrentToken starting at n
            Partial := Copy(S, n, Length(CurrentToken));
            Inc(n, Length(CurrentToken));
            if Partial <> CurrentToken then
                Exit;
        end;
    end;

    //If there's still stuff left over in the string, then it's not valid
    if n <> Length(s)+1 then
    begin
        Result := False;
        Exit;
    end;

    if Day > MonthDays[IsLeapYear(Year), Month] then
    begin
        Result := False;
        Exit;
    end;

    try
        Value := EncodeDate(Year, Month, Day);
    except
        Result := False;
        Exit;
    end;
    Result := True;
end;


class function TDateTimeUtils.TokenizeFormat(fmt: string): TStringDynArray;
var
    i: Integer;
    partial: string;

    function IsDateFormatPicture(ch: AnsiChar): Boolean;
    begin
        case ch of
        'M','d','y': Result := True;
        else Result := False;
        end;
    end;
begin
    SetLength(Result, 0);

    if Length(fmt) = 0 then
        Exit;

    //format is only one character long? If so then that's the tokenized entry
    if Length(fmt)=1 then
    begin
        SetLength(Result, 1);
        Result[0] := fmt;
    end;

    partial := fmt[1];
    i := 2;
    while i <= Length(fmt) do
    begin
        //If the characters in partial are a format picture, and the character in fmt is not the same picture code then write partial to result, and reset partial
        if IsDateFormatPicture(partial[1]) then
        begin
            //if the current fmt character is different than the running partial picture
            if (partial[1] <> fmt[i]) then
            begin
                //Move the current partial to the output
                //and start a new partial
                SetLength(Result, Length(Result)+1);
                Result[High(Result)] := partial;
                Partial := fmt[i];
            end
            else
            begin
                //the current fmt character is more of the same format picture in partial
                //Add it to the partial
                Partial := Partial + fmt[i];
            end;
        end
        else
        begin
            //The running partial is not a format picture.
            //If the current fmt character is a picture code, then write out the partial and start a new partial
            if IsDateFormatPicture(fmt[i]) then
            begin
                //Move the current partial to the output
                //and start a new partial
                SetLength(Result, Length(Result)+1);
                Result[High(Result)] := partial;
                Partial := fmt[i];
            end
            else
            begin
                //The current fmt character is another non-picture code. Add it to the running partial
                Partial := Partial + fmt[i];
            end;
        end;

        Inc(i);
        Continue;
    end;

    //If we have a running partial, then add it to the output
    if partial <> '' then
    begin
        SetLength(Result, Length(Result)+1);
        Result[High(Result)] := partial;
    end;
end;

class function TDateTimeUtils.ReadDigitString(const S: string; var Pos: Integer;
            MinDigits, MaxDigits: Integer; MinValue, MaxValue: Integer;
            var Number: Integer): Boolean;
var
    Digits: Integer;
    Value: Integer;
    Partial: string;
    CandidateNumber: Integer;
    CandidateDigits: Integer;
begin
    Result := False;
    CandidateNumber := -1;
    CandidateDigits := 0;

    Digits := MinDigits;
    while Digits <= MaxDigits do
    begin
        Partial := Copy(S, Pos, Digits);
        if Length(Partial) < Digits then
        begin
            //we couldn't get all we wanted. We're done; use whatever we've gotten already
            Break;
        end;

        //Check that it's still a number
        if not TryStrToInt(Partial, Value) then
            Break;

        //Check that it's not too big - meaning that getting anymore wouldn't work
        if (Value > MaxValue) then
            Break;

        if (Value >= MinValue) then
        begin
            //Hmm, looks good. Keep it as our best possibility
            CandidateNumber := Value;
            CandidateDigits := Digits;
        end;

        Inc(Digits); //try to be greedy, grabbing even *MORE* digits
    end;

    if (CandidateNumber >= 0) or (CandidateDigits > 0) then
    begin
        Inc(Pos, CandidateDigits);
        Number := CandidateNumber;
        Result := True;
    end;
end;
person Ian Boyd    schedule 29.09.2010

Если вы хотите знать, как это было решено в дальнейшем Delphi, вы можете посмотреть на источник слегка более современных (выглядит как Delphi 6) <сильный> sysutils.pas здесь:

HTTP: //anygen.googlecome.com/.../SysUtils.pas

Проверьте перегруженные версии StrToDateTime, которые принимают параметр TFormatSettings.

function StrToDateTime(const S: string;
  const FormatSettings: TFormatSettings): TDateTime; overload;
person Wouter van Nifterick    schedule 25.09.2010

Используйте библиотеку RegExpr (https://github.com/masterandrey/TRegExpr)

var
    RE: TRegExpr;

begin
    RE := TRegExpr.Create;
    try
        RE.Expression := '^(\d\d\d\d)/(\d\d)/(\d\d)T(\d\d):(\d\d):(\d\d)$';
        if RE.Exec( Value ) then
        begin
            try
                Result := EncodeDate( StrToInt( RE.Match[1] ),
                                      StrToInt( RE.Match[2] ),
                                      StrToInt( RE.Match[3] ) ) +
                          EncodeTime( StrToInt( RE.Match[4] ),
                                      StrToInt( RE.Match[5] ),
                                      StrToInt( RE.Match[6] ),
                                      0 )
            except
                raise EConvertError.Create( 'Invalid date-time: ' + Value )
            end
        end
        else
            raise EConvertError.Create( 'Bad format: ' + Value )
    finally
        RE.Free
    end
end;
person Mads Boyd-Madsen    schedule 18.05.2017

Я не уверен, что вы хотите. Я не использую Delphi 5 больше, но я уверен, что функции StrToDateTime в нем существует. С его помощью вы можете преобразовать строку в TDateTime с настройками формата. Тогда вы можете преобразовать такие TDateTime в любой формат, используя FormatDateTime который позволяет использовать любой формат даты, который вы хотите.

person Eduardo Mauro    schedule 24.09.2010
comment
Да, она существует. Но она работает с глобальной переменной: Текущая настройка ShortDateFormat. Я имею дело с множеством форматов, в данный момент времени. Мне нужно, чтобы иметь возможность указать точный формат, используемый для преобразования строки в TDateTime. Настройка глобальной переменной (по причинам, указанным в вопросе) не вариант. - person Willem van Rumpt; 24.09.2010
comment
Проблема заключается в Delphi 5! По крайней мере, начиная с Delphi 7, существует перегруженный StrToDateTime, который принимает настройки формата, что решает проблему с многопоточными приложениями. Это недостаток использования устаревшей среды. - person Uwe Raabe; 24.09.2010
comment
@Uwe: Что касается использования устаревшей среды: обновление / обновление не является моей задачей. Я думаю, что последняя версия Delphi была чуть меньше месяца назад, но от того, что я могу видеть в существующем коде, и с учетом изменений в Delphi, я не думаю, что они когда-либо обновления ... - person Willem van Rumpt; 24.09.2010
comment
Я чувствую с вами. Эта схема видится слишком часто в дикой природе. Вот почему я стараюсь постоянно обновлять. Это делает процесс намного проще. Если вы нагромождаете его версия за версией, наступит момент, когда вы больше не сможете с этим справиться. - person Uwe Raabe; 24.09.2010
comment
Лично я не использовал Delphi, начиная с версии 7. Мой бизнес вращается в основном вокруг .NET. Я сохранил после (довольно многочисленного количества) платежей по Delphi с тех пор со стороны, но для меня, там нет бизнес-кейс для покупки Delphi (не говоря уже о <б> с SA). Работа с Delphi из-за подрядчика, имеющего существующий код базы (в данном случае Delphi 5), а не потому, что это был мой выбор. Это бизнес. В настоящее время, для меня нет бизнес-кейс для покупки Delphi. Мне нравится Delphi, и если для моего бизнеса станет целесообразным его приобретение, я его куплю. Но пока: нет. - person Willem van Rumpt; 24.09.2010

Я хотел бы пойти в другую сторону вокруг него. Как я понимаю, у вас есть около двух вариантов которым вы упомянули один себя

  • Настройте ShortDateFormat и синхронизируйте каждый доступ к нему.
  • Если вы знаете формат строк вы ПОЛУЧАТЬ (так или иначе, вам придется), только <сильный> сделать некоторые строки жонглирование сначала получить ваши строки в текущем ShortDateFormat . После этого преобразования (жонглировал) строку в TDateTime.

Я вообще удивляюсь, как вы собираетесь определить формат говорят 04/05/2010.

program DateTimeConvert;
{$APPTYPE CONSOLE}
uses
  SysUtils;


function GetPart(const part, input, format: string): string;
var
  I: Integer;
begin
  for I := 1 to Length(format) do
    if Uppercase(format[I]) = Uppercase(part) then
      Result := Result + input[I];
end;

function GetDay(const input, format: string): string;
begin
  Result := GetPart('d', input, format);
  if Length(Result) = 1 then Result := SysUtils.Format('0%0:s', [Result]);
end;

function GetMonth(const input, format: string): string;
begin
  Result := GetPart('m', input, format);
  if Length(Result) = 1 then Result := SysUtils.Format('0%0:s', [Result]);
end;

function GetYear(const input, format: string): string;
begin
  Result := GetPart('y', input, format);
end;

function ConvertToMyLocalSettings(const input, format: string): string;
begin
  Result := SysUtils.Format('%0:s/%1:s/%2:s', [GetDay(input, format), GetMonth(input, format), GetYear(input, format)]);
end;

begin
  Writeln(ConvertToMyLocalSettings('05/04/2010', 'dd/mm/yyyy'));
  Writeln(ConvertToMyLocalSettings('05-04-2010', 'dd-mm-yyyy'));
  Writeln(ConvertToMyLocalSettings('5-4-2010', 'd-m-yyyy'));
  Writeln(ConvertToMyLocalSettings('4-5-2010', 'm-d-yyyy'));
  Writeln(ConvertToMyLocalSettings('4-05-2010', 'M-dd-yyyy'));
  Writeln(ConvertToMyLocalSettings('05/04/2010', 'dd/MM/yyyy'));
  Readln;
end.
person Lieven Keersmaekers    schedule 24.09.2010
comment
Настройка параметров даты и времени, которые больше не будут передаваться в виде строки, будет невыполнимой. Добавление дополнительного параметра с указанием ShortDateFormat, используемого на рабочей станции будет тривиальным, однако. Вот почему я ищу что-то вроде StrToDate(strDate: строка; формат: строка) :) - person Willem van Rumpt; 24.09.2010
comment
Или я, или вы неправильно поняли. Суть решения есть , чтобы передать DateTimes как строки. На Ваш станции вы FixUp пропущенный через строки в соответствии с форматом вы используете на вашей рабочей станции. После этого, это просто вызов StrToDate на рабочей станции. - person Lieven Keersmaekers; 24.09.2010
comment
Мы находимся на том же уровне. Я не могу изменить даты, которые передаются в виде строк. I <б> можно добавить дополнительный параметр, определяющий формат, используемый. Чего у меня нет в Delphi 5, так это метода StrToDate, который принимает параметр формата. Я должен написать свой собственный код (или, поглядывая библиотеки кода, скопируйте и настроить его): ваш выбор два (и мой собственный вариант 1, если нет ничего другого, что покрывала мои потребности). - person Willem van Rumpt; 24.09.2010
comment
Для того, чтобы понять (это пятница все-таки), значения передаются на рабочую станцию ​​другими является TDateTime тогда ?! Если нет, то это вы неправильно поняли ‹g› - person Lieven Keersmaekers; 24.09.2010
comment
Нет. Значение я получаю это строка. И (пока что хорошо, пока надеясь на лучшее) это будет строка, отформатированная с использованием ShortDateFormat. StrToDate в Delphi 5 в этом случае бесполезен, так как он преобразует строку, используя формат ShortDateFormat текущего пользователя. Для рабочей станции X используется формат M-dd-yyyy, для рабочей станции Y — дд/мм/гггг, для рабочей станции Z — MMM/д/г. Там есть множество вариантов. Это fiendlishly трудно преобразовать строку в дату, поэтому я ищу встроенный вариант, прежде чем прибегать к пользовательскому методу. - person Willem van Rumpt; 24.09.2010
comment
хорошо, последняя попытка, потому что я до сих пор не понимаю: я не знаю, как преобразовать MMM/d/y (часть y), но все остальные примеры преобразуются (на вашем локальном компьютере) в dd/mm/yyyy с отредактированным ответом. С этого момента, это просто StrToDate на локальном компьютере. - person Lieven Keersmaekers; 24.09.2010
comment
Перечитайте проблемы о резьбе. Добавьте проблемы, связанные с преобразованием строки в дату. Это не тривиально. Ваш код даже близко не охватывающие все аспекты. Открывает SysUtils.pas (если у вас есть лицензия apropriate), и выйти в себя внутренности StrToDate. - person Willem van Rumpt; 24.09.2010
comment
Представленный код является потокобезопасным, и хотя (очень) многое осталось для оптимизации, если вы можете преобразовать входную строку в строку, которая может быть обработана StrTodate, нет необходимости пытаться имитировать все грязные детали StrToDate. Кстати, если бы я дал вам впечатление, что я думал, что это тривиально, я не знаю. Но, по крайней мере, это решение может быть относительно легко расширен, когда вы сталкиваетесь новый формат с новой рабочей станции. - person Lieven Keersmaekers; 24.09.2010
comment
Так как это пятница: Попытка преобразовать строку в дату (время), не зная, формат был отформатирован с помощью, является осуществление проб и ошибок. Без формата, без даты, там просто пустота. Это относится к любой используемой вами библиотеке или языку. Это просто, что некоторые имеют больше шансов получить это право. - person Willem van Rumpt; 24.09.2010
comment
Вы сказали, что не будет никаких проблем, проходя формат. Я основан ответ на это. Если это невозможно, что ж, вы облажались. - person Lieven Keersmaekers; 24.09.2010
comment
<По теме> ENIG навязчивая waarom мы ЖУ gesprek нит Gewoon в гете Nederlands Voeren? :). Goed выходные. - person Lieven Keersmaekers; 24.09.2010
comment
Когда вы говорите ... нет необходимости пытаться имитировать ..., вы говорите о ваших требованиях или моих требованиях? Я не знаю, какие у вас критерии, я знаю, какие у меня. Я получаю дату в виде строки, она может быть в любом формате, допускаемых окнами. Это то, что я должен преобразовать в TDateTime. StrToDate в Delphi-не был сделан accomadate этого требования. На самом деле, как я уже говорил ранее: Преобразование строки в дату, на любом языке является fiendlishly трудно. .NET (язык я использую MOSE, C #, чтобы быть конкретным), получает это право 99% случаев. И даже там, есть место для исключений. - person Willem van Rumpt; 24.09.2010
comment
‹offTopic›Geen idee :) zodra het inhoudelijk over werk gaat (programren) is engels wel zo makkelijk. Daarnaast Werk ик VEEL в гет buitenland, еп даН Энгельс де enige mogelijke voertaal :) (даН Энгельс де enige mogelijk voertaal) => Belgie ан enkele бывшие колонии uitgezonderd .... - person Willem van Rumpt; 24.09.2010