【问题标题】:Epoch time confusion, clarification needed时代混乱,需要澄清
【发布时间】:2012-10-22 11:29:59
【问题描述】:

给定:

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

【问题讨论】:

    标签: java epoch


    【解决方案1】:

    我认为你应该使用clear()。如果你这样做,它将每次返回准确的毫秒数。

    public long inMillis() {
        calendarInstance.clear();
        calendarInstance.set(year, month, day, hour, min);
        return calendarInstance.getTimeInMillis();
    }
    

    来自 Java 文档

    设置此日历的所有日历字段值和时间值(millisecond offset from the Epoch) 未定义。这意味着 isSet() 将为所有日历字段返回 false,并且日期和时间计算会将这些字段视为从未设置过的字段。日历实现类可以使用其特定的默认字段值进行日期/时间计算。例如,如果 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
    

    【讨论】:

    • @Jam 我检查了它,我得到了与它一致的结果。我什至转换为 Date 并检查它是否返回适当的值。
    • 我的数字似乎与 epochconverter.com 不一致。在上述日期以毫秒为单位获取时间时,您会得到什么
    • @Jam 添加了一个示例,您可以检查当天的输出,尽管有睡眠并且时间在变化。
    • 谢谢。你是绝对正确的。能否请您看一下上方并帮助解释可能的数字差异。
    • @Jam 问题可能是因为您没有指定时区并转换为 GMT。检查当地时区。我的价值观完全匹配。您必须使用时区 GMT 创建日历实例以匹配 GMT
    【解决方案2】:

    你没有设置秒或毫秒。 JavaDoc 说:

    设置年、月、日、小时和分钟字段。 其他字段不变。

    【讨论】:

      【解决方案3】:

      我猜这是因为您缺少 Calendar.getInstance() 的 毫秒

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

      【讨论】:

        【解决方案4】:

        java.time

        java.util 日期时间 API 及其格式化 API SimpleDateFormat 已过时且容易出错。建议完全停止使用,改用modern Date-Time API*

        使用现代日期时间 API java.time 的解决方案:

        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 是这样显示的:

        Trail: 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

        【讨论】:

        • 感谢您展示当今绝对推荐的现代解决方案。 OffsetDateTime.of(2012, 11, 1, 19, 9, 0, 0, ZoneOffset.UTC).toInstant().toEpochMilli() 看起来会更简单吗? (产生 1 351 796 940 000,这似乎与提问者的预期相符。)
        猜你喜欢
        • 1970-01-01
        • 2012-04-26
        • 2015-05-02
        • 2011-07-24
        • 2011-11-09
        • 2012-07-18
        • 1970-01-01
        • 2023-03-09
        • 1970-01-01
        相关资源
        最近更新 更多