如何在java中获取自定义日期和时间的纪元?

Posted

技术标签:

【中文标题】如何在java中获取自定义日期和时间的纪元?【英文标题】:How to get epoch of custom date and time in java? 【发布时间】:2021-11-26 09:38:11 【问题描述】:

我想要每天中午 12 点的一个纪元。我试图制作一个函数来生成一串日期时间并且必须转换为一个纪元,但这不起作用,它还显示 12pm 到 0(零)我不知道为什么

这是我尝试过但显示错误的方法:

Calendar now = Calendar.getInstance();
        int year = now.get(Calendar.YEAR);
        int month=now.get(Calendar.MONTH)+1;
        int date=now.get(Calendar.DATE);
        String yearInString = String.valueOf(year);
        String monthInString=String.valueOf(month);
        if(monthInString.length()==1)
            monthInString="0"+monthInString;
        
        String dateInString=String.valueOf(date);
        if(dateInString.length()==1)
            dateInString="0"+dateInString;
        
        int hour=now.get(Calendar.HOUR);
        String hourInString=String.valueOf(hour);
        int minute=now.get(Calendar.MINUTE);
        String minuteInString=String.valueOf(minute);
        if(minuteInString.length()==1)
            minuteInString="0"+minuteInString;
        
        int second=now.get(Calendar.SECOND);
        String secondInString=String.valueOf(second);
        String HRD=yearInString+"-"+monthInString+"-"+dateInString+" "+hourInString+":"+minuteInString+":"+secondInString;
        System.out.println(HRD);
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-dd-MM HH:mm:ss.SSS");
        LocalDateTime dt = LocalDateTime.parse(HRD, dtf);
        Instant instant = dt.toInstant(ZoneOffset.UTC);
        System.out.println(instant.toEpochMilli());

也试过了

Date date1 = dateFormat.parse(HRD);
long epoch = date1.getTime();
System.out.println(epoch);

但显示错误

线程“main”java.time.format.DateTimeParseException 中的异常:无法在索引 11 处解析文本“2021-10-06 0:29:43” 在 java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2052) 在 java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1954) 在 java.base/java.time.LocalDateTime.parse(LocalDateTime.java:494) 在 customepoch.main(customepoch.java:35)

【问题讨论】:

您是否尝试获取由本地时间(在您所在区域内)或 UTC 时间定义的时间段? 是的,你能帮我吗 是的,我的问题的哪一部分? 对不起,我需要本地时区 既然可以使用 java,time,现代 Java 日期和时间 API(DateTimeFormatterLocalDateTimeInstantZoneOffset),也不要涉及设计不佳和早已过时的Calendar 类。 java.time 为您提供所需的所有功能。 【参考方案1】:

java.time

java.util 日期时间 API 已过时且容易出错。建议彻底停止使用,改用modern Date-Time API*

使用现代日期时间 API java.time 的解决方案: 从下午 12 点的 OffsetDateTime,您可以使用 OffsetDateTime#toInstant 和从 Instant 获取相应的 Instant , 可以得到纪元毫秒数。

演示:

import java.time.LocalDate;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.temporal.TemporalAdjusters;

public class Main 
    public static void main(String[] args) 
        OffsetDateTime todayAtNoon = OffsetDateTime.of(LocalDate.now(ZoneOffset.UTC), LocalTime.NOON, ZoneOffset.UTC);
        OffsetDateTime lastDateOfMonth = todayAtNoon.with(TemporalAdjusters.lastDayOfMonth());
        for (OffsetDateTime odt = todayAtNoon; !odt.isAfter(lastDateOfMonth); odt = odt.plusDays(1)) 
            System.out.println(odt.toInstant().toEpochMilli());
        
    

输出:

1633521600000
1633608000000
1633694400000
...

ONLINE DEMO

Trail: Date Time 了解有关现代日期时间 API 的更多信息。


* 如果您正在为一个 android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaring。请注意,Android 8.0 Oreo 已经提供了support for java.time

【讨论】:

【参考方案2】:

你的代码出了什么问题?

已经有两个答案告诉你如何获得你想要的数字。我不再重复了。

我发布这个答案是因为我感到好奇:为什么您的代码将 12 PM 显示为 0(零)?为什么会收到错误(异常)?这就是我在这里要解决的问题。

首先,正如直接或间接所说,您使用Calendar 类来获取您所在时区的当前时间。 Calendar 设计不佳且早已过时。不要那样做。

您从CalendarInstant 的转换非常非常复杂。如果您从某个遗留 API 获得了 Calendar 并想要转换它(您当前的目的不想要它),那么您只需要:

     Instant instant = now.toInstant();

没错,因为 Java 8 Calendar 有一个 toInstant 用于转换的方法。其他旧的日期和时间类也添加了类似的转换方法。

你试过了:

     int hour=now.get(Calendar.HOUR);

Calendar.HOUR 是上午或下午的小时,从 0 到 11。这解释了为什么下午 12 点得到 0。 Calendar.HOUR_OF_DAY 是一天中从 0 到 23 的小时。这只是关于 Calendar 的众多令人困惑的地方之一,也是我建议您不要使用它的众多原因之一。

您在月份、月份和分钟前加上 0 以确保您有两位数。你一小时一秒都没有做同样的事情。由于您的小时数为 0,因此它只有一位数,并且与格式模式中的 HH 不匹配,后者需要两位数。这导致了您报告的异常。

您尝试使用此格式化程序进行解析:

     DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-dd-MM HH:mm:ss.SSS");

您构建的字符串不包括毫秒。您应该省略 .SSS 或者将秒的小数部分添加到字符串中。

这似乎与你的意图相冲突:

     Instant instant = dt.toInstant(ZoneOffset.UTC);

既然你想要你当地时区的时间,它应该是:

     Instant instant = dt.toInstant(ZoneId.systemDefault());

【讨论】:

【参考方案3】:

假设您已为您的 JVM 正确设置了本地时区,以便使用 ZoneId.systemDefault()。还假设您从今天(2021 年 10 月 6 日)开始。那么您的代码将是:

public static void main(String[] args) 
    LocalDateTime start = LocalDateTime.of(2021, Month.OCTOBER, 6, 12, 0);
    for (long i = 0; i < 10; i++) 
        System.out.println(
                start
                        .plusDays(i)
                        .atZone(ZoneId.systemDefault())
                        .toEpochSecond()
        );
    

【讨论】:

以上是关于如何在java中获取自定义日期和时间的纪元?的主要内容,如果未能解决你的问题,请参考以下文章

如何将自纪元以来的 Unix 时间/时间转换为标准日期和时间?

获取 C 中特定日期的纪元秒数

如何从给定城市的给定日期和时间获取 unix 纪元时间戳(以秒为单位)?

如何在 GWT 中获取最后一周的日期

获取表示当前日期的纪元时间戳范围

C ++自定义时间日期结构到utc纪元