检查日期是否与今天的日期相同

40

我写了一些代码来检查两个日期:开始日期和结束日期。如果结束日期在开始日期之前,它会提示显示结束日期在开始日期之前。

我还想增加一个检查,以确定开始日期是否在今天之前(今天指用户使用应用程序的那一天)。我该如何做?(下面是日期检查器代码,也都是为 Android 编写的,如果这有任何影响,请告诉我)

if (startYear > endYear) {
    fill = fill + 1;
    message = message + "End Date is Before Start Date" + "\n";
} else if (startMonth > endMonth && startYear >= endYear) {
    fill = fill + 1;
    message = message + "End Date is Before Start Date" + "\n";
} else if (startDay > endDay && startMonth >= endMonth && startYear >= endYear) {
    fill = fill + 1;
    message = message + "End Date is Before Start Date" + "\n";
}
12个回答

152

不要把它搞得那么复杂。使用这个简单的方法。导入DateUtils java类,并调用以下方法,该方法返回一个布尔值。

DateUtils.isSameDay(date1,date2);
DateUtils.isSameDay(calender1,calender2);
DateUtils.isToday(date1);

了解更多信息,请参考本文 DateUtils Java



8
这很简单,做这个。 - Tyler Pfaff
1
这可能很简单,但是很重要的是让人们明白这只是示例代码,似乎没有测试/覆盖率。它被呈现在这里作为你可以拉入的一些库,但它与其他答案中的其他代码片段没有什么不同。最好拉入一个像Joda或Commons这样的库,因为你可以依赖它们的社区维护。抱歉挑剔你的回答,其他人可能会遇到相同的问题。请,请尽可能使用库。如果您必须从网上复制代码,请确保在进入生产之前进行测试和理解。 - Sander Verhagen
4
我遇到了错误:“The method isToday() is undefined for the type DateUtils”。意思是“在DateUtils类型中未定义isToday()方法”。 - learner
4
这个方法只存在于Android版本的DateUtils中。对于 "desktop" JDK,请使用 DateUtils.isSameDay(someday, new Date()); - Nikolai Shevchenko
我相信这是来自Apache Commons Lang。 - Jakob Hartman

46

这有帮助吗?

Calendar c = Calendar.getInstance();

// set the calendar to start of today
c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);

// and get that as a Date
Date today = c.getTime();

// or as a timestamp in milliseconds
long todayInMillis = c.getTimeInMillis();

// user-specified date which you are testing
// let's say the components come from a form or something
int year = 2011;
int month = 5;
int dayOfMonth = 20;

// reuse the calendar to set user specified date
c.set(Calendar.YEAR, year);
c.set(Calendar.MONTH, month);
c.set(Calendar.DAY_OF_MONTH, dayOfMonth);

// and get that as a Date
Date dateSpecified = c.getTime();

// test your condition
if (dateSpecified.before(today)) {
  System.err.println("Date specified [" + dateSpecified + "] is before today [" + today + "]");
} else {
  System.err.println("Date specified [" + dateSpecified + "] is NOT before today [" + today + "]");
}

1
在开始时,毫秒数也应该重置为零吗? - Mister Smith
2
使用 Joda Time 的 DateMidnight,您无需重置任何内容。 - martin
毫秒也需要重置 c.set(Calendar.MILLISECOND, 0); 如果不这样做,如果您比较同一天的日期,就会出现问题。 - DragonT
2
使用 Calendar.HOUR 是错误的,因为它不会重置 AM/PM 属性,因此如果当前时间是下午 13 点,则结果小时将为下午 12 点。请改用 Calendar.HOUR_OF_DAY - mgaido
1
更新:这些可怕的日期时间类现在已被JSR 310中定义的现代java.time类所取代。 - Basil Bourque
显示剩余2条评论

13

使用纯Java:

public static boolean isToday(Date date){
        Calendar today = Calendar.getInstance();
        Calendar specifiedDate  = Calendar.getInstance();
        specifiedDate.setTime(date);

        return today.get(Calendar.DAY_OF_MONTH) == specifiedDate.get(Calendar.DAY_OF_MONTH)
                &&  today.get(Calendar.MONTH) == specifiedDate.get(Calendar.MONTH)
                &&  today.get(Calendar.YEAR) == specifiedDate.get(Calendar.YEAR);
    }

11

简而言之

LocalDate
.parse( "2021-01-23" )
.isBefore(
    LocalDate.now(
        ZoneId.of( "Africa/Tunis" ) 
    )
)

…或者:

try 
{
    org.threeten.extra.LocalDateRange range =         
        LocalDateRange.of( 
            LocalDate.of( "2021-01-23" ) ,
            LocalDate.of( "2021-02-21" )
        )
    ;
    if( range.isAfter( 
        LocalDate.now( ZoneId.of( "Africa/Tunis" ) )
    ) { … }
    else { … handle today being within or after the range. }
} catch ( java.time.DateTimeException e ) {
    // Handle error where end is before start.
}

详情

其他答案忽略了时区这个关键问题。

其他答案使用过时的类。

避免使用旧的日期时间类

最早版本的Java捆绑的旧的日期时间类设计不佳、令人困惑且麻烦。请避免使用java.util.Date/.Calendar和相关类。

java.time

LocalDate

对于仅日期值,不带时间和时区,请使用LocalDate类。

LocalDate start = LocalDate.of( 2016 , 1 , 1 );
LocalDate stop = start.plusWeeks( 1 );

时区

请注意,虽然LocalDate不会存储时区信息,但是确定诸如“今天”之类的日期需要时区。对于任何给定的时刻,由于时区的不同,日期可能在世界各地有所不同。例如,在巴黎,新的一天比蒙特利尔早。在巴黎午夜后的一瞬间,在蒙特利尔仍然是“昨天”。

如果您只有一个UTC偏移量,请使用ZoneOffset。如果您有完整的时区(大陆/地区),请使用ZoneId。如果您想使用UTC,请使用便捷的常量ZoneOffset.UTC

ZoneId zoneId = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( zoneId );

使用isEqualisBeforeisAfter方法轻松进行比较。

boolean invalidInterval = stop.isBefore( start );

我们可以检查今天是否包含在这个日期范围内。在这里展示的逻辑中,我使用了“半开放”方法,其中开始是“包含的”,而结束是“不包含的”。这种方法在日期时间工作中很常见。因此,例如,一周从星期一开始,但不包括下一个星期一。
// Is today equal or after start (not before) AND today is before stop.
boolean intervalContainsToday = ( ! today.isBefore( start ) ) && today.isBefore( stop ) ) ;

