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

获得Date对象而不包含时间的最有效方法是什么?除了这两种,还有别的办法吗?

// 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();

更新:

我知道Joda-Time;我只是试图避免额外的库为这样一个简单的(我认为)任务。但根据目前的回答,Joda-Time似乎非常受欢迎,所以我可能会考虑一下。 通过高效,我的意思是我想避免像方法1所使用的那样创建临时对象字符串,同时方法2似乎是一种hack而不是解决方案。


当前回答

// 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

其他回答

这是一个干净的解决方案,没有转换到字符串和返回,而且它不会重新计算时间几次,因为你重置时间的每个组件为零。它还使用%(模量)而不是除后乘,以避免重复操作。

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

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;
}

这是一种简单的方法:

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

充分利用Java巨大的时区数据库的最直接的方法是正确的:

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

博士tl;

除了这两种,还有别的办法吗?

是的,有:LocalDate.now

LocalDate.now( 
    ZoneId.of( "Pacific/Auckland" ) 
)

java.time

Java 8和更高版本的新Java。时间包内置。看教程。大部分的java。时间功能在ThreeTen-Backport中向后移植到Java 6和7,并在ThreeTenABP中进一步适应Android。

类似于Joda-Time, java。time提供了一个LocalDate类来表示一个只包含日期的值,不包含日期和时区。

请注意,时区对于确定特定的日期非常重要。例如,在巴黎午夜钟声敲响时,Montréal上的日期仍然是“昨天”。

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

默认为java。time使用ISO 8601标准生成日期或日期-时间值的字符串表示形式。(与Joda-Time的另一个相似之处。)因此,只需调用toString()来生成类似2015-05-21的文本。

String output = today.toString() ; 

关于java.time

java。时间框架内置于Java 8及更高版本中。这些类取代了麻烦的旧遗留日期-时间类,如java.util。日期,日历和简单日期格式。

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

要了解更多,请参阅Oracle教程。搜索Stack Overflow可以找到很多例子和解释。规范是JSR 310。

从哪里获取java。时间类?

Java SE 8、Java SE 9以及更高版本 内置的。 带有捆绑实现的标准Java API的一部分。 Java 9增加了一些小特性并进行了修复。 Java SE 6和Java SE 7 大部分的java。时间功能在ThreeTen-Backport中向后移植到Java 6和7。 安卓 后续版本的Android捆绑实现的java。时间类。 对于早期的Android, ThreeTenABP项目适应了ThreeTen-Backport(如上所述)。参见如何使用ThreeTenABP....

ThreeTen-Extra项目扩展了java。额外的课程时间。这个项目是未来可能添加到java.time的一个试验场。你可以在这里找到一些有用的类,比如Interval、YearWeek、YearQuarter等等。

// 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