2017-02-01 25 views
2

TryStrToDate関数を使用して、mmm/yyの形式の文字列をTDateTimeに変換しようとしています。しかし、それは常に失敗するようです。TryStrToDateは形式mmm/yyで失敗する

私は、書式設定レコードを作成し、日付の区切りと短い日付形式を設定します。長い日付形式を設定して、短くまたは長い日付形式を設定するかどうかに問題があることを示します。

リットルはDD/MM/YYYYを使用し、2017年1月2日に渡す例を変更した場合、それはそうLが問題の形式とすることができると信じて成功しています。私は何リットルの一例を示すデモコンソールアプリを作っている

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

おそらく[this post](http://stackoverflow.com/q/11782114/62576)(特に私が書いた答え)が役に立ちます。 –

答えて

-1

デビットのアドバイスに続いて、月の文字列を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、あなたはTryStrToDateに渡す文字列で。次に、DecodeDateを使用して、月と日の数値を取得し、日を無視します。

したがって、フォーマットとして'd/mmm/yy'を使用し、変換する文字列として'1/' + ADateを渡します。

また、文字列を日付に変換するために使用する短い日付文字列形式であるため、設定する必要があるのは唯一のものです。

最後に、これはあなたが非常に簡単にそれを直接解析することができ、このような単純な形式です。

更新

あなたが観察し、コメントで述べてきたように、RTLの機能は数値のみ月のフォーマットをサポートしていScanDateへの呼び出しで実装されています。あなたが試みたアプローチ全体が、悲しいことに、失敗に至ることになります。あなたが私が特定した問題を解決しても。そのフォーマットはとても簡単であるため

私のアドバイスは、単に文字列を自分で解析することです。

+0

こんにちはデービッド、助けてくれてありがとう。変更を実装し、TryStrToDateのソースを見ると、 'mmm'のscannumberを呼び出すように見えるので、この場合Octはもちろん失敗します。これはフォーマットでmmmを使用できないという意味ですか?または何かを逃していますか? – MattLaza

+0

ガー、私はそれを実現していませんでした。私はあなたが正しいと思う、StrToDateと友人は数字の月だけをサポートしています。私はあなたがこれを自分で解析するのが最善だと思う。正確に1つの '/'文字があることを確認し、その文字に分割して、2つの部分を解析します。 –

関連する問題