从给定的日期起,我需要计算当天的午夜。这就是我想出来的。它太丑了,我觉得必须有更好的方法。
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();
}
建议?
肯特
答案 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解释的“绝对日期”系统代表日。
通过从午夜计算秒数来表示时间。或者,如果您需要亚秒级分辨率,请计算毫秒数。
从您的简短示例中,我无法确定您的程序中的哪些点需要与现有的Date
和Calendar
类兼容,或者您是否可以使用更合理的表示创建有用的子类
答案 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图书馆。