10

現在の UTC 時刻がミリ秒単位であることには興味がありませんし、タイムゾーンをいじる必要もありません。元の日付はすでに UTC タイムスタンプとして保存されています。

データベースにUTC時間「2012-06-14 05:01:25」で日付を保存しています。私は日時には興味がありませんが、その日付部分だけに興味があります。そのため、Java で日付を取得し、時間、分、秒を除外すると、「2012-06-14」が残ります。

これを UTC ミリ秒に変換するにはどうすればよいですか?

4

6 に答える 6

14

編集:「時刻を無視する」部分を見逃していました。現在は存在しますが、終わりに近づいています...

SimpleDateFormat最も簡単な方法は、タイム ゾーンを適切に設定して、おそらく を使用することです。

SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US);
format.setTimeZone(TimeZone.getTimeZone("UTC"));

Date date = format.parse(text);
long millis = date.getTime();

(タイム ゾーンの設定はここで重要なビットです。そうしないと、値がローカルタイム ゾーンにあると解釈されます。)

または、これよりも簡単なことをしている場合は、はるかに優れた日付/時刻 API であるJoda Timeを使用してください。特に、スレッドセーフでSimpleDateFormat はありませんDateTimeFormatterが、次のとおりです。

// This can be reused freely across threads after construction.
DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")
    .withLocale(Locale.US)
    .withZoneUTC();

// Option 1
DateTime datetime = formatter.parseDateTime(text);
long millis = dateTime.getMillis();

// Option 2, more direct, but harder to diagnose errors
long millis = formatter.parseMillis(text);

ここまでで、caboodle 全体を解析しました。日付部分を無視する最も簡単な方法は、四捨五入することです。結局のところ、Java はうるう秒を監視しないため、単純に切り捨てることができます。

long millisPerDay = 24L * 60L * 60L * 1000L; // Or use TimeUnit
long dayMillis = (millis / millisPerDay) * millisPerDay;

これは「1970 年に丸められる」ため、1970 年より前の日付がある場合は、1 日の終わりに丸められますが、問題になる可能性は低いと思います。

Joda Time バージョンでは、代わりにこれを使用できます。

DateTime dateTime = formatter.parseDateTime(text);
long millis = dateTime.toLocalDate().getLocalMillis();

私は個人的には部分文字列を取るという考えには賛成しません。実際には時/分/秒を保持することに関心はありませんが、与えられたものを解析してから情報破棄するのが適切だと思います。他のことは別として、コードが正しくないデータで適切に失敗するようにします。

"2012-06-100"

また

"2012-06-14 25:01:25"

最初の 10 文字が問題ないという理由だけでやみくもに続行するのではなく、それを見つけるのは良いことです。

于 2012-08-22T21:12:31.500 に答える
2

更新: Ole VV による正しい回答でjava.timeクラスを使用した最新のソリューションを参照してください。

よりシンプルに

Jon Skeetの答えは正しいです。そして彼は、解析中に時刻情報を切り捨てるのではなく含めることについて、良い点を指摘しています。

ただし、彼のコードは単純化できます。Joda-Timeが最新バージョンで重要な新しいメソッドを取得したため、特にそうです: withTimeAtStartOfDay. このメソッドは、現在廃止されているすべての「真夜中」関連のクラスとメソッドに取って代わります。

彼のコードに示されているように、 Localeを指定することは良い習慣です。ただし、この特定のケースでは、Locale は必要ありません。

彼の答えは、java.util.Date、.Calendar、および java.text.SimpleTextFormat を使用するよりもはるかに優れた Joda-Time ライブラリを正しく示唆しています。これらのクラスは厄介なことで有名であり、避けるべきです。代わりに、Joda-Time またはJava 8 に組み込まれた新しいjava.time パッケージ(JSR 310 で定義された Joda-Time に触発されたもの) を使用してください。

その日の最初の瞬間

必要なものがエポックからのミリ秒のカウントである場合、時刻を無視することはできません。あなたが望むのは、時刻をその日の最初の瞬間に変更することだと思います。UTC では、これは常に時刻を意味し00:00:00.000ます。ただし、ローカル タイム ゾーンでは、夏時間やその他の異常により、最初の瞬間が異なる時間になる可能性があることに注意してください。

ISO8601

文字列はほぼ標準のISO 8601形式ですがT、途中の SPACE を a に置き換える必要があります。次に、Joda-Time には標準文字列にデフォルトで使用される組み込みのフォーマッターがあるため、結果の文字列を Joda-Time に直接フィードできます。

サンプルコード

次のコード例では、質問の意図が文字列をUTCタイム ゾーンの日時値として解析し、時刻をその日の最初の瞬間に調整してから、 Unix エポック(開始時刻) からのミリ秒数に変換することであると想定しています。 UTC で 1970 年)。

String inputRaw = "2012-06-14 05:01:25";
String input = inputRaw.replace( " ", "T" );  // Replace SPACE with a 'T'.
DateTime dateTime = new DateTime( input, DateTimeZone.UTC );  // Parse, assuming UTC.
DateTime dateTimeTopOfTheDay = dateTime.withTimeAtStartOfDay();  // Adjust to first moment of the day.
long millisecondsSinceUnixEpoch = dateTimeTopOfTheDay.getMillis();  // Convert to millis. Use a 'long', not an 'int'.
于 2014-10-08T06:39:27.963 に答える
0

Date オブジェクトを SimpleDateFormat と組み合わせて使用​​します。

Date には、ミリ秒を返す getTime() という名前のメソッドがあります。

あなたの問題を解決する例:

Date truc = new SimpleDateFormat( "y-m-d").parse( "2010-06-14");
System.out.println(truc.getTime());
于 2012-08-22T21:10:18.673 に答える