2 回答

TA貢獻(xiàn)1780條經(jīng)驗(yàn) 獲得超1個(gè)贊
你不應(yīng)該使用這個(gè)Calendar
類(lèi),因?yàn)樗呀?jīng)過(guò)時(shí)了。您應(yīng)該改用java.time
包中的類(lèi)。
為了獲得所需的結(jié)果,您可以使用該類(lèi)Period
。
您首先需要將兩個(gè)Calendar
實(shí)例都轉(zhuǎn)換為LocalDate
instances。
然后您可以使用Period.between(startDate, endDate)
to 獲取一個(gè)Period
實(shí)例,這使得getDays()
和getMonths()
方法getYears()
對(duì)您可用。
如果您還想包括時(shí)間組件(小時(shí)、分鐘和秒),那么您可以Duration
結(jié)合使用Period
.?
這樣的事情可能會(huì)起作用:
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);
請(qǐng)注意,Java 9 附帶to…Part方法,因此您不必再使用模運(yùn)算符。
請(qǐng)注意:由于夏令時(shí),此代碼未考慮時(shí)鐘調(diào)整。

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