使用してこれを行う方法の
任意のポインタ。
javadocによると、フィールドAMPM_OF_DAY
はAM
の値0
とPM
ため1
を持つことができるので、あなただけのこれらの値を使用してマップを作成し、フォーマッタに渡し:
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;
import java.time.LocalTime;
// create map with custom values (0=AM, 1=PM, mapping to values "A" and "P")
Map<Long, String> map = new HashMap<>();
map.put(0L, "A"); // AM mapped to "A"
map.put(1L, "P"); // PM mapped to "P"
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
// hour/minute/second (change to whatever pattern you need)
.appendPattern("hh:mm:ss ")
// use the mapped values
.appendText(ChronoField.AMPM_OF_DAY, map)
// create formatter
.toFormatter();
// testing
System.out.println(formatter.format(LocalTime.of(10, 30, 45))); // 10:30:45 A
System.out.println(formatter.format(LocalTime.of(22, 30, 45))); // 10:30:45 P
すると出力がされます:
10時30分45秒
10時30分45秒P
そしてそれはまたString
を解析するために動作します:
System.out.println(LocalTime.parse("10:20:30 A", formatter)); // 10:20:30
System.out.println(LocalTime.parse("10:20:30 P", formatter)); // 22:20:30
出力は次のようになります。
10時20分30秒
夜09時20分30秒
パターンを制御しない場合は、文字012を探すことができます(AM/PMフィールドに対応するパターン)、カスタムバージョンで置き換えます。
1つの選択肢は、区切り文字としてa
を使用して、フォーマットString
を分割することです、そしてあなたは、パターンの残りの部分を失うことはありません:
// format with day/month/year hour:minute:second am/pm timezone
String format = "dd/MM/yyyy hh:mm:ss a z";
// split the format ("a" is the AM/PM field)
String[] formats = format.split("a");
DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder()
// first part of the pattern (everything before "a")
.appendPattern(formats[0])
// use the AM/PM mapped values
.appendText(ChronoField.AMPM_OF_DAY, map);
// if there's something after the "a", add it
if (formats.length > 1) {
builder.appendPattern(formats[1]);
}
// create formatter
DateTimeFormatter formatter = builder.toFormatter();
//test
ZonedDateTime z = ZonedDateTime.of(2017, 5, 1, 10, 20, 30, 0, ZoneId.of("America/Sao_Paulo"));
// AM replaced by "A"
System.out.println(formatter.format(z)); // 01/05/2017 10:20:30 A BRT
a
が先頭にある場合や、このアルゴリズムはまた、作品またはa
がない場合(この場合は、最後に追加します。存在しない場合は、追加する必要があるかどうかはわかりません)。フォーマットはa
が含まれていない場合は、それを追加しないように
// "a" in the end
String format = "hh:mm:ss a";
DateTimeFormatter formatter = // use same code above
System.out.println(formatter.format(LocalTime.of(15, 30))); // 03:30:00 P
// "a" in the beginning
String format = "a hh:mm:ss";
DateTimeFormatter formatter = // use same code above
System.out.println(formatter.format(LocalTime.of(15, 30))); // P 03:30:00
// no "a" (field is added in the end)
String format = "HH:mm:ss";
DateTimeFormatter formatter = // use same code above
System.out.println(formatter.format(LocalTime.of(15, 30))); // 03:30:00P
あなたは、いくつかの改善を行うことができます(またはその前にスペースを追加)、または何でもしたいです。
PS:このコードは"dd/MM/yyyy 'at' hh:mm:ss a"
のようなリテラル('
内のテキスト)を処理しません(「時」リテラルで、交換/削除すべきではありません)。
私は正規表現の専門家(私はそれがすべてのケースで動作している場合は100%わからない)ないんだけど、あなたはこのような何かを行うことができます。
String[] formats = format.split("(?<!\'[^\']{0,20})a|a(?![^\']{0,20}\')");
引用された内部でこの正規表現はa
を無視しますテキスト。 lookaheadとlookbehinds((?
パターン)は*
を受け付けないため、{0,20}
の限定記号を使用する必要があります。したがって、 "a"の前後に引用符で囲まれたテキストが最大20文字(ちょうどあなたが考えるものユースケースに最適です)。
一部のテスト:
String format = "\'Time: at\' hh:mm:ss a";
DateTimeFormatter formatter = // use same code above, but with the modified regex split
System.out.println(formatter.format(LocalTime.of(15, 30))); // Time: at 03:30:00 P
String format = "dd/MM/yyyy \'at\' hh:mm:ss a z";
DateTimeFormatter formatter = // use same code above, but with the modified regex split
ZonedDateTime z = ZonedDateTime.of(2017, 5, 1, 10, 20, 30, 0, ZoneId.of("America/Sao_Paulo"));
System.out.println(formatter.format(z)); // 01/05/2017 at 10:20:30 A BRT
これは前に頼まれました。私は正確なタイトルや言葉を覚えていませんが、検索に行きます。 –
受け取っているパターンは常に同じですか?それは常に午前/午後のフィールドを持っていますか? –
[この回答](https://stackoverflow.com/a/24004917/5772882)が役立ちます。質問は解析についてですが、私は解決策がフォーマットにも役立つと思います。 –