私のWebアプリでは、ユーザーの特定のアクティビティの日時がタイムスタンプLong
として(データベースに)格納されます。ユーザーに表示するには、通常の日時形式に変換する必要があります。
(実際に私のデータベースCassandraは、列が書き込まれたときのタイムスタンプを、1970年からのマイクロ秒)として保存します。対応するユーザーアクティビティ)
JSF 2.0(+ primefaces)を使用していますが、この変換に役立つコンバーターがあると思いますか?または、どうすればこれらの変換をどのように達成できますか?
このソリューションを提案します。マネージドBeanでこれを行います
public String convertTime(long time){
Date date = new Date(time);
Format format = new SimpleDateFormat("yyyy MM dd HH:mm:ss");
return format.format(date);
}
jSFページでこれを行うことができます(foo
がtime
を含むオブジェクトであると仮定します)
<h:dataTable value="#{myBean.convertTime(myBean.foo.time)}" />
このメソッドを利用したい複数のページがある場合、これをabstract class
に入れ、マネージドBeanにこのabstract class
を拡張させることができます。
編集:TimeZoneで時刻を返す
残念ながら、SimpleDateFormat
は常に現地時間で時刻をフォーマットするので、SimpleDateFormat
は使用できなくなります。異なるTimeZoneで時間を表示するには、これを行うことができます
public String convertTimeWithTimeZome(long time){
Calendar cal = Calendar.getInstance();
cal.setTimeZone(TimeZone.getTimeZone("UTC"));
cal.setTimeInMillis(time);
return (cal.get(Calendar.YEAR) + " " + (cal.get(Calendar.MONTH) + 1) + " "
+ cal.get(Calendar.DAY_OF_MONTH) + " " + cal.get(Calendar.HOUR_OF_DAY) + ":"
+ cal.get(Calendar.MINUTE));
}
より良い解決策は、JodaTime
を利用することです。私の意見では、このAPIはカレンダーよりもはるかに優れています(軽量、高速、より多くの機能を提供)。プラスCalendar.Month
of January
は0
で、開発者に1
を結果に追加するよう強制するため、時間を自分でフォーマットする必要があります。 JodaTime
を使用すると、すべてを修正できます。間違っている場合は修正しますが、JodaTime
はJDK7
に組み込まれていると思います
JSFに組み込み機能があるかどうかはわかりませんが、_Java.sql.Date
_のコンストラクターを使用して日付オブジェクトに変換できます。 http://download.Oracle.com/javase/1.5.0/docs/ api/Java/sql/Date.html#Date(long)
次に、Java SE、Java EEによって提供されるより高いレベルの機能を使用して、抽出された日付を表示およびフォーマットします。_Java.util.Calendar
_および明示的に時間を設定します: http://download.Oracle.com/javase/1.5.0/docs/api/Java/util/Calendar.html#setTime(Java.util.Date) =
編集:JSFコンポーネントは変換を処理すべきではありません。データアクセス層(永続層)がこれを処理する必要があります。言い換えれば、JSFコンポーネントはlong
型付き属性を処理せず、Date
型またはCalendar
型付き属性のみを処理する必要があります。
_ ZoneId usersTimeZone = ZoneId.of("Asia/Tashkent");
Locale usersLocale = Locale.forLanguageTag("ga-IE");
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM)
.withLocale(usersLocale);
long microsSince1970 = 1_512_345_678_901_234L;
long secondsSince1970 = TimeUnit.MICROSECONDS.toSeconds(microsSince1970);
long remainingMicros = microsSince1970 - TimeUnit.SECONDS.toMicros(secondsSince1970);
ZonedDateTime dateTime = Instant.ofEpochSecond(secondsSince1970,
TimeUnit.MICROSECONDS.toNanos(remainingMicros))
.atZone(usersTimeZone);
String dateTimeInUsersFormat = dateTime.format(formatter);
System.out.println(dateTimeInUsersFormat);
_
上記のスニペットは以下を印刷します。
4 Noll 2017 05:01:18
「Noll」は12月のゲール語であるため、ユーザーを満足させるはずです。タシケントに住んでいるゲール語を話す人がほとんどいない場合を除き、ユーザーの正しいタイムゾーンとロケールを自分で指定してください。
データベースからマイクロ秒を取得したことを真剣に考えています。 2番目の精度が問題ない場合は、remainingMicros
を使用せずに、1引数Instant.ofEpochSecond()
を使用するだけでコードを数行短くできます。 Instant
とZonedDateTime
はナノ秒の精度をサポートしているため、タイムスタンプの完全な精度を維持することが最も正しいことがわかりました。タイムスタンプがマイクロ秒ではなくミリ秒単位である場合(多くの場合)、Instant.ofEpochMilli()
を使用できます。
この質問が7年前に尋ねられたとき、Date
、Calendar
、および/またはSimpleDateFormat
を使用した回答は問題ありませんでした。今日、これらのクラスはすべて古くなっており、最新のJava日付と時刻API)である_Java.time
_の方がはるかに優れています。
ほとんどの用途では、コードで行っているように、組み込みのローカライズされた形式を使用することをお勧めします。書式スタイルにSHORT
、LONG
、またはFULL
を渡すことを試すことができます。 Yoは、オーバーロードされたofLocalizedDateTime
メソッドを使用して、日付と時刻の形式スタイルを個別に指定することもできます。特定の形式が必要な場合(これは 重複する質問 で尋ねられました)、次のようにできます。
_ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss, dd/MM/uuuu");
_
代わりにこのフォーマッターを使用すると、
05:01:18、2017年4月12日
リンク:Oracleチュートリアル:日時 _Java.time
_の使用方法の説明.
私はこれを試し、私のために働きました。
Date = (long)(DateTime.Now.Subtract(new DateTime(1970, 1, 1, 0, 0, 0))).TotalSeconds
時間、分、秒の前に先行ゼロを表示するには、以下の修正コードを使用します。ここでのコツは、整数を文字列に変換(またはより正確にフォーマット)して、該当する場合は常に先頭にゼロを表示することです。
public String convertTimeWithTimeZome(long time) {
Calendar cal = Calendar.getInstance();
cal.setTimeZone(TimeZone.getTimeZone("UTC"));
cal.setTimeInMillis(time);
String curTime = String.format("%02d:%02d:%02d", cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND));
return curTime;
}
結果は次のようになります:00:01:30