LocalDateRange

如果需要广泛处理时间范围,请考虑将ThreeTen-Extra库添加到您的项目中。该库扩展了java.time框架,并是可能添加到java.time的内容的试验场。 ThreeTen-Extra包括一个LocalDateRange类,其中包含方便的方法,例如abutscontainsenclosesoverlaps等等。

关于java.time

java.time框架内置于Java 8及更高版本中。这些类替代了令人头疼的旧遗留日期时间类,例如java.util.Date, Calendar, 和SimpleDateFormat

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

如需了解更多信息,请参见 Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规范为 JSR 310

您可以直接与数据库交换 java.time 对象。使用符合 JDBC 4.2 或更高版本的 JDBC 驱动程序。无需字符串,也不需要 java.sql.* 类。

如何获取 java.time 类?


太冗长,答案埋在中间。最好将答案放在顶部,如果需要可以详细解释。 - Sun
@Sun 我在顶部添加了一个“tl;dr”部分。谢谢。 - Basil Bourque

9

2
完美而简单。谢谢! - rjr-apps

5

检查日期是否为今天的日期,只需检查日期,并且不包括时间,因此将时间设置为00:00:00,并使用以下代码:

    Calendar c = Calendar.getInstance();

    // set the calendar to start of today
    c.set(Calendar.HOUR_OF_DAY, 0);
    c.set(Calendar.MINUTE, 0);
    c.set(Calendar.SECOND, 0);
    c.set(Calendar.MILLISECOND, 0);

    Date today = c.getTime();

    // or as a timestamp in milliseconds
    long todayInMillis = c.getTimeInMillis();


    int dayOfMonth = 24;
    int month = 4;
    int year =2013;

    // reuse the calendar to set user specified date
    c.set(Calendar.YEAR, year);
    c.set(Calendar.MONTH, month - 1);
    c.set(Calendar.DAY_OF_MONTH, dayOfMonth);
    c.set(Calendar.HOUR_OF_DAY, 0);
    c.set(Calendar.MINUTE, 0);
    c.set(Calendar.SECOND, 0);
    c.set(Calendar.MILLISECOND, 0);
    // and get that as a Date
    Date dateSpecified = c.getTime();

    // test your condition
    if (dateSpecified.before(today)) {

        Log.v(" date is previou")
    } else if (dateSpecified.equal(today)) {

        Log.v(" date is today ")
    } 
             else if (dateSpecified.after(today)) {

        Log.v(" date is future date ")
    } 

希望这能有所帮助...


5
使用Joda Time,这可以简化为:
DateMidnight startDate = new DateMidnight(startYear, startMonth, startDay);
if (startDate.isBeforeNow())
{
    // startDate is before now
    // do something...
}

这个现在已经过时了! - User3
在月份参数上要非常小心 - Joda的范围是1-12,而Java的范围是0-11。如果月份是一月并从Java传递,则可能会抛出IllegalArgument异常。虽然它没有记录,但如果值无效,它将抛出org.joda.time.IllegalFieldValueException(IllegalArgumentException的子类)。 - Skynet
好的提示,但我认为Joda的范围才是正确的。对我来说,0-11从未有过意义。 - martin

2
    boolean isBeforeToday(Date d) {
        Date today = new Date();
        today.setHours(0);
        today.setMinutes(0);
        today.setSeconds(0);
        return d.before(today);
    }

1

我猜你是用整数来表示年、月和日的吧?如果你想保持一致,就使用日期方法。

Calendar cal = new Calendar();
int currentYear, currentMonth, currentDay; 
currentYear = cal.get(Calendar.YEAR); 
currentMonth = cal.get(Calendar.MONTH); 
currentDay = cal.get(Calendar.DAY_OF_WEEK);

     if(startYear < currentYear)
                {
                    message = message + "Start Date is Before Today" + "\n";
                }
            else if(startMonth < currentMonth && startYear <= currentYear)
                    {
                        message = message + "Start Date is Before Today" + "\n";
                    }
            else if(startDay < currentDay && startMonth <= currentMonth && startYear <= currentYear)
                        {
                            message = message + "Start Date is Before Today" + "\n";
                        }

1
另一种执行此操作的方法:

public class TimeUtils {

    /**
     * @param timestamp
     * @return
     */
    public static boolean isToday(long timestamp) {
        Calendar now = Calendar.getInstance();
        Calendar timeToCheck = Calendar.getInstance();
        timeToCheck.setTimeInMillis(timestamp);
        return (now.get(Calendar.YEAR) == timeToCheck.get(Calendar.YEAR)
                && now.get(Calendar.DAY_OF_YEAR) == timeToCheck.get(Calendar.DAY_OF_YEAR));
    }

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接