如何从日期中删除毫秒、秒、分钟和小时

7
我遇到了一个问题,我想比较两个日期。然而,我只想比较年份、月份和日期。这是我想出来的解决方案:
 private Date trim(Date date) {

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.MILLISECOND, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.HOUR, 0);
        return calendar.getTime();
    }

我使用这个函数来剪切所有单位,但保留天、月和年。 现在问题是你对此有什么看法? 你知道其他的做法吗?
谢谢。

2
我真的不明白问题出在哪里? - Hussain Akhtar Wahid 'Ghouri'
看起来是干净的代码,任何访问日期类的其他代码很可能会更大,为什么你要改呢,哈哈。 - SSpoke
1
您正在为哪位用户生成输出,其时区与平台上运行的JVM时区相同吗? :) - Affe
我标记为重复的问题中未被接受的答案涉及到其他库和类,你可以使用它们更清晰地处理Date,除了被接受的答案基本上与你的代码相同。 - Robert Rouhani
感谢所有的评论。代码没有问题。但是,我觉得可能有一些更简洁或更好的方法来做到这一点 :) - Adelin
显示剩余3条评论
5个回答

8

你真的需要使用 java.util.Date 吗?如果你可以切换到 joda time,你会发现它有很多很好的特性,比如:

dateTime.dayOfMonth().roundFloorCopy()

它可以完全满足您的需求。


这正是我在寻找的答案,不过我的项目很小,我不需要添加更多的依赖项 :) - Adelin
Joda现在已经比较主流,所以你不用担心使用某些晦涩的库……无论项目多么小,如果想要进行任何记录,都应该使用slf4j;如果你正在编写测试--testng,如果你关注日期/时间,你需要Joda(或者它们的替代品,当然 -- 我们不想在这里开始一场宗教战争)。 - Costi Ciudatu
您说得对,也许将来我会添加Joda。 - Adelin

6
您的代码能够正常运行且易于阅读。我没有发现任何问题或更改的必要。

谢谢您的回复。但是,我正在寻找像“Stephen C”答案这样的解决方案。 - Adelin

4
现在的问题是你对这样做有什么想法?
看起来很简单和合理。你正在创建一个新的Date和临时的Calendar对象,但这只是一个小开销。(...除非你正在使用它来排序/排序大型数据结构...)
在我看来,可能没有必要改变它。
你知道其他的方法吗?
  1. Develop / use a Comparator<Date> that only uses the fields you are interested in, using a Calendar to extract them.

    Whether this will help depends on how you are currently doing the comparisons. A comparator may be neater. But the flip-side is that you may end up repeatedly doing the conversions, and Comparator<Date> doesn't give you any scope for caching the converted dates.

  2. Do the calculation using the values returned by Date.getTime(). Roughly like this:

    long val = date.getTime(); // milliseconds since 'epoch' in UTC 
    val = val + /* local timezone offset in milliseconds */  
    long day = val / (1000 * 60 * 60 * 24); // days since "local" epoch.
    
    // repeat for other Date, and compare the 'day' numbers as integers
    

    Explanation, it should be more efficient to do some simple arithmetic than use a Calendar (or whatever). The code is a bit more obscure, but it should be obvious to someone with reasonable maths skills.


第二个建议没有考虑夏令时或闰秒的任何更改。它只会告诉您两个日期是否相隔不到24小时,而这可以通过计算24小时内的毫秒数来更简单地实现。除非这正是您想要的,否则只需使用您现有的代码,读者对其意图更为明显。 - SimonC
@SimonC - 相关的“代码”实际上是一条注释。它是否考虑夏令时(或不考虑)取决于您如何实现它。(但是是的,这确实使事情变得复杂。)我相当确定闰秒是无关紧要的。它们通过调整UTC基准时间来工作... - Stephen C
@StephenC,你提供的公式并不是自纪元以来的日历天数,而是24小时周期的数量。你需要知道自纪元以来本地日历中添加/删除的夏令时小时数。据我所知,闰秒被插入到当前日期中,因此有些日历日期有24 * 60 * 60 + 1秒。这将进一步扭曲你的计算结果。除非有一个非常好的理由,否则时间计算应该总是通过已经被许多人测试过的库来完成。 - SimonC
@SimonC - 我不明白你在计算方面的观点。由于夏令时添加和删除的小时数将平衡 ... 取模一个可以从当前DST状态和数量计算出的数字。关于闰秒,您是错误的。正如我所说,它们通过调整UTC基准时间来处理。由于闰秒的存在,时间服务器报告的实际时间会发生变化,所有同步的时钟也会发生变化。这在正常的日历目的下被忽略。 - Stephen C
看,我不是说考虑DST很简单。但我要说的是,你可以高效地做到它,如果你能高效地做到它,那么这就是根据OP要求比较日期的最有效方式。 - Stephen C

2

我猜您想比较两个日期,其中您只想比较

您所做的是正确的,即删除小时分钟毫秒。 您需要对两个日期都这样做。

修剪完成后,您将需要在Date类中使用compareTo方法。

您可以使用以下代码 -

if(date1.compareTo(date2) < 0) {
  // date1 is earlier
} else if(date1.compareTo(date2) > 0) {
  // date 2 is earlier
} else {
  // both dates are equal
}      

1
我认为我真的不需要那个。date1.before(date2) 似乎更好。 - Adelin
1
是的。我希望我能对你有所帮助。 - JHS

0

你可以试试这个,因为日期的格式是固定的:

    String first = date1.toString().substring(4,10) + " " + date.toString().substring(24, 28);
    String second = date2.toString().substring(4,10) + " " + date.toString().substring(24, 28);

这将输出

1969年12月31日

1969年1月6日

然后比较结果。

return (first.equals(second));

我不知道它是否比你的想法更好,但你可以得到相同的结果。


1
只有在想要比较日期是否相等时才能使用此方法。而且这种方法非常低效...并且不可移植,因为它依赖于默认的字符串格式化,这是与语言环境相关的。 - Stephen C
谢谢您的回答,但是我将无法使用 if(date1.before(date2)) ... :)。 - Adelin

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