【问题标题】:Java millis time with hourly resolution具有每小时分辨率的 Java 毫秒时间
【发布时间】:2020-02-06 10:05:09
【问题描述】:

如何在 UTC 中获取 java 时间毫秒,忽略分钟和秒。

例如: 如果是 2019 年 10 月 10 日,上午 1:10:59,它应该得到 Time 或毫秒 2019 年 10 月 10 日凌晨 1 点。

【问题讨论】:

  • 你有什么尝试吗?
  • 请参阅How to Ask,在您提出关于 SO 的问题之前,您需要付出一些努力,谢谢。
  • 我建议 1. 解析输入,2. 格式化输出。只需使用不包括分钟和秒的格式模式即可。

标签: java time timezone utc localtime


【解决方案1】:

总结:

Instant
.now()
.truncatedTo( 
    ChronoUnit.HOURS 
)
.toEpochMilli()

1570600800000


java.time,现代 Java 日期和时间 API 正好提供您需要的方法:许多类都有一个 truncatedTo 方法来满足您的需求。

    Instant now = Instant.now();
    System.out.println("Rough milliseconds:                        " + now.toEpochMilli());
    Instant currentWholeHour = now.truncatedTo(ChronoUnit.HOURS);
    System.out.println("Milliseconds ignoring minutes and seconds: "
            + currentWholeHour.toEpochMilli());

刚才运行这个 sn-p 时,输出是:

Rough milliseconds:                        1570604053787
Milliseconds ignoring minutes and seconds: 1570600800000

我很清楚第一行是你要求拥有的。我只是把它包括在内,让你看看有什么不同。

截断发生在 UTC。如果您所在的时区与 UTC 的偏移量不是整数小时,则结果可能与您预期的不同。此类时区的示例包括亚洲/加德满都、美洲/St_Johns,有时还包括澳大利亚/Lord_Howe。

链接: Oracle tutorial: Date Time

【讨论】:

    【解决方案2】:

    你可以使用LocalDate#atTime:

    LocalDate.now().atTime(LocalDateTime.now().getHour(), 0, 0);
    

    这将为您提供当前日期,并将小时、分钟和秒设置为 0。

    并获得 UTC 毫秒数:

    LocalDate.now().atTime(LocalDateTime.now().getHour(), 0, 0).toInstant(ZoneOffset.UTC).toEpochMilli();
    

    Jon Skeet 注意到,调用now 可能会在极端情况下产生意想不到的结果。可以肯定的是,我们可以调用它一次,然后使用上述解决方案将其转换为LocalDate

    var currentTime = LocalDateTime.now();
    var currentDate = currentTime.toLocalDate();
    

    或者反过来——先获取LocalDate,然后使用LocalDate#atStartOfDay

    【讨论】:

    • @Zabuza 我同意,但我无法明确看到,这应该转换为字符串
    • 像这样使用now() 两次总是很危险的,因为如果时钟从 23:59:00 翻转到 00:00:00,您可能会返回将近 24 小时的结果。
    • @NoviceUser:Time 对象是什么意思?据我所知,Java 标准库中没有 Time 类。你的意思是LocalTimeLocalDateTime?如果你能展示你已经尝试过的东西,这将是有帮助的 - 它会让你想要实现的目标更加清晰。
    • @JonSkeet 我的意思是让 Mills 很抱歉造成混乱
    • @JonSkeet 感谢您注意到极端情况,编辑了答案
    【解决方案3】:

    鉴于您对 UTC 毫秒感兴趣,并且每小时有整数个毫秒,您可以通过简单的算术来做到这一点。对于大多数日历计算,我真的不建议这样做,但在这种情况下,我认为这是最简单的方法。像这样的:

    private static final long MILLISECONDS_PER_HOUR = TimeUnit.HOURS.toMillis(1);
    
    // Injecting a clock makes the method testable. You can use Clock.systemUTC()
    // for the system clock.
    public static long truncateMillisToHour(Clock clock) {
        long millisSinceEpoch = clock.millis();
        // Truncate to the nearest hour
        long hoursSinceEpoch = millisSinceEpoch / MILLISECONDS_PER_HOUR;
        // Then multiply up again
        return hoursSinceEpoch * MILLISECONDS_PER_HOUR;
    }  
    

    请注意,如果时钟是在 纪元之前,这会将 向上 舍入到最接近的小时,但如果您使用的是真正的“当前时间”,那么这不太可能是个问题。

    (我在看到 Ole V.V. 的 truncatedTo 的回答之前写了这个答案,这是一个非常好的方法。)

    【讨论】:

      【解决方案4】:

      这是忽略时间和分钟秒并返回UTC时间的方法

      private static SimpleDateFormat dateToString = new SimpleDateFormat("yyyy-MM-dd");
      
      public static String dateToString(Date date) {
      
      dateToString.setTimeZone(TimeZone.getTimeZone("UTC "));
      
      String strDate = "";
        strDate =  dateToString.format(date);
      
        return strDate;
      }
      

      【讨论】:

      • 这根本不显示小时 - 它返回一个字符串,而不是毫秒。
      • 请不要教年轻人使用早已过时且臭名昭著的SimpleDateFormat类。至少不是第一选择。而且不是没有任何保留。今天我们在java.time, the modern Java date and time API, 和它的DateTimeFormatter 中做得更好。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-11-12
      • 1970-01-01
      • 2011-04-13
      • 2018-06-01
      • 1970-01-01
      • 2014-07-21
      相关资源
      最近更新 更多