[英]How to get date part (dispose of time part) from java.util.Date?
我想比較兩個java.util.Date
對象的日期部分。 我怎樣才能做到這一點? 我不打算分別比較日期,月份和年份。
提前致謝!
commons-lang DateUtils為這個問題提供了一個很好的解決方案:
通過這種方式,您可以在一行中比較兩個Date
實例,而無法看到所需Date
的每個部分。
Date date1 = new Date(2011, 8, 30, 13, 42, 15);
Date date2 = new Date(2011, 8, 30, 15, 23, 46);
int compareTo = DateUtils.truncatedCompareTo(date1, date2,
Calendar.DAY_OF_MONTH);
在此示例中, compareTo
值為0。
Date
只是一個瞬間。 當您將日歷和時區應用於日期時,它實際上只是“意味着”任何日期。 因此,您應該真正關注Calendar
,如果您想要堅持使用標准Java API - 您可以使用正確的Date
和時區創建Calendar
對象,然后將時間組件設置為0。
但是,使用Joda Time以及它的LocalDate
類型會更好,它更准確地反映了您感興趣的內容。
將Calendar.set()
與Calendar.HOUR_OF_DAY
, Calendar.MINUTE
, Calendar.SECOND
和Calendar.MILLISECOND
一起使用,將所有這些字段設置為0。
這個重復問題的答案很有用: 重置Java中時間戳的時間部分
在下面找到一個采用Joda Time並支持時區的解決方案。 因此,您將在JVM中當前配置的時區中獲取日期和時間(到currentDate
和currentTime
)。
請注意,Joda Time不支持閏秒 。 所以,你可以離開真正價值26或27秒。 這可能只會在未來50年內解決,屆時積累的誤差將接近1分鍾,人們將開始關心它。
另見: https : //en.wikipedia.org/wiki/Leap_second
/**
* This class splits the current date/time (now!) and an informed date/time into their components:
* <lu>
* <li>schedulable: if the informed date/time is in the present (now!) or in future.</li>
* <li>informedDate: the date (only) part of the informed date/time</li>
* <li>informedTime: the time (only) part of the informed date/time</li>
* <li>currentDate: the date (only) part of the current date/time (now!)</li>
* <li>currentTime: the time (only) part of the current date/time (now!)</li>
* </lu>
*/
public class ScheduleDateTime {
public final boolean schedulable;
public final long millis;
public final java.util.Date informedDate;
public final java.util.Date informedTime;
public final java.util.Date currentDate;
public final java.util.Date currentTime;
public ScheduleDateTime(long millis) {
final long now = System.currentTimeMillis();
this.schedulable = (millis > -1L) && (millis >= now);
final TimeZoneUtils tz = new TimeZoneUtils();
final java.util.Date dmillis = new java.util.Date( (millis > -1L) ? millis : now );
final java.time.ZonedDateTime zdtmillis = java.time.ZonedDateTime.ofInstant(dmillis.toInstant(), java.time.ZoneId.systemDefault());
final java.util.Date zdmillis = java.util.Date.from(tz.tzdate(zdtmillis));
final java.util.Date ztmillis = new java.util.Date(tz.tztime(zdtmillis));
final java.util.Date dnow = new java.util.Date(now);
final java.time.ZonedDateTime zdtnow = java.time.ZonedDateTime.ofInstant(dnow.toInstant(), java.time.ZoneId.systemDefault());
final java.util.Date zdnow = java.util.Date.from(tz.tzdate(zdtnow));
final java.util.Date ztnow = new java.util.Date(tz.tztime(zdtnow));
this.millis = millis;
this.informedDate = zdmillis;
this.informedTime = ztmillis;
this.currentDate = zdnow;
this.currentTime = ztnow;
}
}
public class TimeZoneUtils {
public java.time.Instant tzdate() {
final java.time.ZonedDateTime zdtime = java.time.ZonedDateTime.now();
return tzdate(zdtime);
}
public java.time.Instant tzdate(java.time.ZonedDateTime zdtime) {
final java.time.ZonedDateTime zddate = zdtime.truncatedTo(java.time.temporal.ChronoUnit.DAYS);
final java.time.Instant instant = zddate.toInstant();
return instant;
}
public long tztime() {
final java.time.ZonedDateTime zdtime = java.time.ZonedDateTime.now();
return tztime(zdtime);
}
public long tztime(java.time.ZonedDateTime zdtime) {
final java.time.ZonedDateTime zddate = zdtime.truncatedTo(java.time.temporal.ChronoUnit.DAYS);
final long millis = zddate.until(zdtime, java.time.temporal.ChronoUnit.MILLIS);
return millis;
}
}
LocalDate ld =
myUtilDate.toInstant()
.atZone( ZoneId.of( "America/Montreal" ) )
.toLocalDate() ;
您正在使用麻煩的舊遺留日期時間類。 避免他們。
而是使用java.time類。 這些取代了舊類以及Joda-Time庫。
將java.util.Date
轉換為Instant
。
Instant
類表示UTC時間軸上的一個時刻,分辨率為納秒 。
Instant instant = myUtilDate.toInstant();
應用時區。 時區至關重要。 對於任何特定時刻,日期在全球范圍內因地區而異。 例如,法國巴黎午夜過后幾分鍾是新的一天,同時也是魁北克蒙特利爾的“昨天”。
應用ZoneId
以獲取ZonedDateTime
對象。
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );
Local…
類型 LocalDate
類表示沒有時間且沒有時區的僅日期值。 同樣, LocalTime
表示沒有日期且沒有時區的時間。 您可以將這些視為兩個組件,它們與ZoneId
一起構成ZonedDateTime
。 您可以從ZonedDateTime
提取這些ZonedDateTime
。
LocalDate ld = zdt.toLocalDate();
LocalTime lt = zdt.toLocalTime();
如果您的目標僅僅是為用戶生成字符串,則不需要Local…
類型。 而是使用DateTimeFormatter
生成僅表示日期部分或時間部分的字符串。 該類足夠智能,可以在生成String時自動進行本地化 。
指定Locale
以確定(a)用於翻譯日期名稱,月份名稱等的人類語言,以及(b)用於確定諸如縮寫,大小寫,標點符號等問題的文化規范。
Locale l = Locale.CANADA_FRENCH ; // Or Locale.US, Locale.ITALY, etc.
DateTimeFormatter fDate = DateTimeFormatter.ofLocalizedDate( FormatStyle.MEDIUM ).withLocale( locale );
String outputDate = zdt.format( fDate );
DateTimeFormatter fTime = DateTimeFormatter.ofLocalizedTime( FormatStyle.MEDIUM ).withLocale( locale );
String outputTime = zdt.format( fTime );
java.time框架內置於Java 8及更高版本中。 這些類取代了舊的麻煩的日期時間類,如java.util.Date
, .Calendar
和java.text.SimpleDateFormat
。
現在處於維護模式的Joda-Time項目建議遷移到java.time。
要了解更多信息,請參閱Oracle教程 。 並搜索Stack Overflow以獲取許多示例和解釋。
大部分的java.time功能后移植到Java 6和7 ThreeTen,反向移植 ,並進一步適應的Android在ThreeTenABP (見如何使用...... )。
ThreeTen-Extra項目使用其他類擴展了java.time。 該項目是未來可能添加到java.time的試驗場。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.