如何使用 Java 从现在开始减去 30 天、3 个月和 1 年的纪元时间?



我现在有一个纪元时间,我想得到 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。这个问题已经解决了很多次,所以搜索堆栈溢出以了解更多信息。

最新更新