假设:
private Calendar calendarInstance = Calendar.getInstance();
public long inMillis() {
calendarInstance.set(year, month, day, hour, min);
return calendarInstance.getTimeInMillis();
}
根据我的理解,结果随着时间的推移而回归,以毫秒为单位
从纪元开始的当前时间为UTC毫秒。
鉴于我的测试始终将对象设置为相同,为什么随着时间的推移结果会有所不同?
detailedMoment = new MomentInTime(2012, 11, 1, 19, 9);
detailedMoment.inMillis() // gives different results as time passes by
更新
我继续猜测自己
在同一时期我得到了
1_351_796_940 // http://www.epochconverter.com
1_354_410_540 // my number
答案 0 :(得分:2)
嗯,你没有设置秒或毫秒。 JavaDoc说:
设置年,月,日,小时和分钟字段。 其他字段不会更改。
答案 1 :(得分:2)
我认为你应该使用clear()。如果你这样做,它将每次返回确切的毫秒数。
public long inMillis() {
calendarInstance.clear();
calendarInstance.set(year, month, day, hour, min);
return calendarInstance.getTimeInMillis();
}
来自Java doc
设置此日历的所有日历字段值和时间值
(millisecond offset from the Epoch)
未定义。这意味着isSet()将为所有日历字段返回false,并且日期和时间计算将字段视为从未设置过。 Calendar实现类可以使用其特定的默认字段值进行日期/时间计算。例如,如果YEAR字段值未定义,则GregorianCalendar使用1970
。
示例程序
public class MomentInTime {
private static Calendar calendarInstance = Calendar.getInstance();
public static long inMillis() {
calendarInstance.clear();
calendarInstance.set(2012, 10, 1, 19, 9);
return calendarInstance.getTimeInMillis();
}
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 10; i++) {
System.out.println(inMillis()/1000);
Thread.sleep(300);
}
}
}
输出:
1351777140
答案 2 :(得分:1)
我想这是因为你缺少Calendar.getInstance()的秒和毫秒。
您只是替换了year, month, day, hour, min
的Calendar对象,但每次获得日历实例时,该特定时间点的秒和毫秒都可能会发生变化。
答案 3 :(得分:1)
java.util
日期时间 API 及其格式化 API SimpleDateFormat
已过时且容易出错。建议完全停止使用它们并切换到 modern Date-Time API*。
使用 java.time
(现代日期时间 API)的解决方案:
import java.time.LocalDate;
import java.time.ZoneOffset;
public class Main {
public static void main(String[] args) {
//Test
System.out.println(inMillis(2021,6,19,8,30));
}
public static long inMillis(int year, int month, int day, int hour, int min) {
return LocalDate.now()
.atStartOfDay(ZoneOffset.UTC)
.withYear(year)
.withMonth(month)
.withDayOfMonth(day)
.withHour(hour)
.withMinute(min)
.toInstant()
.toEpochMilli();
}
}
输出:
1624091400000
这就是http://www.epochconverter.com的显示方式:
从 Trail: Date Time 了解有关现代 Date-Time API 的更多信息。
更简单的版本(感谢 Ole V.V.):
public static long inMillis(int year, int month, int day, int hour, int min) {
return OffsetDateTime.of(year, month, day, hour, min, 0, 0, ZoneOffset.UTC)
.toInstant()
.toEpochMilli();
}
* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 & 7. 如果您正在为 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaring 和 How to use ThreeTenABP in Android Project。