2017-02-01 7 views
2

TryStrToDate 함수를 사용하여 mmm/yy 형식의 문자열을 TDateTime으로 변환하려고합니다. 그러나 항상 실패로 보인다.TryStrToDate 형식이 mmm/yy로 실패 함

포맷 설정 레코드를 만들고 날짜 구분 기호 및 간단한 날짜 형식을 설정합니다. 긴 날짜 형식을 설정했는지 여부에 관계없이 문제가 발생했음을 보여주기 위해 긴 날짜 형식을 설정했습니다.

dd/mm/yyyy를 사용하도록 예제를 변경하고 01/02/2017에 전달하면 성공하므로 문제가 형식 일 수 있다고 생각합니다. 나는 무엇 리터의 예를 보여주는 데모 콘솔 응용 프로그램을 만들었습니다

http://www.delphibasics.co.uk/RTL.asp?Name=formatdatetime

형식 문자열을 만드는 데 참고로 아래의 링크를 사용 부탁드립니다

uses 
    System.SysUtils; 

function ValidateDate(ADate: string): boolean; 
var 
    fs: TFormatSettings; 
    DateTime: TDateTime; 
begin 
    fs := TFormatSettings.Create(); 
    fs.DateSeparator := '/'; 
    fs.ShortDateFormat := 'mmm/yy'; 
    fs.LongDateFormat := 'mmm/yy'; 

    result := true; 
    if not TryStrToDate(ADate, DateTime, fs) then 
     result := false; 
end; 

begin 
    try 
     if not ValidateDate('Oct/16') then 
      WriteLn('Failed to convert') 
    except 
     on E: Exception do 
      Writeln(E.ClassName, ': ', E.Message); 
    end; 
end. 

리터을 위해 노력하고 있어요 왜 실패했는지에 대한 아이디어.

+0

Delphibasics를 사용하지 마십시오. 공식 문서를 사용하십시오. 그리고 당신의 결과는 이상합니다. 'result : = TryStrToDate (...)'사용 –

+0

