1 回答

TA貢獻1802條經驗 獲得超6個贊
這里不需要SimpleDateFormat
,as表示自Unix EpochDate
以來的毫秒數,即 1970 年 1 月 1 日午夜(UTC)。
然而,可能導致混淆的是方法,toString()
因為它在生成表示該值的字符串時應用 JVM 的默認時區。
由于您擔心 UTC,讓我提醒您注意協調世界時 (UTC) 實際上是什么:它是一個時間標準(而不是時區),它由高精度原子鐘和地球自轉決定。
UTC 時間標準經過多次調整,直到 1972 年引入閏秒以使 UTC 與地球自轉保持一致,地球自轉并不完全均勻,而且不如原子鐘精確。隨著地球自轉速度的減慢,我們不得不時不時地在各處插入閏秒:
雖然 的內部值Date
旨在反映 UTC,但由于那些閏秒,它可能不會完全這樣做。
Java 8 和日期和時間的新 API
即使Date
在涉及 UTC 時適合您的需求,您也應該避免使用它?,F在是遺留類。
Java 8為基于 ISO 日歷系統的日期、時間、瞬間和持續時間引入了新的 API 。最接近的等價物Date
是Instant
代表時間戳,UTC 時間線上的時刻。
要以 UTC 格式捕獲當前時刻,您可以使用以下命令:
Instant.now(); // Capture the current moment in UTC
您可以使用以下內容來獲取表示此類值的字符串:
Instant.now().toString(); // 2019-05-17T12:50:40.474Z
此字符串根據ISO 8601進行格式化,其中Z
指示給定時間為 UTC。
與 JJWT 的互操作性
對于尚不支持類型的JJWT 的互操作性java.time
,您可以創建Date
from的實例Instant
:
Date.from(Instant.now()); // Convert from modern class to legacy class
這是一個演示如何發布和驗證令牌的測試:
@Test
public void shouldMatchIssuedAtAndExpiration() {
Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);
Instant issuedAt = Instant.now().truncatedTo(ChronoUnit.SECONDS);
Instant expiration = issuedAt.plus(3, ChronoUnit.MINUTES);
log.info("Issued at: {}", issuedAt);
log.info("Expires at: {}", expiration);
String jws = Jwts.builder()
.setIssuedAt(Date.from(issuedAt))
.setExpiration(Date.from(expiration))
.signWith(key)
.compact();
Claims claims = Jwts.parser()
.setSigningKey(key)
.parseClaimsJws(jws)
.getBody();
assertThat(claims.getIssuedAt().toInstant(), is(issuedAt));
assertThat(claims.getExpiration().toInstant(), is(expiration));
}
對于上面的示例,我使用了 JJWT 0.10.5 以及文檔中列出的依賴項。如果您需要,上面的代碼是用以下import語句編寫的:
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import java.security.Key;
import java.time.Instant;
import java.time.ZoneOffset;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
添加回答
舉報