我现在有一个纪元时间,我想得到 30 天、3 个月和 1 年的纪元时间如何在 java 代码中做到这一点。
long todayEpochTime = System.currentTimeMillis()/1000;
System.out.println(todayEpochTime);
使用LocalDate
我们可以尝试:
LocalDate date = LocalDate.now().minusDays(30).minusMonths(3).minusYears(1);
ZoneId zoneId = ZoneId.systemDefault();
long newEpoch = date.atStartOfDay(zoneId).toEpochSecond();
在撰写此问题时,日期是 2019 年 12 月 9 日,新的纪元值对应于该日期:
Wednesday, August 8, 2018 10:00:00 PM
您可以使用特定ZoneId
纪元中的毫秒来获取Instant
的实例,然后减去天,月和年
long todayEpochTime = System.currentTimeMillis();
long dateTime = Instant.ofEpochMilli(todayEpochTime)
.atZone(ZoneId.systemDefault())
.minusDays(30)
.minusMonths(3)
.minusYears(1)
.toEpochSecond();
System.out.println(todayEpochTime);
System.out.println(dateTime);
tl;博士
如果您只想使用 UTC 而不是时区工作:
Instant
.ofEpochSecond( secondsSinceEpoch )
.minus(
Period.ofDays( 30 )
)
.toEpochSecond()
注意:虽然 UTC 中的天数始终为 24 小时,但不同时区的天数可能会更长或更短,从而产生不同的结果。
另一个问题:对于任何给定时刻,日期因时区而异。
如果要使用日期而不是时刻:
Instant
.ofEpochSecond( secondsSinceEpoch )
.atZone(
ZoneId.of( "Africa/Tunis" )
)
.toLocalDate()
.minusDays( 30 )
.atStartOfDay(
ZoneId.of( "Africa/Tunis" )
)
.toEpochSecond()
java.time
显然,自 UTC 中 1970 年第一个时刻的纪元参考以来,您有一个整整秒的计数,1970-01-01T00:00:00.0Z。
Instant
解析为Instant
。
Instant instant = Instant.ofEpochSecond( secondsSinceEpoch ) ;
对于任何给定时刻,日期因时区而异。日本东京午夜过后几分钟是新的一天,而在法国巴黎和美国俄亥俄州托莱多仍然是"昨天"。
ZonedDateTime
应用您希望感知日期的时区。将ZoneId
传递给Instant
以获得ZonedDateTime
。
ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
减去你的时间跨度。
ZonedDateTime thirtyDaysEarlier = zdt.minusDays( 30 ) ;
ZonedDateTime threeMonthsEarlier = zdt.minusMonths( 3 ) ;
ZonedDateTime oneYearEarlier = zdt.minusYears 1 ) ;
LocalDate
如果您只关心日期部分,没有一天中的时间和时区,请提取LocalDate
。然后做同样的日期数学。
LocalDate localDate = zdt.toLocalDate() ;
Period
您可以使用Period
表示您的时间跨度。然后做你的约会数学。保留为常量的命名变量优先于单纯的整数,以使代码更具自我记录性,提供类型安全性并确保有效值。
Period periodDays30 = Period.ofDays( 30 ) ;
Period periodMonths3 = Period.ofMonths( 3 ) ;
Period periodYears1 = Period.ofYears( 1 ) ;
LocalDate then = localDate.minus( periodDays30 ) ;
字符串
至于字符串,要生成标准ISO 8601格式的文本,只需调用.toString()
即可。
对于其他格式,请使用DateTimeFormatter
。这个问题已经解决了很多次,所以搜索堆栈溢出以了解更多信息。