大纪元时间混乱,需要澄清

时间:2012-11-01 19:54:40

标签: java epoch

假设:

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

更新

我继续猜测自己 enter image description here

在同一时期我得到了

1_351_796_940 // http://www.epochconverter.com
1_354_410_540 // my number

4 个答案:

答案 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

enter image description here

答案 2 :(得分:1)

我想这是因为你缺少Calendar.getInstance()的毫秒

您只是替换了year, month, day, hour, min的Calendar对象,但每次获得日历实例时,该特定时间点的秒和毫秒都可能会发生变化。

答案 3 :(得分:1)

java.time

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

ONLINE DEMO

这就是http://www.epochconverter.com的显示方式:

enter image description here

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 desugaringHow to use ThreeTenABP in Android Project