重要な概念
1. UTC と UTC+8
UTCは世界標準時、UTC+8は東8区の標準時で、中国は東8区に属しており北京時間です。
+8 は 8 時間を追加します。タイムゾーン分割図は次のとおりです。
つまり、
UTC 時間が現在2023-08-08 01:00:00
(2023 年 8 月 8 日の午前 1 時) であれば、北京時間は現在2023-08-08 09:00:00
(午前 9 時) になります。
2. タイムスタンプ
タイムスタンプは、UTC の 1970 年 1 月 1 日 (0) から始まり、その後の時間からこの時間を減算して秒数を取得する数値です。
たとえば、UTC のタイムスタンプは1970-01-01 00:00:00
0 です。1970-01-01 00:01:00
タイムスタンプは1 分後の60 です。
なぜ今回から始めるのか?
これは UNIX オペレーティング システムの規則であるため、1970 年 1 月 1 日が時代の始まりとして設定されており、多くのコンピューター関連の言語やシステムはこの規則に従っています。
特定の時刻のタイムスタンプを取得する
@Test
public void Timestamp(){
LocalDateTime dateTime = LocalDateTime.of(1970, 1, 1, 0, 0, 0);// 获取时间戳(秒数)
long timestamp = dateTime.toEpochSecond(ZoneOffset.UTC);//设置时区后获取时间戳
System.out.println("Timestamp: " + timestamp); //0, 时间戳开始
}
- LocalDateTime はタイムゾーン情報のない時刻です
- ZoneOffset.UTC は UTC のタイムゾーンを表します
Java には、現在時刻のタイムスタンプを取得する簡単な方法も用意されています。
System.currentTimeMillis()
タイムゾーンの時刻を取得する
ZonedDateTime は、タイム ゾーンを指定する必要がある時刻です。たとえば、北京時間の 1970 年 1 月 1 日の午前 8 時、次のように表現できます。
ZonedDateTime utc8DateTime= ZonedDateTime.of(1970, 1, 1, 8, 0, 0,0, ZoneId.of("UTC+8"));
東第 8 地区の時刻は UTC 標準時より 8 時間進んでいるため、上記の時刻はタイムスタンプの開始時刻でもあります。
@Test
public void zoneTimeStamp(){
ZonedDateTime utc8DateTime= ZonedDateTime.of(1970, 1, 1, 8, 0, 0,0, ZoneId.of("UTC+8"));
long timestamp =utc8DateTime.toEpochSecond();
System.out.println("Timestamp1: " + timestamp); //0
}
もちろん、タイムゾーンの時刻は LocalDateTime から変換することもできます。次に例を示します。
LocalDateTime lcoalDateTime = LocalDateTime.of(1970, 1, 1, 8, 0, 0);
ZonedDateTime zonedDateTime = ZonedDateTime.of(lcoalDateTime, ZoneId.of("UTC+8"));
timestamp =zonedDateTime.toEpochSecond();
Assert.assertEquals(0, timestamp);
フォーマットされた時刻の表示
DateTimeFormatter を使用して、時間をさまざまな形式の文字列として表示します。サンプル コードは次のとおりです。
@Test
public void dateTimeformatter() {
LocalDateTime lcoalDateTime = LocalDateTime.of(1970, 1, 1, 8, 0, 0);
ZonedDateTime zonedDateTime = ZonedDateTime.of(lcoalDateTime, ZoneId.of("UTC+8"));
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String lcoalDateTimeStr = formatter.format(lcoalDateTime);
Assert.assertEquals("1970-01-01 08:00:00", lcoalDateTimeStr);
String zonedDateTimeStr = formatter.format(zonedDateTime);
Assert.assertEquals("1970-01-01 08:00:00", zonedDateTimeStr);
}
北京の現在の時刻を取得する
現在時刻は ZonedDateTime.now() で取得できます。
@Test
public void getCurrentUtc8Time() {
// 获取UTC+8时区
ZoneId utc8ZoneId = ZoneId.of("UTC+8");
// 获取当前时间
ZonedDateTime now = ZonedDateTime.now(utc8ZoneId);
// 格式化为字符串
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String currentTime = now.format(formatter);
// 输出时间
System.out.println("Current time in UTC+8: " + currentTime);
}
UTC 標準時間を取得したい場合は、上記で取得したタイムゾーンを変更する必要があります。
ZoneId.of("UTC");
タイムスタンプを時間に変換する
タイムスタンプはインスタントで時刻に変換できます。
@Test
public void timeMillisToUtc() {
long timeMillis = 0L;
Instant instant = Instant.ofEpochMilli(timeMillis);
LocalDateTime utcDateTime = LocalDateTime.ofInstant(instant, ZoneId.of("UTC"));
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String utcTime = utcDateTime.format(formatter);
Assert.assertEquals("1970-01-01 00:00:00", utcTime);
}
注: タイムスタンプは時間とは関係ありません
実際の開発では、このようなシナリオに遭遇すると、一部のアプリケーションの認証トークンの有効期限が長整数のタイムスタンプ形式になっている場合、誰かが「これは +8 によって処理されましたか?」と尋ねます。時間は?」 明らかに、この質問は非常に専門的ではありません。
タイムスタンプは時刻、つまり UTC 開始時刻を基準とした時刻に対応しており、このタイムスタンプは他のタイムゾーンの時刻に変換できますが、タイムスタンプ自体にはタイムゾーンの差はありません。つまり、タイムスタンプは 0 で、UTC 時間の 1970 年 1 月 1 日の 0 時、つまり 1970 年 1 月 1 日の午前 8 時に対応します。
要約する
- LocalDateTime はタイムゾーンとは関係のない時間処理クラスです。
- ZonedDateTime はタイムゾーンに関連する時間処理クラスです。
- タイムスタンプの開始時刻は 1970 年 1 月 1 日の 0:00、つまり北京時間の午前 8:00 です。
- タイムスタンプはタイムゾーンに依存しません