如何在Java中获得没有时间的日期?

How do I get a Date without time in Java?

从堆栈溢出问题继续Java程序获得当前日期没有时间戳:

在没有时间的情况下获取日期对象最有效的方法是什么?除了这两个还有别的办法吗?

1
2
3
4
5
6
7
8
9
10
11
// Method 1
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date dateWithoutTime = sdf.parse(sdf.format(new Date()));

// Method 2
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
dateWithoutTime = cal.getTime();

更新:

  • 我知道乔达的时间,我只是想避免为这样一个简单的(我认为)任务增加图书馆。但根据目前的答案,佐达时间似乎非常流行,所以我可能会考虑。

  • 我的意思是,我想避免使用method 1所使用的临时对象String创建,同时method 2看起来像是一个黑客,而不是一个解决方案。


  • 你一定要用java.util.Date吗?我将彻底建议您使用JoDA时间或Java 8中的EDCOX1×1封装。特别是,虽然日期和日历总是代表一个特定的时间瞬间,但没有"只是一个日期"的概念,但Joda Time确实有一个表示这一点的类型(LocalDate)。如果您能够使用表示您实际尝试执行的操作的类型,那么您的代码将更加清晰。

    使用joda time或java.time而不是内置的java.util类型还有许多其他原因,它们通常是更好的API。如果需要,您可以在自己的代码边界处(例如,用于数据库交互)转换为/从java.util.Date转换。


    下面是我过去得到的日期,时间设置为00:00:00

    1
    2
    3
    4
    5
    DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");

    Date today = new Date();

    Date todayWithZeroTime = formatter.parse(formatter.format(today));


    您可以使用ApacheCommons库中的dateutils.truncate。

    例子:

    1
    DateUtils.truncate(new Date(), java.util.Calendar.DAY_OF_MONTH)


    Is there any other way than these two?

    是的,有。

    1
    2
    3
    LocalDate.now(
        ZoneId.of("Pacific/Auckland" )
    )

    Java.时间

    Java 8和以后带有内置的新JavaTimePACK。见教程。Java.TimeActudio的许多功能在3TeNeN后端移植到Java 6和7,并进一步适应了Android的三层版本。

    与joda time类似,java.time提供了一个LocalDate类来表示一个只包含日期的值,不包含时间和时区。

    请注意,时区对于确定特定日期至关重要。例如,在巴黎午夜时分,在蒙特利尔,日期仍然是"昨天"。

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

    默认情况下,java.time使用ISO 8601标准生成日期或日期时间值的字符串表示。(与Joda时间的另一个相似之处)所以只需调用toString()生成类似2015-05-21的文本。

    1
    String output = today.toString() ;

    关于JavaTimes

    JavaTimeFr框架是在Java 8和之后构建的。这些类取代了麻烦的旧遗留日期时间类,如java.util.DateCalendarSimpleDateFormat

    现在处于维护模式的joda time项目建议迁移到java.time类。

    要了解更多信息,请参阅Oracle教程。以及搜索堆栈溢出以获得许多示例和解释。规格为JSR 310。

    在哪里获取java.time类?

    • Java SE 8、Java SE 9及以后
      • 内置的。
      • 标准JAVA API的一部分与捆绑实现。
      • Java 9添加了一些小的特性和修复。
    • Java SE 6和Java SE 7
      • 大部分JavaTimeActudio都被移植到TealEnter后端的Java 6和7中。
    • 安卓
      • java.time类的Android包实现的更高版本。
      • 对于早期的android,threetenabp项目适应threeten backport(如上所述)。看看如何使用三连珠……

    threeten额外项目使用额外的类扩展java.time。这个项目是将来可能添加到java.time的一个试验场。您可以在这里找到一些有用的类,如IntervalYearWeekYearQuarter等等。


    最直接的方法是:

    1
    2
    3
    4
    long millisInDay = 60 * 60 * 24 * 1000;
    long currentTime = new Date().getTime();
    long dateOnly = (currentTime / millisInDay) * millisInDay;
    Date clearDate = new Date(dateOnly);


    这些问题的标准答案是使用Joda时间。API更好,如果您使用的是格式化程序和解析器,则可以避免SimpleDateFormat的非直观的线程安全性不足。

    使用Joda意味着你可以简单地做到:

    1
    LocalDate d = new LocalDate();

    更新::使用Java 8,可以使用

    1
    LocalDate date = LocalDate.now();


    在标准Java运行时的日期例程中,没有时间戳的日期是没有意义的,因为它基本上映射到特定的毫秒而不是日期。说毫秒本质上是一天中的一个时间,这使得它容易受到时区问题,如夏令时和其他日历调整。明白为什么要减去这两次(1927年)会得到一个奇怪的结果吗?举个有趣的例子。

    如果要使用日期而不是毫秒,则需要使用其他内容。对于Java 8,有一套新的方法可以提供您所要求的。对于Java 7和更早使用HTTP://www. Jorda.Org/JoDa-Time/


    好吧,据我所知,如果您只使用标准JDK,那么实现这一点就不容易了。

    当然,您可以将method2中的逻辑放入helper类中的静态函数中,就像这里在tobeginingoftheday方法中所做的那样。

    然后您可以将第二种方法缩短为:

    1
    2
    3
    Calendar cal = Calendar.getInstance();
    Calendars.toBeginningOfTheDay(cal);
    dateWithoutTime = cal.getTime();

    或者,如果您如此频繁地需要这种格式的当前日期,那么您可以用另一个静态助手方法将其包装起来,从而使其成为一行程序。


    这是一种简单的方法:

    1
    2
    3
    Calendar cal = Calendar.getInstance();
    SimpleDateFormat dateOnly = new SimpleDateFormat("MM/dd/yyyy");
    System.out.println(dateOnly.format(cal.getTime()));


    如果你只想看到这样的日期"YYYY-MM-DD",而不想看到其他杂乱无章的日期,例如"2015年5月21日星期四12:08:18",那么只需使用java.sql.Date。此示例获取当前日期:

    1
    new java.sql.Date(System.currentTimeMillis());

    另外,java.sql.Datejava.util.Date的一个子类。


    当然不是最正确的方法,但是如果你只是需要一个快速的解决方案来获得没有时间的日期,而且你不想使用第三方库,那么应该这样做。

    1
        Date db = db.substring(0, 10) + db.substring(23,28);

    我只需要这个日期作为视觉上的目的,不能Joda,所以我改了。


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // 09/28/2015
    System.out.println(new SimpleDateFormat("MM/dd/yyyy").format(Calendar.getInstance().getTime()));

    // Mon Sep 28
    System.out.println( new Date().toString().substring(0, 10) );

    // 2015-09-28
    System.out.println(new java.sql.Date(System.currentTimeMillis()));

    // 2015-09-28
    // java 8
    System.out.println( LocalDate.now(ZoneId.of("Europe/Paris")) ); // rest zones id in ZoneId class

    如果你需要日期部分只是为了回响,那么

    1
    2
    Date d = new Date();
    String dateWithoutTime = d.toString().substring(0, 10);


    如果您只需要当前日期,而不需要时间,另一个选项是:

    1
    DateTime.now().withTimeAtStartOfDay()


    使用LocalDate.now()转换成Date如下:

    1
    Date.from(LocalDate.now().atStartOfDay(ZoneId.systemDefault()).toInstant());


    最充分利用Java的庞大时区数据库的最先进的方法是正确的:

    1
    2
    long currentTime = new Date().getTime();
    long dateOnly = currentTime + TimeZone.getDefault().getOffset(currentTime);

    检查检验时间。它是java.util和joda time的简单而有效的替代方案。它有一个直观的API和类,它们单独表示日期,而没有时间戳。


    这里有一个干净的解决方案,它不需要转换成字符串和字符串,而且当您将时间的每个组件重置为零时,它也不会多次重新计算时间。它还使用EDOCX1(模数)而不是除后乘,以避免双重操作。

    它不需要第三方依赖,并且尊重传入的日历对象的时区。此函数返回您传入日期(日历)的时区中上午12点的时间点。

    1
    2
    3
    4
    5
    6
    7
    8
    public static Calendar date_only(Calendar datetime) {
        final long LENGTH_OF_DAY = 24*60*60*1000;
        long millis = datetime.getTimeInMillis();
        long offset = datetime.getTimeZone().getOffset(millis);
        millis = millis - ((millis + offset) % LENGTH_OF_DAY);
        datetime.setTimeInMillis(millis);
        return datetime;
    }


    我刚为我的应用程序做了这个:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public static Date getDatePart(Date dateTime) {
        TimeZone tz = TimeZone.getDefault();
        long rawOffset=tz.getRawOffset();
        long dst=(tz.inDaylightTime(dateTime)?tz.getDSTSavings():0);
        long dt=dateTime.getTime()+rawOffset+dst; // add offseet and dst to dateTime
        long modDt=dt % (60*60*24*1000) ;

        return new Date( dt
                        - modDt // substract the rest of the division by a day in milliseconds
                        - rawOffset // substract the time offset (Paris = GMT +1h for example)
                        - dst // If dayLight, substract hours (Paris = +1h in dayLight)
        );
    }

    Android API 1级,无外部库。它尊重日光和默认时区。没有字符串操作,所以我认为这种方式比您的CPU效率高,但我没有做任何测试。


    尽量不要使用第三方库。我知道前面提到过这种方法,但这里有一种干净的方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
      /*
        Return values:
        -1:    Date1 < Date2
         0:    Date1 == Date2
         1:    Date1 > Date2

        -2:    Error
    */

    public int compareDates(Date date1, Date date2)
    {
        SimpleDateFormat sdf = new SimpleDateFormat("ddMMyyyy");

        try
        {
            date1 = sdf.parse(sdf.format(date1));
            date2 = sdf.parse(sdf.format(date2));
        }
        catch (ParseException e) {
            e.printStackTrace();
            return -2;
        }

        Calendar cal1 = new GregorianCalendar();
        Calendar cal2 = new GregorianCalendar();

        cal1.setTime(date1);
        cal2.setTime(date2);

        if(cal1.equals(cal2))
        {
            return 0;
        }
        else if(cal1.after(cal2))
        {
            return 1;
        }
        else if(cal1.before(cal2))
        {
            return -1;
        }

        return -2;
    }

    好吧,不使用公历可能是一种选择!


    你可以利用Joda时间。

    1
    2
    3
    private Date dateWitoutTime(Date date){
     return new LocalDate(date).toDate()
    }

    你打电话给:

    1
    2
    Date date = new Date();
    System.out.println("Without Time =" + dateWitoutTime(date) +"/n  With time =" + date);

    这个怎么样?

    1
    2
    3
    4
    5
    6
    public static Date formatStrictDate(int year, int month, int dayOfMonth) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(year, month, dayOfMonth, 0, 0, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }