web-dev-qa-db-ja.com

hh:mm aとHH:mmaの違い

これが私の元のコードです-

String dateString = "23 Dec 2015 1:4 PM";
Locale locale = new Locale("en_US");
SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm a");
DateFormat df = new SimpleDateFormat("dd MMM yyyy HH:mm a", locale);
Date date = null;

try {
    date = formatter.parse(dateString);
} catch (ParseException e) {
    LOGGER.error(e);
}

String newDate = df.format(date);
System.out.println("oldDate = " + dateString);
System.out.println("newDate = " + newDate);

そしてここに私の出力があります-

oldDate = 23 Dec 2015 1:4 PM
newDate = 23 Dec 2015 01:04 AM

oldDatenewDateの間にはAM-PMの違いがあります。ここで、DateFormatコードを-に変更しました。

SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy hh:mm a");
DateFormat df = new SimpleDateFormat("dd MMM yyyy hh:mm a", locale);

そして私は期待される出力を得る、それは-

oldDate = 23 Dec 2015 1:4 PM
newDate = 23 Dec 2015 01:04 PM

HH24時間形式を意味し、hh12時間形式を意味することを知っています。

私の質問は

HH:mm aの代わりにhh:mm aを使用する場合、これは時刻を24時間形式で返す必要がありますか?

(または)

デフォルトが12時間形式の場合、入力された日付に応じて、それぞれのAM/PMマーカーを返す必要がありますか?

これは私の理解のためです。

5
AlwaysALearner

簡単なテストは、パターン「HH:mma」がどのように解釈されるかに対する最良の答えです。まず、印刷モードを調べてみましょう:

古いフォーマットエンジンSimpleDateFormat :

_Calendar cal = new GregorianCalendar(2015, 3, 1, 17, 45);
SimpleDateFormat sf = new SimpleDateFormat("HH:mm a", Locale.US);
System.out.println(sf.format(cal.getTime())); // 17:45 PM
_

Java-8(新しいパッケージ_Java.time.format_を使用):

_LocalTime time = LocalTime.of(17, 59);
DateTimeFormatter tf = DateTimeFormatter.ofPattern("HH:mm a", Locale.US);
System.out.println(tf.format(time)); // 17:59 PM
_

ここでオーバーライドは観察されませんどちらの場合も。 「HH」と「a」の組み合わせを使用することは、プログラミングエラーの兆候であると私は考えているため、このアプローチを好みます(ユーザーは明らかにこれらのパターンシンボルの意味と公式の説明について十分に考えていません)。

ここで、解析モードを調べてみましょう(厳密モードを使用して、実際に舞台裏で何が起こっているかを観察します):

_String dateString = "23 Dec 2015 1:4 PM";
SimpleDateFormat df = new SimpleDateFormat("dd MMM yyyy H:m a", Locale.US);
df.setLenient(false);
Date date = df.parse(dateString);
// Java.text.ParseException: Unparseable date: "23 Dec 2015 1:4 PM"
_

Java-8の動作はどうですか?これは同じですが、より明確なエラーメッセージが表示されます。

_DateTimeFormatter tf = DateTimeFormatter.ofPattern("H:m a", Locale.US);
tf = tf.withResolverStyle(ResolverStyle.STRICT);
LocalTime.parse("1:4 PM", tf);
// DateTimeException: Cross check failed: AmPmOfDay 0 vs AmPmOfDay 1
_

このメッセージは、値が「1」の解析された時間(24時間形式!)がAMを示し、テキスト入力に他の解析されたAM/PM値「PM」が含まれていることを示しています。このアンビバレンスは解決できません。

レッスン:矛盾する情報が無視され、誤った仮定につながる可能性がある場合は、寛大な構文解析に注意する必要があります。 @ Arjunの受け入れられた答えは完全に間違っています。

ちなみに、「en-US」という言語は存在しないため、new Locale("en", "US")の代わりに_Locale.US_またはnew Locale("en-US")を使用してください。

1
Meno Hochschild