아마도 (이 게시물 (http://stackoverflow.com/q/11782114/62576)) (특히 내가 쓴 답변) 도움이 될 수 있습니다. –

답변

-1

David의 조언에 따라 문자열을 ie Jan에서 01로 변환 한 다음 TryStrToDate를 호출하여 변환 된 날짜를 가져 오는 함수를 만들었습니다. 형식 문자열은 하루에 포함되지 않은 경우 중 하나에 알려 주시기 바랍니다 어떤 개선 또는 최적화를 볼 수 있다면 그것은 01

function ParseDate(ADate: string; AFormatSettings: TFormatSettings): TDateTime; 
var 
    DateData, FormatData: TStringList; 
    Month, Day, Year: string; 
    ConvertedDate: Double; 
    i: integer; 

    function ConvertMonth(AMonth: string; ALongMonth: boolean = false): string; 
    var 
     i: integer; 
    begin 
     Result := '-1'; // default to invalid month 
     if ALongMonth then 
     begin 
      for i := 1 to high(AFormatSettings.LongMonthNames) do 
      begin 
       if AFormatSettings.LongMonthNames[i] = AMonth then 
       begin 
        Result := inttostr(i); // MonthArray starts at index 1 which matches the month 
        break; 
       end; 
      end; 
     end 
     else 
     begin 
      for i := 1 to high(AFormatSettings.ShortMonthNames) do 
      begin 
       if AFormatSettings.ShortMonthNames[i] = AMonth then 
       begin 
        Result := inttostr(i); // MonthArray starts at index 1 which matches the month 
        break; 
       end; 
      end; 
     end; 
    end; 
begin 
    DateData := TStringList.Create(); 
    FormatData := TStringList.Create(); 
    try 
     DateData.Delimiter := AFormatSettings.DateSeparator; 
     DateData.StrictDelimiter := true; 
     DateData.DelimitedText := ADate; 

     FormatData.Delimiter := AFormatSettings.DateSeparator; 
     FormatData.StrictDelimiter := true; 
     FormatData.DelimitedText := AFormatSettings.ShortDateFormat; 

     Day := '01'; 
     Month := '01'; 
     Year := '01'; 

     for i := 0 to FormatData.Count - 1 do 
     begin 
      if FormatData[i].IndexOf('d') <> -1 then 
       Day := DateData[i] 
      else if FormatData[i].IndexOf('m') <> -1 then 
      begin 
       if FormatData[i] = 'mmm' then 
        Month := ConvertMonth(DateData[i]) 
       else if FormatData[i] = 'mmmm' then 
        Month := ConvertMonth(DateData[i], true) 
       else 
        Month := DateData[i] 
      end 
      else if FormatData[i].IndexOf('y') <> -1 then 
       Year := DateData[i] 
     end; 

     ADate := Day + AFormatSettings.DateSeparator + Month + AFormatSettings.DateSeparator + Year; 

     AFormatSettings.ShortDateFormat := 'dd' + AFormatSettings.DateSeparator + 'mm' + AFormatSettings.DateSeparator + 'yyyy'; 
     TryStrToDate(ADate, Result, AFormatSettings); 
    finally 
     DateData.free(); 
     FormatData.free(); 
    end; 
end; 

로 설정됩니다.

+0

질문 된 질문에 대한 대답이 아닙니다. 또한이 코드는 정말 좋지 않습니다. –

+0

어떻게 프로그래밍 했습니까? 날짜 문자열을 전달한 다음 날짜 형식 문자열이 어떤 형식인지 명시하는 형식 설정을 허용했습니다. 그 다음에 trystrtodate 형식을 사용할 수있는 형식으로 변환합니다. – MattLaza

+0

물어 본 질문과 관련이 없습니다. –

7

형식 문자열이 유효하지 않습니다. 이러한 형식 문자열은 일, 월 및 년을 인코딩해야합니다. 허락되지 않은 날은 생략합니다.

변환을 위해 제공 한 문자열에서 연도를 생략 할 수 있습니다. 이 경우 현재 연도로 간주됩니다.

이 문자열을 단지 몇 달 및 1 년으로 변환하려면 가짜 날짜를 포함하십시오. 1, TryStrToDate에 전달하는 문자열에서. 그런 다음 DecodeDate을 사용하여 월 및 일의 숫자 값을 구하고 그 날을 무시하십시오.

형식으로 'd/mmm/yy'을 사용하고 변환 할 문자열로 '1/' + ADate을 전달하십시오.

문자열에서 날짜로 변환하는 데 사용되는 짧은 날짜 문자열 형식이므로 설정해야하는 유일한 날짜 형식입니다.

마지막으로이 형식은 매우 간단하게 직접 구문 분석 할 수있는 간단한 형식입니다.

당신이 관찰 한 것처럼

업데이트 및 의견 진술은 RTL 기능은 숫자 만 달 포맷을 지원 ScanDate에 대한 호출로 구현됩니다. 그래서 여러분이 시도한 전체 접근법은 슬프게도 실패로 끝날 것입니다. 내가 확인한 문제를 해결하더라도.

제 조언은 형식이 매우 간단하기 때문에 문자열을 직접 구문 분석하는 것입니다.

+0

안녕 데이빗, 도와 줘서 고마워.변경 사항을 구현하고 TryStrToDate의 소스를 보면 scannumber를 'mmm'에 호출하려고 시도하는 것처럼 보입니다.이 경우 Oct는 물론 실패합니다. 이것은 제가 형식으로 mmm을 사용할 수 없다는 것을 의미합니까? 아니면 뭔가 놓친 거니? – MattLaza

+0

가, 나는 그것을 깨닫지 못했습니다. 나는 네가 옳다고 생각한다. StrToDate와 친구들은 숫자 만 지원한다. 나는 너 자신을 파싱하는 것이 최선이라고 생각한다. 정확히 하나의'/'문자가 있는지 확인하고, 그 문자로 분할하고, 두 부분을 파싱합니다. –