计算给定日期的日期

时间:2009-05-31 00:06:26

标签: java date

从给定的日期起,我需要计算当天的午夜。这就是我想出来的。它太丑了,我觉得必须有更好的方法。

private Date day(Date creation) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(creation);
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);
    return calendar.getTime();
}

建议?

肯特

8 个答案:

答案 0 :(得分:7)

您应该考虑内置日期API obselete。而是使用Joda日期和时间API。

这是您的方法的替代品。

private Date day(Date creation) {
    return new DateMidnight(creation).toDate();
}

这是一个简单的测试:

public static void main(String[] args) {
    final Date creation = new Date();
    final Date midnight = new Foobar().day(creation);
    System.out.println("creation = " + creation);
    System.out.println("midnight = " + midnight);
}

输出结果为:

creation = Sun May 31 10:09:38 CEST 2009    
midnight = Sun May 31 00:00:00 CEST 2009

答案 1 :(得分:5)

JODA可能有一个更好的解决方案,代价是对库的另一个依赖。我正在看它的DateMidnight property。对不起,我不能权威地回答,但我自己也不是JODA用户。

答案 2 :(得分:2)

如果您正在寻找当地时间,那将是您最好的。虽然你可能认为它很难看,但是(可能)在幕后会发生很多事情。

如果您想要午夜UTC,以下内容将起作用:

public static void main(String[] argv)
throws Exception
{
    final long MILLIS_PER_DAY = 24 * 3600 * 1000L;

    long midnightUTC = (System.currentTimeMillis() / MILLIS_PER_DAY) * MILLIS_PER_DAY;
}

修改:我真的不建议在“生产”代码中使用本地日期。他们造成的麻烦超出了他们的价值 - 考虑到美国西海岸的一个人突然发现他/她的“日子”缩短了3个小时,因为东海岸的电脑有一个不同的午夜想法。

答案 3 :(得分:1)

如果您有严格的日历需求,那么

JODA是最佳选择,至少在JSR-310进入JDK之前(1.7可能,如果不是1.8)。

话虽如此,有一些事情可以使这段代码变得更好。

import static java.util.Calendar.*;

...

private static final List<Integer> TIME_FIELDS = 
    Arrays.asList(HOUR_OF_DAY, MINUTE, SECOND, MILLISECOND);

private Date day(Date creation) {
     Calendar c = getInstance();
     c.setTime(creation);
     for(int field : TIME_FIELDS) c.set(field, 0);
     return c.getTime();
}

这不会赢得任何表现奖。您可以依赖于特定字段值来执行循环标准(Calendar类具有FIELD_COUNT字段,这意味着您可以执行类似的操作),但这可能会导致JDK实现和版本之间出现问题。

答案 4 :(得分:1)

使用date4j库:

DateTime start = dt.getStartOfDay();

答案 5 :(得分:0)

我认为,使代码显着改善的唯一方法是改变表示形式。例如,

  • 由Nachum Dershowitz和Ed Reingold在Calendrical Calculations解释的“绝对日期”系统代表日。

  • 通过从午夜计算秒数来表示时间。或者,如果您需要亚秒级分辨率,请计算毫秒数。

从您的简短示例中,我无法确定您的程序中的哪些点需要与现有的DateCalendar类兼容,或者您​​是否可以使用更合理的表示创建有用的子类

答案 6 :(得分:0)

暂时没有编写Java,但您可以调用此set method来传递当前值,包括年,月和日。虽然从阅读有点接近,你可能不得不首先打电话给清楚。这可能比使用您当前的方法更简洁。

答案 7 :(得分:0)

这只是最初发布的代码的补充。它在新的GregorianCalendar对象中设置年,月和日,而不是清除日历变量中除年,月和日之外的所有内容。这并没有太大的改进,但我认为更清楚地说明你要复制哪些字段,而不是你忽略哪些字段。

public Date day(Date creation) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(creation);
    return new GregorianCalendar(
            calendar.get(Calendar.YEAR),
            calendar.get(Calendar.MONTH),
            calendar.get(Calendar.DAY_OF_MONTH)).getTime();
}

就个人而言,我认为我会选择其他人提出的Joda图书馆。