从日期对象中删除时间?

85

我想从Date对象中删除时间。

DateFormat df;
String date;
df = new SimpleDateFormat("dd/MM/yyyy");
d = eventList.get(0).getStartDate(); // I'm getting the date using this method
date = df.format(d); // Converting date in "dd/MM/yyyy" format

但是当我转换这个日期(它是以String格式表示的)时,它会附加时间。

我根本不想要时间。我想要的只是"21/03/2012"。


最后一行代码后面的 System.out.println(date) 是什么意思呢?它肯定已经是所需的格式了,对吧?否则你并没有发布完整的代码。例如,你可能会在稍后将其转换回 Date 对象,这将获取默认时间。 - BalusC
你从“日期”中难道不只是得到了21/03/2012吗? - Vaandu
@BalusC 是的...这是期望的格式...但是当将字符串转换回日期时,它会附加默认时间...这不是我想要的... - Laxman Rana
为什么你要再转换回Date呢?这有什么意义吗?Date对象表示以毫秒为单位的时期时间戳,当然也包括时间。如果你的唯一目的是向人类展示它,只需按所需格式转换为String,就像你已经做过的那样。你只需要在你要向人类展示它的那一刻进行转换。阅读javadoc:http://docs.oracle.com/javase/7/docs/api/java/util/Date.html(特别是`toString()`方法)。 - BalusC
请参考此链接:https://stackoverflow.com/a/12244292/131157 - Babak
显示剩余2条评论
20个回答

136

要从java.util.Date中去除时间部分,可以将其小时、分钟、秒和毫秒值设置为零。

import java.util.Calendar;
import java.util.Date;

public class DateUtil {

    public static Date removeTime(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

}

8
这并不是删除时间部分,而只是将其设置为零。 - Ganesh Krishnan
4
我也想要这个确切的解决方案。谢谢你的回答。 - Buddhika Ariyaratne
6
但如果你想要按照日期进行比较,这需要将每个时间设为相同的值。 - WendyG
2
无论时区如何,它都能正常工作吗?如果我们在一个时区存储日期,当您在另一个时区应用此方法时,您可能会得到另一个日期(d + 1或d-1)...我只想使用日历日期,例如“aaaa-mm-dd”,没有时间。我开始认为“String”是Java中表示日历日期的最先进的类。 - boumbh
java.util.Date是独立于时区的。如果您想使用特定于时区的日期/时间,请使用java.util.Calendar。 - Sunil Manheri
不可靠,使用它结果不一致。已转移到Apache通信中。 - Rajat

56

简而言之,不允许这样做,因为这是Date的作用。

来自Date的javadoc:

日期类表示一个具体的时间瞬间,精确到毫秒。

然而,由于这个类只是一个数据对象,它并不关心我们如何描述时间。 当我们看到日期2012/01/01 12:05:10.321时,我们可以说它是2012/01/01,这就是你需要的。 有很多方法可以做到这一点。

示例1:通过操作字符串

输入字符串 :2012/01/20 12:05:10.321

期望的输出字符串 :2012/01/20

由于格式为yyyy/MM/dd正是我们所需的,我们可以简单地操作字符串以获得结果。

String input = "2012/01/20 12:05:10.321";
String output = input.substring(0, 10);  // Output : 2012/01/20

例2:使用SimpleDateFormat

输入字符串:2012/01/20 12:05:10.321

期望输出字符串:01/20/2012

在这种情况下,我们需要一个不同的格式。

String input = "2012/01/20 12:05:10.321";
DateFormat inputFormatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS");
Date date = inputFormatter.parse(input);

DateFormat outputFormatter = new SimpleDateFormat("MM/dd/yyyy");
String output = outputFormatter.format(date); // Output : 01/20/2012

如果要使用SimpleDateFormat,请查看SimpleDateFormat JavaDoc


1
就像我说的,你不被允许这样做,Date 并不是为了那个目的。你需要改变描述 Date 的方式,而不是改变 Date 对象本身。 - Rangi Lin
我可以阅读 java.text.DateFormat 还是 android.text.format.DateFormat 吗? - hornetbzz
@hornetbzz:我不熟悉Android JDK,但我相信Android有自己的日期格式化方式。 - Rangi Lin
2
这样的答案应该被取消采纳。 - taylorcressy
@taylorcressy 你是怎么想的? - jbowman
显示剩余2条评论

44

Apache Commons DateUtils"truncate" 方法可以满足您的需求,我刚使用了它。这个方法非常容易使用:

DateUtils.truncate(dateYouWantToTruncate, Calendar.DAY_OF_MONTH);

DateUtils还有许多其他很酷的实用工具,比如"isSameDay()"等等。来看看吧!这可能会让你的事情更容易。


7
应该是 DateUtils.truncate(dateYouWantToTruncate, Calendar.Date); ? - borjab
3
在Java文档中,Calendar.DATE和Calendar.DAY_OF_MONTH被标记为同义词。 - Daniel Gradinjan

13

这个怎么样:

    Date today = new Date();
    SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");

