2016-08-10 8 views
3

現在、文字列が日付に変更されるいくつかの異なる形式のいずれかになっているかどうかを確認するための検証メソッドをJavaで作成しています。文字列がJavaで正しい形式である場合に文字列を検証する方法

受け入れるフォーマットは、MM/DD/YY、M/DD/YY、MM/D/YY、M/D/YYです。

私は最初のフォーマットをテストしていましたが、有効な日付に入力しても有効ではないと私が言っているたびにテストしていました。私はまだ最後の形式の場合の条件に置く必要がある

public class IsDateFormatValid 
{ 
    public boolean isValid(String date) 
    { 
     boolean result = true; 
     if(date.length()>8||date.length()<6) 
     { 
     result= false; 
     } 
     if(date.length()==8) 
     { 
     if((Character.toString(date.charAt(2))!= "/")||(Character.toString(date.charAt(5))!="/")) 
     { 
      result=false; 
     } 
     } 
     if(date.length()==7) 
     { 
     if((Character.toString(date.charAt(2))!="/"&&Character.toString(date.charAt(1))!="/") ||(Character.toString(date.charAt(3))!="/"&&Character.toString(date.charAt(4))!= "/")) 
     { 
      result=false; 
     } 
     } 

     return result; 
    } 
} 

:ここ

は次のように私の現在のコードが見えるものです。私はデバッグメソッドを行い、常にfalseを返す部分が次のような行であることを確認しました。if((Character.toString(date.charAt(2))!= "/")||(Character.toString(date.charAt) (5))!= "/"))

この質問の主なポイントは、ここでの他の質問がどのように尋ねるかについて単数ではなく、複数の形式に対してチェックしようとしています。

+1

これらの質問は、私は怒っていると非常に悲しいことができます。それが日付であれば日付でなければなりません。日付でない場合は 'null 'にする必要があります。 –

+0

幸運にも1/2/06の意味を推測します。 :) – Eiko

答えて

6

おそらく高価な単純なアプローチです。しかし、何らかの理由で良い習慣に逆らってこのようになります:

  1. 許可されたパターンごとに1つのフォーマッタオブジェクトのリストを作成します。
  2. そのリストを反復する。各フォーマッタ(寛容がfalseに設定されている)を使用して日付文字列を解析できるかどうか試してください。例外をスローしないものを取得した場合は、受信した文字列が有効な形式に準拠していることがわかります。

フォーマットで解析する場合は、このquestionをチェックアウトすることができます。

Peterが指摘しているように、このソリューションはスレッドセーフではありません。したがって、それに対処するには、questionを調べる必要があります。

一方、paulsm4のようにすると、あなたはスレッドの問題を避けます...残念ながら、たくさんのフォーマッタオブジェクトのを作成しています。あなたはすぐに後で捨てる。 CPUサイクルを浪費し、そこに「メモリガーベジ」を作成することについて話してください。

オプション2;指定されたフォーマットの文字列に一致する正規表現を1つ(またはそれ以上)用意することは、それほどコストがかかりません。もちろん、Susannahから提案されたものほど簡単ではありません。ご存じのように、本当に "55/66/77"のような文字列を拒否したい場合は、 "2桁のダッシュ2桁のダッシュ2桁"をチェックする単純な正規表現と完全に一致します。

はい、オプション1は高価です。ここでの質問は、あなたの検証がどれくらい良いのでしょうか?構文的に「正しい」が「02/29/15」(2015年はうるう年ではありません)のように「意味的に」間違っている日付を拒否しますか?

更新:はこれについて考え、素敵な解決策は次のようになります:値が「フォーマッタ入力」として使用できる文字列になりMap<Regex, String>を作成

  1. 。対応するキーはその形式に "一致"する正規表現です
  2. マップキーを反復します
  3. キーが一致しない場合は、完了しました。入力が不明/無効な形式であることがわかります
  4. キーが一致する場合:そのキーのマップ値をフェッチし、それを使用して非寛容なフォーマッタオブジェクトを作成します。これで、フォーマッタが入力を解析できるかどうかを確認できます。入力した場合:のいずれかの日付で入力してください。
4

正規表現に対して照合を試してみると、作業が軽減されます。

if(date.matches("\\d{1-2}\\\\d{1-2}\\\\d{1-2}")){ 
    // ..do something 
} 
+1

実際の値が有効かどうかはチェックされません。あなたは99/99/99を簡単に渡すことができ、それが有効であると言います。 –

+0

うわー、なぜ2つのdownvotes? –

+0

00は有効な月ではありません –

5

あなたはこのように、可能なフォーマットを反復処理する場合があります

例:

private static String[] date_formats = { 
     "yyyy-MM-dd", 
     "yyyy/MM/dd", 
     "dd/MM/yyyy", 
     "dd-MM-yyyy", 
     "yyyy MMM dd", 
     "yyyy dd MMM", 
     "dd MMM yyyy", 
     "dd MMM yyyy" 
}; 

/** 
* A brute-force workaround for Java's failure to accept "any arbitrary date format" 
*/ 
public static Date tryDifferentFormats (String sDate) { 
    Date myDate = null; 
    for (String formatString : date_formats) { 
     try { 
      SimpleDateFormat format = new SimpleDateFormat(formatString); 
      format.setLenient(false); 
      myDate = format.parse(sDate); 
      break; 
     } 
     catch (ParseException e) { 
      // System.out.println(" fmt: " + formatString + ": FAIL"); 
     } 
    } 
    return myDate; 
} 
+1

@PeterRaderスレッディングは問題ではないようです。 'SimpleDateFormat形式'はここではメソッドローカル変数です。 – bradimus

+0

この回答が編集されたようには見えません – bradimus

+0

その1つの問題:本当に高価な部分は、そのフォーマッタオブジェクトの**作成**です。そして、あなたはいつもそれを続けています。だから、あなたはmフォーマットを持っています。あなたが** n * m **新しいフォーマッタを提供するn個の受信文字列。 mが大きい場合、男の子、あなたはたくさんのCPUサイクルを燃やしています。ここではたくさんの「ゴミ」を作り出す可能性があります。 – GhostCat

関連する問題