11

そのdateString1.compareTo(dateString2)ため、各文字の Unicode 値に基づいて、文字列との辞書式比較を行い、int を返すを使用しています。これがコードサンプルです。

String dateString1 = "05-12-2012";
String dateString2 = "05-13-2012";
if (dateString1.compareTo(dateString2) <=0){
   System.out.println("dateString1 is an earlier date than dateString2");
}

Javaで日付を比較するこれは間違ったアプローチですか?

私のテストでは、予期しない結果が得られる状況には遭遇しませんでした。長時間実行されるループ内でこれを行っているため、必要がなければ、文字列から Date オブジェクトを作成したくありません。

Ninja Edit 以下の回答から収集すると、日付がyyyyMMdd形式の場合は文字列として比較しても問題はありませんが、他の形式の場合は明らかにエラーになります。

実際のコードでは、実際に日付文字列をyyyyMMddフォーマットとして使用しています。(上記の例では、フォーマットを間違って入力しました。) したがって、今のところ、コードはそのままにして、決定を正当化するために数行のコメントを追加します。

しかし、このような文字列の比較は非常に制限的であり、dba が将来的に日付形式を変更することを決定した場合、バグに遭遇することがわかりました。

4

6 に答える 6

18

文字列を使用して Java で日付を処理することは、常に最適なオプションとは限りません。たとえば、うるう年の場合、2 月は余分な日があります。文字列は一見正しいように見えるため、変換を実行する方が適切です。Java は、日付が正しいことを検証します。

SimpleDateFormatクラスを使用して、文字列を日付に変換できます。

public static void main(String[] args) throws ParseException {
    String dateString1 = "05-12-2012";
    String dateString2 = "05-13-2012";

    SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyyy");

    Date date1 = format.parse(dateString1);
    Date date2 = format.parse(dateString2);

    if (date1.compareTo(date2) <= 0) {
        System.out.println("dateString1 is an earlier date than dateString2");
    }
}

フォーマットのカスタマイズをチェックできるパラメーターを見つけるには(Java™ チュートリアル > 国際化 > フォーマット)

于 2012-05-15T22:34:34.553 に答える
8

(ここで説明されているように)正しいことを行い、適切なオブジェクトに変換しDateて比較することをお勧めします。実際にアプリケーションに影響を与える場合は、パフォーマンスへの影響を心配します(おそらく影響はありません)。

于 2012-05-15T22:23:44.130 に答える
4

年の変更を処理できないため、かなり悪いです。

そのようにしたい場合はYYYY-MM-DD、新年が台無しにならないように日付をフォーマットすることをお勧めします。

于 2012-05-15T22:20:47.317 に答える
3

日付の順序を処理するためにアルファベット順のルールを使用するのは良くありません。主に、アルファベットと数のシステムに従って順序が異なるという問題に遭遇するためです。

アルファベットの場合

01-02-2011 comes before
01-1-2011 (because 0 in the date field is before 1 in the other date field)

ナンバーシステムの場合

01, 02, 2011 comes after
01, 1, 2011  because all fields are being compared like numbers

日付オブジェクトは、比較でどのフィールドが優先されるかを知るために数値比較を拡張します。そのため、実際には後の月に発生する別の月よりも前の月に日付が「前」に置かれることはありません。

日付形式を厳密に制御している場合は、アルファベット順の規則にも従うように日付を揃えることができます。ただし、誤って誤った形式の日付を挿入すると、プログラム全体が奇妙な方法で失敗するリスクがあります。

これを行う一般的な方法は次のとおりです (推奨されません。文字列以外の日付比較を使用してください)。

YYYYMMDD
(year)(month)(day) all zero-padded.

最後の手法は主に、最終的に実際に使用されるようになるため含まれており、それが何であるかを認識する必要があります: 適切な日付ライブラリを使用せずに日付を処理しようとする試み (別名、巧妙なハック)。

于 2012-05-17T15:14:09.420 に答える
2

説明したように、一般的には、文字列よりも日時オブジェクトを操作する方が適切です。

java.time

他の回答では、設計が不十分で、混乱し、面倒であることが証明されている古い時代遅れの日時クラスを使用しています。それらには、時刻やタイムゾーンのない日付のみの値を真に表すクラスがありません。

代わりに、Java 8 以降に組み込まれているjava.timeフレームワークを使用してください。Oracle チュートリアルを参照してください。java.time 機能の多くは、ThreeTen-Backportで Java 6 および 7 にバックポートされ、さらにThreeTenABPで Android に適合されています。

String input = "05-12-2012";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "MM-dd-yyyy" );
LocalDate ld = LocalDate.parse( input , formatter );

LocalDate実装しますcompareTo。また、メソッド equals、isBefore、isAfter を呼び出すこともできます。

Boolean isEarlier = ld.isBefore( someOtherLocalDate );
于 2016-07-12T16:59:48.910 に答える
1

各日付の読み取りを 1 回だけ行う場合は、YYYYMMDD (あなたが行ったように MMDDYYYY ではありません) が最適なソリューションである可能性があります。ただし、各日付を複数回処理する場合 (たとえば、日付を並べ替える場合) は、文字列よりも速く比較できるオブジェクト (日付など) に変更することをお勧めします。

于 2012-05-15T23:44:58.990 に答える