在Java中将Epoch秒转换为日期和时间格式

31

我拥有自1970年1月1日UTC以来的秒数(时间戳)。

1320105600

我需要将这些秒数转换为以下格式的日期和时间。

2011年11月4日星期五 上午5:00

我该如何实现这个功能?


6
可以浏览Javadocs来获取灵感-例如java.util.Date。 - Ingo
5个回答

52

如果你被限制使用遗留的java.util.Datejava.util.Calendar API,需要注意时间戳是以毫秒为单位解释的,而不是秒。因此,你需要先将其乘以1000,才能得到以毫秒为单位的时间戳。

long seconds = 1320105600;
long millis = seconds * 1000;
这样您就可以将其传递给例如java.util.Date的构造函数,最终使用SimpleDateFormatjava.util.Date转换为所需日期格式模式下的java.lang.String,如果需要在预定义的时区中进行转换(否则它将使用系统默认时区,该时区不一定是GMT/UTC,因此格式化的时间可能会出错)。
Date date = new Date(millis);
SimpleDateFormat sdf = new SimpleDateFormat("EEEE,MMMM d,yyyy h:mm,a", Locale.ENGLISH);
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
String formattedDate = sdf.format(date);
System.out.println(formattedDate); // Tuesday,November 1,2011 12:00,AM

如果你已经使用Java8,那么可以使用LocalDateTime#ofEpochSecond()方法,直接传入以秒为单位的时间戳,而不需要将其乘以1000来转换成毫秒。

LocalDateTime dateTime = LocalDateTime.ofEpochSecond(seconds, 0, ZoneOffset.UTC);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEEE,MMMM d,yyyy h:mm,a", Locale.ENGLISH);
String formattedDate = dateTime.format(formatter);
System.out.println(formattedDate); // Tuesday,November 1,2011 12:00,AM

请详细阐述您得到的结果和期望的结果。我无法直接亲自前往您那里查看问题。但我可以告诉您,我发布的代码在我的电脑上运行良好,并且我得到了最后一行注释中显示的结果。 - BalusC
实际上,我在发布问题时犯了一个错误。我正在使用美国芝加哥的时间,并且我的秒数是1320105600。这个问题的正确结果应该是2011年11月1日星期二上午7:00,但是使用上述代码我得到的是2011年10月31日星期一下午7:00。 - androiduser
我知道时区不同,但是相差12个小时? - BalusC
我再次验证了芝加哥时间(CST,GMT-6)。你的比较材料可能是错误的或被误解了。也许AM / PM标记或24小时制的信息没有被正确解释。确切的12小时差异也是一个太大的巧合。请注意,您在另一个问题中得到的答案也证实了这一点。尝试使用CST作为时区和calendar.set(2011, Calendar.OCTOBER, 31, 19, 0);。你会得到正好1320105600 - BalusC
似乎你或你的同事仍然没有理解时区的影响:http://stackoverflow.com/questions/8273200/code-to-convert-seconds-to-date-and-time-combination-in-java。这也证实了你的比较材料是错误的。我会编辑答案,包括UTC时区。 - BalusC

20
long yourSeconds = 1320105600L;
Date date = new Date(yourSeconds * 1000);

查看这个javadoc以获取更多信息。构造函数需要毫秒。

要以适当的格式显示此日期,您应该检查DateFormat

这是一个例子:

DateFormat df = new SimpleDateFormat("dd MMM yyyy hh:mm:ss zzz");
System.out.println(df.format(date));

12

java.time

BalusC的回答很好,因为它指向了使用java.time。但是那个回答使用LocalDateTime,而Instant更加适合。LocalDateTime不是时间轴上的瞬间,因为它有意没有与UTC偏移量相关的概念时区

java.time

java.time 框架是内置于 Java 8 及其后版本中的。这些类取代了旧有的麻烦日期时间类,如 java.util.Date.Calendarjava.text.SimpleDateFormatJoda-Time 团队也建议迁移到 java.time。

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

Java 6 和 7 中的大部分 java.time 功能都被移植到 ThreeTen-Backport 中,并在 ThreeTenABP 中进一步适用于 Android。

Instant

纳秒 分辨率表示的 UTC 时间轴上的瞬间由 Instant 类表示。

Instant instant = Instant.ofEpochSecond ( 1_320_105_600L );

在控制台中转储。您的输入值是2011年11月1日第一时刻在UTC中。末尾的Z代表“Zulu”,表示UTC。

System.out.println ( "instant: " + instant );

即时时间:2011年11月1日00:00:00Z

ZonedDateTime

在您的评论中,您提到想要通过America/Chicago时区的视角看到这个日期时间。使用正确的时区名称。应用一个时区ZoneId,以获得一个ZonedDateTime对象。我们看到在那个日期,芝加哥比UTC晚五个小时。

ZoneId zoneId = ZoneId.of ( "America/Chicago" );
ZonedDateTime zdt = instant.atZone ( zoneId );

以下是翻译内容:

zdt: 2011-10-31T19:00-05:00[美国/芝加哥]

字符串

上述字符串采用标准的ISO 8601格式。要生成其他格式的字符串,请使用DateTimeFormatter类。您可以指定自己的自定义模式,但通常最好让java.time自动本地化到Locale对象中编码的人类语言和文化规范。

DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime ( FormatStyle.FULL );
formatter = formatter.withLocale ( Locale.US );
String output = zdt.format ( formatter );

2011年10月31日晚上7点(中央标准时间)

如果您想指定自己的自定义格式,请在Stack Overflow上搜索许多示例和更多讨论。


2
int seconds = 1320105600;
Date date = new Date(seconds * 1000);
SimpleDateFormat sdf = new SimpleDateFormat("EEEE,MMMM d,yyyy h:mm,a");
System.out.println(sdf.format(date));

0
诀窍在于使用java.util.Datejava.text.DateFormat来获得所需的格式。您可以查阅Web上的教程以了解如何操作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接