如何从 java.util.Date 获取日期部分(处理时间部分)?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7609582/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 20:40:51  来源:igfitidea点击:

How to get date part (dispose of time part) from java.util.Date?

javadatecalendardate-comparison

提问by MozenRath

I want to compare the date part of two java.util.Dateobjects. How can I achieve this? I am not looking to comparing the date, month and year separately.

我想比较两个java.util.Date对象的日期部分。我怎样才能做到这一点?我不想分别比较日期、月份和年份。

Thanks in advance!

提前致谢!

采纳答案by Jon Skeet

A Dateis just an instant in time. It only really "means" anything in terms of a date when you apply a calendar and time zone to it. As such, you should really be looking at Calendar, if you want to stick within the standard Java API - you can create a Calendarobject with the right Dateand time zone, then set the time components to 0.

ADate只是一个瞬间。当您将日历和时区应用于日期时,它只是真正“意味着”任何日期。因此,您真的应该考虑一下Calendar,如果您想坚持使用标准 Java API - 您可以创建一个Calendar具有正确Date时区的对象,然后将时间组件设置为 0。

However, it would be nicer to use Joda Timeto start with, and its LocalDatetype, which more accurately reflects what you're interested in.

但是,最好使用Joda Time开始,它的LocalDate类型更准确地反映您感兴趣的内容。

回答by Turbokiwi

The commons-lang DateUtils provide a nice solution for this problem:

commons-lang DateUtils 为这个问题提供了一个很好的解决方案:

watch this

看这个

With this you can compare two Dateinstances in a single line, loosing sight of every part of the Dateyou want.

有了这个,您可以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);

In this example the value of compareTois 0.

在本例中,的值为compareTo0。

回答by Xavi López

Use Calendar.set()with Calendar.HOUR_OF_DAY, Calendar.MINUTE, Calendar.SECONDand Calendar.MILLISECONDto set all those fields to 0.

使用Calendar.set()Calendar.HOUR_OF_DAYCalendar.MINUTECalendar.SECONDCalendar.MILLISECOND所有这些字段设置为0。

The answers to this duplicate question will be useful: Resetting the time part of a timestamp in Java

这个重复问题的答案会很有用:Resetting the time part of a timestamp in Java

回答by Richard Gomes

Find below a solution which employs Joda Time and supports time zones. So, you will obtain date and time (into currentDateand currentTime) in the currently configured timezone in the JVM.

在下面找到一个使用 Joda 时间并支持时区的解决方案。因此,您将在 JVM 中当前配置的时区中获取日期和时间(进入currentDatecurrentTime)。

Please notice that Joda Time does not support leap seconds. So, you can be some 26 or 27 seconds off the true value. This probably will only be solved in the next 50 years, when the accumulated error will be closer to 1 min and people will start to care about it.

请注意 Joda Time 不支持闰秒。因此,您可能与真实值相差 26 或 27 秒。这可能要在未来 50 年才能解决,届时累积误差将接近 1 分钟,人们会开始关心它。

See also: https://en.wikipedia.org/wiki/Leap_second

另见: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;
    }
}

回答by Basil Bourque

tl;dr

tl;博士

LocalDate ld = 
    myUtilDate.toInstant()
              .atZone( ZoneId.of( "America/Montreal" ) )
              .toLocalDate() ;

Avoid legacy date-time classes

避免遗留的日期时间类

You are using troublesome old legacy date-time classes. Avoid them.

您正在使用麻烦的旧式日期时间类。避开它们。

Instead use java.timeclasses. These supplant the old classes as well as the Joda-Time library.

而是使用java.time类。这些取代了旧的类以及 Joda-Time 库。

Convert

兑换

Convert your java.util.Dateto an Instant.

将您的转换java.util.DateInstant.

The Instantclass represents a moment on the timeline in UTCwith a resolution of nanoseconds.

Instant级表示时间轴上的时刻UTC,分辨率为纳秒

Instant instant = myUtilDate.toInstant();

Time Zone

时区

Apply a time zone. Time zone is crucial. For any given moment the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while also being “yesterday” in Montréal Québec.

应用时区。时区至关重要。对于任何给定时刻,日期因地区而异。例如,在法国巴黎午夜过后几分钟是新的一天,而在魁北克蒙特利尔也是“昨天”。

Apply a ZoneIdto get a ZonedDateTimeobject.

应用 aZoneId来获取一个ZonedDateTime对象。

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );

Local…types

Local…类型

The LocalDateclass represents a date-only value without time-of-day and without time zone. Likewise, the LocalTimerepresents a time-of-day without a date and without a time zone. You can think of these as two components which along with a ZoneIdmake up a ZonedDateTime. You can extract these from a ZonedDateTime.

LocalDate级表示没有时间一天和不同时区的日期,唯一的价值。同样,LocalTime表示没有日期和时区的时间。您可以将它们视为两个组件,它们与ZoneId一个ZonedDateTime. 您可以从ZonedDateTime.

LocalDate ld = zdt.toLocalDate();
LocalTime lt = zdt.toLocalTime();

Strings

字符串

If your goal is merely generating Strings for presentation to the user, no need for the Local…types. Instead, use DateTimeFormatterto generate strings representing only the date-portion or the time-portion. That class is smart enough to automatically localizewhile generating the String.

如果您的目标只是生成字符串以呈现给用户,则不需要Local…类型。相反,用于DateTimeFormatter生成仅表示日期部分或时间部分的字符串。该类足够智能,可以在生成字符串时自动进行本地化

Specify a Localeto determine (a) the human language used for translating name of day, name of month, and such, and (b) the cultural norms for deciding issues such as abbreviation, capitalization, punctuation, and such.

指定 aLocale以确定 (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 );

About java.time

关于 java.time

The java.timeframework is built into Java 8 and later. These classes supplant the old troublesome date-time classes such as java.util.Date, .Calendar, & java.text.SimpleDateFormat.

java.time框架是建立在Java 8和更高版本。这些类取代了旧的麻烦的日期时间类,例如java.util.Date, .Calendar, & java.text.SimpleDateFormat

The Joda-Timeproject, now in maintenance mode, advises migration to java.time.

现在处于维护模式Joda-Time项目建议迁移到 java.time。

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations.

要了解更多信息,请参阅Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。

Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backportand further adapted to Androidin ThreeTenABP(see How to use…).

大部分的java.time功能后移植到Java 6和7 ThreeTen,反向移植,并进一步用于安卓ThreeTenABP(见如何使用......)。

The ThreeTen-Extraproject extends java.time with additional classes. This project is a proving ground for possible future additions to java.time.

ThreeTen-额外项目与其他类扩展java.time。该项目是未来可能添加到 java.time 的试验场。