在纪元中转换日期格式

Posted

技术标签:

【中文标题】在纪元中转换日期格式【英文标题】:Convert a date format in epoch 【发布时间】:2011-10-04 23:18:36 【问题描述】:

我有一个日期格式的字符串,例如

Jun 13 2003 23:11:52.454 UTC

包含毫秒...我想在纪元中转换。 是否有 Java 中的实用程序可以用来进行这种转换?

【问题讨论】:

【参考方案1】:

这段代码展示了如何使用java.text.SimpleDateFormat 从字符串中解析java.util.Date:

String str = "Jun 13 2003 23:11:52.454 UTC";
SimpleDateFormat df = new SimpleDateFormat("MMM dd yyyy HH:mm:ss.SSS zzz");
Date date = df.parse(str);
long epoch = date.getTime();
System.out.println(epoch); // 1055545912454

Date.getTime() 以毫秒为单位返回纪元时间。

【讨论】:

【参考方案2】:

您也可以使用 Java 8 API

import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;

public class ***Test
    public static void main(String args[])
        String strDate = "Jun 13 2003 23:11:52.454 UTC";
        DateTimeFormatter dtf  = DateTimeFormatter.ofPattern("MMM dd yyyy HH:mm:ss.SSS zzz");
        ZonedDateTime     zdt  = ZonedDateTime.parse(strDate,dtf);        
        System.out.println(zdt.toInstant().toEpochMilli());  // 1055545912454  
    

DateTimeFormatter 类替换了旧的 SimpleDateFormat。然后,您可以创建一个ZonedDateTime,从中提取所需的纪元时间。

主要优点是您现在是线程安全的。

感谢 Basil Bourque 的评论和建议。阅读他的回答以获取完整的详细信息。

【讨论】:

【参考方案3】:

tl;博士

ZonedDateTime.parse( 
                        "Jun 13 2003 23:11:52.454 UTC" , 
                        DateTimeFormatter.ofPattern ( "MMM d uuuu HH:mm:ss.SSS z" ) 
                    )
              .toInstant()
              .toEpochMilli()

1055545912454

java.time

此答案扩展了Answer by Lockni。

DateTimeFormatter

首先通过创建DateTimeFormatter 对象来定义格式模式以匹配您的输入字符串。

String input = "Jun 13 2003 23:11:52.454 UTC";
DateTimeFormatter f = DateTimeFormatter.ofPattern ( "MMM d uuuu HH:mm:ss.SSS z" );

ZonedDateTime

将字符串解析为ZonedDateTime。你可以把这个类想象成:(Instant + ZoneId)。

ZonedDateTime zdt = ZonedDateTime.parse ( "Jun 13 2003 23:11:52.454 UTC" , f );

zdt.toString(): 2003-06-13T23:11:52.454Z[UTC]

Count-from-epoch

我不建议将日期时间值作为 count-from-epoch 进行跟踪。这样做会使调试变得棘手,因为人类无法从数字中辨别出有意义的日期时间,因此无效/意外的值可能会溜走。此外,这些计数在粒度(整秒、毫、微米、纳米等)和纪元(各种计算机系统至少有两打)方面是不明确的。

但是,如果您坚持,您可以通过 Instant 类从 UTC (1970-01-01T00:00:00) 的 1970 年第一刻的纪元开始计算毫秒数。请注意,这意味着数据丢失,因为您将任何纳秒级截断到毫秒级。

Instant instant = zdt.toInstant ();

instant.toString(): 2003-06-13T23:11:52.454Z

long millisSinceEpoch = instant.toEpochMilli() ; 

1055545912454


关于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.* 类。 Hibernate 5 & JPA 2.2 支持 java.time

从哪里获取 java.time 类?

Java SE 8Java SE 9Java SE 10Java SE 11 和更高版本 - 具有捆绑实现的标准 Java API 的一部分。 Java 9 带来了一些小功能和修复。 Java SE 6Java SE 7 大部分 java.time 功能在ThreeTen-Backport 中向后移植到 Java 6 和 7。 Android java.time 类的更高版本的 android (26+) 捆绑实现。 对于早期的 Android (API desugaring 的进程带来了最初未内置于 Android 中的subset of the java.time 功能。 如果脱糖不能满足您的需求,ThreeTenABP 项目会将ThreeTen-Backport(如上所述)适配到 Android。见How to use ThreeTenABP…

【讨论】:

【参考方案4】:

创建将字符串转换为日期格式的常用方法

public static void main(String[] args) throws Exception 
    long test = ConvertStringToDate("May 26 10:41:23", "MMM dd hh:mm:ss");
    long test2 = ConvertStringToDate("Tue, Jun 06 2017, 12:30 AM", "EEE, MMM dd yyyy, hh:mm a");
    long test3 = ConvertStringToDate("Jun 13 2003 23:11:52.454 UTC", "MMM dd yyyy HH:mm:ss.SSS zzz");


private static long ConvertStringToDate(String dateString, String format) 
    try 
        return new SimpleDateFormat(format).parse(dateString).getTime();
     catch (ParseException e) 
    return 0;

【讨论】:

不要吞下异常。它们是有意义的。通常是重要的。 我建议远离现在早已过时的日期和时间课程,例如SimpleDateFormat。 2011 年,当有人问这个问题时,我也使用了它们。没有了。【参考方案5】:
  String dateTime="15-3-2019 09:50 AM" //time should be two digit like 08,09,10 
   DateTimeFormatter dtf  = DateTimeFormatter.ofPattern("dd-MM-yyyy hh:mm a");
        LocalDateTime zdt  = LocalDateTime.parse(dateTime,dtf);
        LocalDateTime now = LocalDateTime.now();
        ZoneId zone = ZoneId.of("Asia/Kolkata");
        ZoneOffset zoneOffSet = zone.getRules().getOffset(now);
        long a= zdt.toInstant(zoneOffSet).toEpochMilli();
        Log.d("time","---"+a);

您可以通过a link 获取区域 ID!

【讨论】:

感谢您的贡献。这不是完全相同的问题。我得到java.time.format.DateTimeParseException: Text '15-3-2019 09:50 AM' could not be parsed at index 3。最后正确的转换是long a = LocalDateTime.parse(dateTime, dtf).atZone(zone).toInstant().toEpochMilli();

以上是关于在纪元中转换日期格式的主要内容,如果未能解决你的问题,请参考以下文章

以日期时间格式转换纪元日期 1980-01-01

在 Oracle SQL 中将纪元时间转换为正常的日期时间格式

将日期从人类可读格式转换为纪元失败

在php中将纪元时间斜坡转换为格式化的日期字符串[重复]

将具有日期和纪元格式值的字符串列转换为 postgresql/Tableau prep 中的日期列

使用 PHP 将 mm/dd/yyyy 格式转换为纪元