    today = sdf.parse(sdf.format(today));

将日期转换为字符串,然后再解析回来并不是一个好的解决方案,因为已经有一个类可用(日历)可以直接更改所需的日期组件。 - rghome

9
你想要的是不可能实现的。
一个Date对象代表着一个“绝对”的时间点。你不能从中“移除时间部分”。当你使用System.out.println(date)直接打印Date对象时,它总是会按照默认格式进行格式化,其中包括时间。你无法做任何改变。
与其试图以某种方式使用Date类来进行设计之外的工作,你应该寻找另一种解决方案。例如,使用SimpleDateFormat将日期格式化为任何你想要的格式。
Java日期和日历API不幸地并非标准Java API中最良好设计的类。有一个称为Joda-Time的库,它具有更好、更强大的API。
Joda-Time有许多特殊类来支持日期、时间、周期、持续时间等。如果你想要仅使用日期而没有时间,那么Joda-Time的LocalDate类就是你要使用的类。 < p > < em >编辑 -请注意,我上面的答案已经超过10年了。如果您正在使用当前版本的Java(Java 8或更高版本),则建议使用包java.time 中的新标准日期和时间类。有许多可用的类表示仅日期(日,月,年);日期和时间;只是时间等。

另外,https://stackoverflow.com/a/12244292/131157 - Babak

5
Date dateWithoutTime =
    new Date(myDate.getYear(),myDate.getMonth(),myDate.getDate()) 

这是一种已经被弃用的方法,但它是最快的方式。


5
也许下面的代码可以帮助那些正在寻找一天中零点的人:
    Date todayDate = new Date();
    GregorianCalendar todayDate_G = new GregorianCalendar();
    gcd.setTime(currentDate);
    int _Day    = todayDate_GC.get(GregorianCalendar.DAY_OF_MONTH);
    int _Month  = todayDate_GC.get(GregorianCalendar.MONTH);
    int _Year   = todayDate_GC.get(GregorianCalendar.YEAR);

    GregorianCalendar newDate = new GregorianCalendar(_Year,_Month,_Day,0,0,0);
    zeroHourDate = newDate.getTime();
    long zeroHourDateTime = newDate.getTimeInMillis();

希望这对您有所帮助。


我能理解你的意思,这个想法还不错,但代码不清晰且包含许多错误。 todayDate 没有被使用,todayDate_G 也没有(可能拼写错误),而 todayDate_GC 没有定义(可能也是拼写错误)。此外 gcd 没有定义。 - DAB

4
你可以尝试这样做:
import java.text.*;
import java.util.*;
public class DtTime {
public static void main(String args[]) {
String s;
Format formatter;
  Date date = new Date();
  formatter = new SimpleDateFormat("dd/MM/yyyy");
  s = formatter.format(date);
  System.out.println(s);
    }
}

这将会输出21/03/2012

或者你也可以尝试这个,如果你想要输出21 Mar, 2012

import java.text.*;
import java.util.*;
public class DtTime {
public static void main(String args[]) {
    Date date=new Date();
String df=DateFormat.getDateInstance().format(date);
System.out.println(df);
    }
}

3
你可以写成这样的例子:
private Date TruncarFecha(Date fechaParametro) throws ParseException {
    String fecha="";
    DateFormat outputFormatter = new SimpleDateFormat("MM/dd/yyyy");
    fecha =outputFormatter.format(fechaParametro);
    return outputFormatter.parse(fecha);
}

欢迎来到 Stack Overflow!这个问题已经三年了,而且已经有一个被接受的答案。你应该回答更加当前的问题。 - ByteHamster

2

如果只需要日期而不需要时间,正确的类是LocalDateLocalDate是Java 8引入的新日期API——java.time的一部分。

因此,最好的做法是修改你正在使用的getStartDate方法,使其返回一个LocalDate

    DateTimeFormatter dateFormatter = DateTimeFormatter
            .ofLocalizedDate(FormatStyle.SHORT)
            .withLocale(Locale.forLanguageTag("en-IE"));

    LocalDate d = eventList.get(0).getStartDate(); // We’re now getting a LocalDate using this method
    String dateString = d.format(dateFormatter);
    System.out.println(dateString);

示例输出:

2012年3月21日

如果您无法更改getStartDate,您仍然可以添加一个返回我们想要的类型的新方法。但是,如果您现在无法承担这样做的成本,请将您获取的旧式Date(我假设是java.util.Date)转换为:

    d = eventList.get(0).getStartDate(); // I'm getting the old-fashioned Date using this method
    LocalDate dateWithoutTime = d.toInstant()
            .atZone(ZoneId.of("Asia/Kolkata"))
            .toLocalDate();

请插入为 Date 假定的时区。您可以使用 ZoneId.systemDefault() 来设置JVM的时区设置,但是只有此设置可以从程序的其他部分或在同一JVM中运行的其他程序随时更改。
当这个问题被问出来6年前,我们所有人都在使用 java.util.Date 类(不是所有人;我使用了,并且我们很多人都在使用)。几年后,java.time 出现了并替换了旧的 DateCalendarSimpleDateFormatDateFormat,因为它们设计得很差。此外,尽管名称包含“date”一词,但 Date 不能代表日期,而是一个时间点。其他答案所做的是将时间向下舍入到JVM默认时区的开始时间(“午夜”)。这并没有移除一天中的时间,只设置了它,通常为00:00。更改默认时区 - 如我所说,即使是在同一JVM中运行的另一个程序也可能随时进行更改而无需通知 - 所有事情都会崩溃(经常发生)。 链接: Oracle教程:日期和时间,解释如何使用 java.time

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