[英]How to change time unit from seconds to days/months/years
I am bashing my head against Java's Temporal API. 我反对Java的Temporal API。 I can't find anything in the Java Docs or anywhere else that'll answer what I need to do.
我在Java文档或其他任何地方都找不到任何可以回答我需要做的事情。 I simply need to at 1,000,000,000 seconds to a date and return the date, calculating the moment someone lived a billion seconds (somewhere around 30 years.)
我只需要以10亿秒为单位返回一个日期并计算该日期,即某人活出10亿秒(大约30年左右)的时间。
public Temporal getGigasecondDate(Temporal given) {
final long gigasecond = 1000000000;
final long gigaDays = gigasecond / 60 / 60 / 24;
Duration amount = Duration.ofDays(gigaDays);
Temporal date = amount.addTo(given);
return date;
}
I get an error saying Exception in thread "main" java.time.DateTimeException: Unit must be Years, Months or Days, but was Seconds
and I can't for the life of me find a way in the JavaDocs, or anywhere else, figure out how to get the unit to years, months, or days. 我收到一条错误消息,说
Exception in thread "main" java.time.DateTimeException: Unit must be Years, Months or Days, but was Seconds
,我一生无法在JavaDocs或其他任何地方找到方法,弄清楚如何使单位为年,月或日。
All I need to do, is return a Temporal object that states the moment someone has lived a billion seconds. 我需要做的就是返回一个Temporal对象,该对象声明某人生活了十亿秒的时刻。
ZonedDateTime.of( // Mom gave birth at 3 AM in year 2000, New Zealand time.
2000 , 1 , 23 , 3 , 45 , 0 , 0 , ZoneId.of( "Pacific/Auckland" )
) // Returns a `ZonedDateTime` object.
.plus(
Duration.ofSeconds( 1_000_000_000L ) // A billion seconds.
) // Returns another `ZonedDateTime` object. Immutable objects in *java.time* means we get a fresh object rather than “mutating” (altering) the original.
.toString() // Generate a `String` representing the value of our `ZonedDateTime` object, using standard ISO 8601 format wisely extended to append the name of the time zone in square brackets.
2031-10-01T05:31:40+13:00[Pacific/Auckland]
2031-10-01T05:31:40 + 13:00 [太平洋/奥克兰]
The Answer by Andreas is correct. 安德烈亚斯的答案是正确的。 Here are a few more thoughts.
这里还有一些想法。
Temporal
Temporal
The documentation for java.time explains that generally in an app you should be using the concrete classes rather than the interfaces and superclasses. java.time的文档解释说,通常在应用程序中,您应该使用具体的类,而不是接口和超类。 To quote from
Temporal
interface: 从
Temporal
接口引用:
This interface is a framework-level interface that should not be widely used in application code.
该接口是框架级别的接口,不应在应用程序代码中广泛使用。 Instead, applications should create and pass around instances of concrete types, such as LocalDate.
相反,应用程序应创建并传递具体类型的实例,例如LocalDate。 There are many reasons for this, part of which is that implementations of this interface may be in calendar systems other than ISO.
造成这种情况的原因很多,部分原因是该接口的实现可能在ISO以外的日历系统中。 See ChronoLocalDate for a fuller discussion of the issues.
有关问题的更详细讨论,请参见ChronoLocalDate。
[add] 1,000,000,000 seconds to a date and return the date,
[将] 1,000,000,000秒添加到日期并返回日期,
Determine the moment of the person's birth. 确定该人的出生时刻。
LocalDate ld = LocalDate.of( 2000 , Month.JANUARY , 23 ) ;
LocalTime lt = LocalTime.of( 3 , 45 ) ; // Mom gave birth at 3 AM in New Zealand time.
ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;
See that same moment in UTC, if useful. 如果有用,请在UTC中查看同一时刻。
Instant instant = zdt.toInstant() ;
Define the amount of time to add. 定义添加时间。 The
Duration
class represents a span of time not attached to the timeline. Duration
类表示未附加到时间轴上的时间跨度。
Duration d = Duration.ofSeconds( 1_000_000_000L ) ;
Add. 加。
ZonedDateTime zdtLater = zdt.plus( d ) ;
Or, in UTC (same moment, different wall-clock time). 或者,以UTC(相同的时刻,不同的时钟时间)。
Instant instantLater = instant.plus( d ) ;
See this code run live at IdeOne.com . 看到此代码在IdeOne.com上实时运行 。
zdt.toString(): 2000-01-23T03:45+13:00[Pacific/Auckland]
zdt.toString():2000-01-23T03:45 + 13:00 [太平洋/奥克兰]
instant.toString(): 2000-01-22T14:45:00Z
Instant.toString():2000-01-22T14:45:00Z
d.toString(): PT277777H46M40S
d.toString():PT277777H46M40S
zdtLater.toString(): 2031-10-01T05:31:40+13:00[Pacific/Auckland]
zdtLater.toString():2031-10-01T05:31:40 + 13:00 [太平洋/奥克兰]
instantLater.toString(): 2031-09-30T16:31:40Z
InstantLater.toString():2031-09-30T16:31:40Z
If you care for only the date, without the time-of-day and without the time zone, extract a LocalDate
. 如果您只关心日期,没有时间和时区,则提取
LocalDate
。
LocalDate ldLater = zdtLater.toLocalDate() ;
You can call plus(long amountToAdd, TemporalUnit unit)
, with unit as ChronoUnit.SECONDS
: 您可以调用
plus(long amountToAdd, TemporalUnit unit)
,单位为ChronoUnit.SECONDS
:
public static Temporal getGigasecondDate(Temporal given) {
return given.plus(1_000_000_000, ChronoUnit.SECONDS);
}
Test 测试
System.out.println(getGigasecondDate(LocalDateTime.of(2000, 1, 1, 0, 0)));
System.out.println(getGigasecondDate(ZonedDateTime.of(2000, 1, 1, 0, 0, 0, 0, ZoneId.of("America/New_York"))));
Output 输出量
2031-09-09T01:46:40
2031-09-09T02:46:40-04:00[America/New_York]
So, someone born at midnight on Jan 1, 2000 will be 1 billion seconds old on Sep 9, 2031 at 1:46:40 AM, assuming no Daylight Savings Time. 因此,假设没有夏令时,那么在2000年1月1日午夜出生的人将在2031年9月9日上午1:46:40达到10亿秒的年龄。
If they lived in New York, it would be at 2:46:40 AM EDT. 如果他们住在纽约,那么就会是美国东部时间凌晨2:46:40。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.