【问题标题】:What is the proper way to remove the time part from java.util.Date? [duplicate]从 java.util.Date 中删除时间部分的正确方法是什么? [复制]
【发布时间】:2011-12-08 07:37:57
【问题描述】:

我想实现一个线程安全的函数来从 java.util.Date 中删除时间部分。

我试过这种方式

private static final DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
public static Date removeTimeFromDate(Date date) {
        Date returnDate = date;

        if (date == null) {
            return returnDate;
        }

        //just have the date remove the time
        String targetDateStr = df.format(date);
        try {
            returnDate = df.parse(targetDateStr);
        } catch (ParseException e) {
        }

        return returnDate;
}

并使用 synchronized 或 threadLocal 使其成为线程安全的。 但它有更好的方法来用 Java 实现它。这种方式似乎有点冗长。 我对此并不满意。

【问题讨论】:

  • 顺便说一句,但为 thread-safety reasons 保留对 DateFormat 的静态引用通常是不明智的。
  • 你是对的。在知道它需要是线程安全的之后,我改变了它。

标签: java date


【解决方案1】:

Date 对象包含一个变量,该变量将时间表示为自 epoch 以来的毫秒数。所以,你不能“删除”时间部分。您可以做的是将当天的时间设置为零,这意味着它将是当天的 00:00:00 000。这是通过使用 GregorianCalendar 完成的:

GregorianCalendar gc = new GregorianCalendar();
gc.setTime(date);
gc.set(Calendar.HOUR_OF_DAY, 0);
gc.set(Calendar.MINUTE, 0);
gc.set(Calendar.SECOND, 0);
gc.set(Calendar.MILLISECOND, 0);
Date returnDate = gc.getTime();

【讨论】:

  • 可能这只是我,但我更喜欢日历而不是 GregorianCalendar。
  • 请注意,时区很重要,并且该时区可能不存在午夜......请参阅我的答案。
  • @JonSkeet:我对使用 TimeZones 不是很熟悉。将时区指定为构造函数参数是否足够?
  • @MartijnCourteaux:是的,那很好 - 但 OP 需要决定他们感兴趣的哪个时区。此外,您最终可能会得到一个无效的本地时间设置为午夜。
【解决方案2】:

Date 在时间上保持 即时 - 这意味着它不会明确指定特定日期。所以你需要指定一个时区以及,以便计算出某件事的日期。然后,您需要确定如何表示结果 - 例如,Date 的值为“UTC 日期的午夜”?

您还应该注意,由于 DST 转换可能发生在午夜,因此并非所有时区的所有日子都出现午夜。 (巴西就是一个常见的例子。)

除非你真的DateCalendar 结婚,否则我建议你开始改用Joda Time,因为这样你就可以拥有@987654326 类型的值@ 可以解决大部分问题。

【讨论】:

  • 它已经在使用日期。所以我无法更改为 Joda Time。而且我想在我的使用中,它不需要那么准确。只要日期部分在其本地时间正确计算。那没关系。
  • @ClarkBao: 但这就是重点——你需要指定你的意思是哪个时区......如果你尝试将日历设置为无效值,当你调用getTime时它很可能会失败.如果您正在做大量约会工作,您绝对应该考虑将所有内容都更改为 Joda Time - 这是一个更好的 API。
  • 输入日期通常是 new Date()。会不会有问题?我发现结果与上面的日历方式的日期格式方式相同。
  • 最终日期 targetDate = new Date(); System.out.println(targetDate);最终的 GregorianCalendar cal = 新的 GregorianCalendar(); cal.setTime(targetDate); System.out.println(cal.getTime());我发现这两个是一样的。
  • @ClarkBao:这只是以当前时间为准。但是您需要确定要考虑将哪个时区转换为日期。
猜你喜欢
  • 2013-10-16
  • 2010-10-04
  • 1970-01-01
  • 1970-01-01
  • 2014-03-26
  • 1970-01-01
  • 1970-01-01
  • 2012-11-11
  • 1970-01-01
相关资源
最近更新 更多