2 回答

TA貢獻(xiàn)1780條經(jīng)驗(yàn) 獲得超1個贊
你不應(yīng)該使用這個Calendar
類,因?yàn)樗呀?jīng)過時了。您應(yīng)該改用java.time
包中的類。
為了獲得所需的結(jié)果,您可以使用該類Period
。
您首先需要將兩個Calendar
實(shí)例都轉(zhuǎn)換為LocalDate
instances。
然后您可以使用Period.between(startDate, endDate)
to 獲取一個Period
實(shí)例,這使得getDays()
和getMonths()
方法getYears()
對您可用。
如果您還想包括時間組件(小時、分鐘和秒),那么您可以Duration
結(jié)合使用Period
.?
這樣的事情可能會起作用:
LocalDateTime start = LocalDateTime.of(2019, 1, 1, 12, 0, 0);
LocalDateTime end = LocalDateTime.of(2021, 4, 26, 5, 56, 40);
Duration d = Duration.between(start.toLocalTime(), end.toLocalTime());
Period p = Period.between(start.toLocalDate(), end.toLocalDate());
// If the startdate's time component lies behind the enddate's time component,
// then we need to correct both the Period and Duration
if (d.isNegative()) {
? ? p = p.minusDays(1);
? ? d = d.plusDays(1);
}
System.out.printf("y %s m %s d %s h %s m %s s %s%n",
? ? p.getYears(),
? ? p.getMonths(),
? ? p.getDays(),
? ? d.toHours() % 24,
? ? d.toMinutes() % 60,
? ? d.getSeconds() % 60);
請注意,Java 9 附帶to…Part方法,因此您不必再使用模運(yùn)算符。
請注意:由于夏令時,此代碼未考慮時鐘調(diào)整。

TA貢獻(xiàn)1802條經(jīng)驗(yàn) 獲得超10個贊
Period
.between(
? ? ( ( GregorianCalendar ) myCalStart ).toZonedDateTime().toLocalDate() ,
? ? ( ( GregorianCalendar ) myCalStop ).toZonedDateTime().toLocalDate()?
)
…或者…
Duration
.between(
? ? ( ( GregorianCalendar ) myCalStart ).toInstant() ,
? ? ( ( GregorianCalendar ) myCalStop ).toInstant()?
)
java.time
您正在使用多年前被 JSR 310 中定義的現(xiàn)代java.time類所取代的可怕的日期時間類。
切勿使用Calendar
,?GregorianCalendar
,?Date
,SimpleDateFormat
等。僅使用在java.time包中找到的類。
ZonedDateTime
假設(shè)您的兩個Calendar
對象實(shí)際上都是GregorianCalendar
下面的對象,請轉(zhuǎn)換。要進(jìn)行轉(zhuǎn)換,請調(diào)用添加到舊類的新to…
/方法。from…
// start
GregorianCalendar gcStart = ( GregorianCalendar ) myCalStart ;
ZonedDateTime zdtStart = gcStart.toZonedDateTime() ;
// stop
GregorianCalendar gcStop = ( GregorianCalendar ) myCalStop ;
ZonedDateTime zdtStop = gcStop.toZonedDateTime() ;
和 都GregorianCalendar
代表ZonedDateTime
一個日期和一個時區(qū)上下文中的時間,結(jié)合起來確定一個時刻(時間軸上的特定點(diǎn))。ZonedDateTime
解析到更精細(xì)的納秒級而不是毫秒級。
Period
如果您關(guān)心以年-月-日為單位的經(jīng)過時間,請使用Period
對象LocalDate
。LocalDate
表示沒有時間和時區(qū)的日期。我們可以從我們的對象中提取日期部分ZonedDateTime
。
LocalDate ldStart = zdtStart.toLocalDate() ;
LocalDate ldStop = zdtStop.toLocalDate() ;
Period p = Period.between( ldStart , ldStop ) ;
生成標(biāo)準(zhǔn)ISO 8601格式的字符串。
String output = p.toString() ;
詢問數(shù)年、數(shù)月、數(shù)日。
int years = p.getYears() ;
int months = p.getMonths() ;
int days = p.getDays() ;
Duration
如果您以小時-分鐘-秒的形式計(jì)算經(jīng)過的時間,請使用Duration
.?此類代表 UTC 中的一對時刻。因此,我們Instant
從我們的ZonedDateTime
對象對中提取對象,這些對象在內(nèi)部保留自 UTC 1970 年第一時刻的紀(jì)元參考以來的整秒計(jì)數(shù),加上小數(shù)秒作為納秒計(jì)數(shù)。
Instant instantStart = zdtStart.toInstant() ;
Instant instantStop = zdtStop.toInstant() ;
Duration d = Duration.between( instantStart , instantStop ) ;
生成標(biāo)準(zhǔn)ISO 8601格式的字符串。
String output = d.toString() ;
查詢天數(shù)(與日歷無關(guān)的 24 小時時間塊)、小時、分鐘、秒。
long days = d.toDaysPart() ;
int hours = d.toHoursPart() ;
int minutes = d.toMinutesPart() ;
int seconds = d.toSecondsPart() ;
int nanos = d.toNanosPart() ;
PeriodDuration
如果您考慮一下,您會發(fā)現(xiàn)將年/月/日與 24 小時-日/小時/分鐘/秒結(jié)合起來是沒有意義的。
添加回答
舉報