【问题标题】:Not able to convert date to epoch time [duplicate]无法将日期转换为纪元时间[重复]
【发布时间】:2020-02-21 12:29:26
【问题描述】:

这是我的示例代码

    String dt = "Oct 24 2019 12:00:00.000 AM UTC";
    String dt1="Oct 24 2019 11:59:59.000 PM UTC";
    SimpleDateFormat df = new SimpleDateFormat("MMM dd yyyy HH:mm:ss.SSS 
    aa zzz");
    Date date = df.parse(dt);
    Date date1 = df.parse(dt1);
    long epoch = date.getTime();
    long epoch1 = date1.getTime();
    System.out.println(epoch);
    System.out.println(epoch1);

这里指定了 AM 和 PM,但它没有取值并将异常抛出为

{"error_code":"INVALID_PARAMETER_VALUE","message":"Time range must have a start time earlier than the end time"}

如何在 java 代码中指定 AM/PM。 如何在 java 代码中将昨天的日期和时间作为今天的输入以转换为纪元。

【问题讨论】:

  • 我刚刚运行了你的代码 sn-p,一切都对我有用。
  • 现在请不要使用DateSimpleDateFormat 类。它们已被更好的类所取代。查看LocalDateTimeDateTimeFormatter 类。
  • 仅供参考,存在严重缺陷的日期时间类,例如 java.util.Datejava.util.Calendarjava.text.SimpleDateFormat 现在是 legacy,被 Java 8 及更高版本中内置的 java.time 类所取代.
  • 快速查看documentation会发现H,大写,用于“小时(0-23)”,而h,小写,用于“上午/下午的小时(1 -12)"

标签: java datetime-format epoch


【解决方案1】:

tl;博士

ZonedDateTime
.parse(
    "Oct 24 2019 12:00:00.000 AM UTC" ,
    DateTimeFormatter.ofPattern( "MMM d uuuu hh:mm:ss.SSS a z" ).withLocale( Locale.US ) 
)
.toInstant() 
.toEpochMilli() 

1571875200000

java.time

两个问题:

  • 作为commented by Heuberger,您使用的格式代码不正确。
  • 您使用的日期时间类在几年前被现代 java.time 类所取代。

您的输入,为清晰起见重命名。

String inputStart = "Oct 24 2019 12:00:00.000 AM UTC";
String inputStop = "Oct 24 2019 11:59:59.000 PM UTC";

定义格式模式以匹配您的输入。

DateTimeFormatter f = DateTimeFormatter.ofPattern( "MMM d uuuu hh:mm:ss.SSS a z" ).withLocale( Locale.US );

解析输入。

ZonedDateTime zdtStart = ZonedDateTime.parse( inputStart , f );
ZonedDateTime zdtStop = ZonedDateTime.parse( inputStop , f );

计算经过的时间。我们应该比 24 小时少一秒钟。

Duration d = Duration.between( zdtStart , zdtStop );

显然,您想要自 1970 年第一刻(UTC,1970-01-01T00:00Z)的纪元参考以来的毫秒数。首先从每个ZonedDateTime 中提取构建块类InstantInstant 代表 UTC 中的时刻。此类可让您查询自纪元以来的计数。请注意,java.time 类解析为纳秒。所以要求毫秒可能会导致数据丢失,忽略任何微秒或纳秒。

Instant start = zdtStart.toInstant() ;
Instant stop = zdtStop.toInstant() ;

long millisStart = start.toEpochMilli() ;
long milliStop = stop.toEpochMilli() ;

转储到控制台。

System.out.println( "zdtStart = " + zdtStart );
System.out.println( "zdtStop = " + zdtStop );
System.out.println( "d = " + d );

System.out.println( "start = " + start );
System.out.println( "stop = " + stop );

System.out.println( "millisStart = " + millisStart );
System.out.println( "milliStop = " + milliStop );

zdtStart = 2019-10-24T00:00Z[UTC]

zdtStop = 2019-10-24T23:59:59Z[UTC]

d = PT23H59M59S

开始 = 2019-10-24T00:00:00Z

停止 = 2019-10-24T23:59:59Z

millisStart = 1571875200000

milliStop = 1571961599000



关于java.time

java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.DateCalendarSimpleDateFormat

要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310

Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

您可以直接与您的数据库交换 java.time 对象。使用符合JDBC 4.2 或更高版本的JDBC driver。不需要字符串,不需要java.sql.* 类。

从哪里获得 java.time 类?

ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

【讨论】:

    【解决方案2】:

    您需要使用以下日期格式:

    SimpleDateFormat df = new SimpleDateFormat("MMM dd yyyy hh:mm:ss.SSS a zzz",Locale.US);
    

    对于 AM/PM 标记,使用“a”。对于reference

    例如

    import java.util.*;
    import java.text.*;
    public class Main
    {
        public static void main(String[] args) {
            try{
                String dt = "Oct 24 2019 12:00:00.000 AM UTC";
                String dt1="Oct 24 2019 11:59:59.000 PM UTC";
                SimpleDateFormat df = new SimpleDateFormat("MMM dd yyyy hh:mm:ss.SSS a zzz",Locale.US);
                Date date = df.parse(dt);
                Date date1 = df.parse(dt1);
                long epoch = date.getTime();
                long epoch1 = date1.getTime();
                System.out.println(epoch);
                System.out.println(epoch1);  
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    }
    

    输出:

    1571918400000                                                                                                                                                                      
    1571918399000
    

    【讨论】:

    • 您还应该将第二个参数添加到new SimpleDateFormat,值为Locale.US,否则解析可能会失败,因为Oct 在大多数其他语言中将是一个未知月份。
    • 24日午夜前1秒怎么能是24日午夜前1秒?从午夜(一天的开始)到午夜前 1 秒(一天的结束)有 23 小时 59 分 59 秒。当我运行你的代码时,我得到15718752000001571961599000
    猜你喜欢
    • 2013-04-02
    • 2021-05-26
    • 2018-04-24
    • 2011-12-06
    • 1970-01-01
    • 2012-09-06
    • 2014-08-28
    • 2019-12-08
    • 2018-08-09
    相关资源
    最近更新 更多