簡體   English   中英

如何從java.util.Date獲取日期部分(處理時間部分)?

[英]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_DAYCalendar.MINUTECalendar.SECONDCalendar.MILLISECOND一起使用,將所有這些字段設置為0。

這個重復問題的答案很有用: 重置Java中時間戳的時間部分

在下面找到一個采用Joda Time並支持時區的解決方案。 因此,您將在JVM中當前配置的時區中獲取日期和時間(到currentDatecurrentTime )。

請注意,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;
    }
}

TL;博士

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.time框架內置於Java 8及更高版本中。 這些類取代了舊的麻煩的日期時間類,如java.util.Date.Calendarjava.text.SimpleDateFormat

現在處於維護模式Joda-Time項目建議遷移到java.time。

要了解更多信息,請參閱Oracle教程 並搜索Stack Overflow以獲取許多示例和解釋。

大部分的java.time功能后移植到Java 6和7 ThreeTen,反向移植 ,並進一步適應的AndroidThreeTenABP (見如何使用...... )。

ThreeTen-Extra項目使用其他類擴展了java.time。 該項目是未來可能添加到java.time的試驗場。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM