java 格式化日期到毫秒_关于日期:Java – SimpleDateFormat格式化程序,以毫秒为单位返回纪元时间...

本问题已经有最佳答案,请猛点这里访问。

我是Java和编码的新手 - 我有一些代码以下列格式yyyy.MM.dd HH:mm:ss:ms返回时间戳,如下所示:

SimpleDateFormat formatter = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss:sss");

返回:

2017.07.19 11:42:30:423

有没有办法编辑上面的"SimpleDateFormat格式化程序"代码,将日期/时间作为包含毫秒的纪元时间戳返回,以便返回的值按照下面的格式进行格式化?

1500464550423

我希望我可以修改SimpleDateFormat formatter代码的("yyyy.MM.dd HH:mm:ss:sss")部分来执行此操作。

非常感谢任何帮助或建议。

谢谢

这对我来说不是100%清楚。 你是说你收到2017.07.19 11:42:30:423作为一个字符串,你想将它转换为自纪元以来的毫秒数?

这是正确的 - 时间戳值后来在代码中使用并用于创建一个变量字符串 - 返回时间戳的部分是"+ formatter.format(time)"而没有引号 - 这就是我希望的原因 我可以修改("yyyy.MM.dd HH:mm:ss:sss")部分代码,以毫秒为单位返回epoc,因为我不知道如何修改代码以使用人们在这里建议的其他方法。..

在格式模式字符串中使用大小写时遇到一个简单的错误(这些区分大小写)。更糟糕的是,你正在使用旧的麻烦的SimpleDateFormat类。它的许多问题之一是它没有告诉你问题是什么。

所以我建议您使用现代Java日期和时间API(我故意使用您的格式模式字符串逐字):

String receivedTimetamp ="2017.07.19 11:42:30:423";

DateTimeFormatter parseFormatter

= DateTimeFormatter.ofPattern("yyyy.MM.dd HH:mm:ss:sss");

LocalDateTime dateTime = LocalDateTime.parse(receivedTimetamp, parseFormatter);

System.out.println(dateTime);

此代码抛出IllegalArgumentException: Too many pattern letters: s。我希望这可以让你意识到这样一个事实,即你使用的是两秒钟的秒数和三秒钟的秒数。如果仍然不清楚,文档将告诉您小写s在几秒内是正??确的,而分数需要大写s。我们来修理:

DateTimeFormatter parseFormatter

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

现在代码打印2017-07-19T11:42:30.423,因此我们设法正确解析字符串。

要转换为毫秒,我们仍然缺少一个重要的信息:在什么时区应该解释时间戳?我认为两个明显的猜测是UTC和你当地的时区(我不知道)。试试UTC:

System.out.println(dateTime.atOffset(ZoneOffset.UTC).toInstant().toEpochMilli());

这会产生1500464550423,这是您要求的数字。我想我们已经完成了。

如果您想要JVM的时区设置,请使用.atZone(ZoneId.systemDefault())而不是.atOffset(ZoneOffset.UTC),但要注意该设置可能会被同一JVM中运行的其他软件更改,因此这很脆弱。

感谢您提供了很好的解释 - 我很难理解如何将它集成到我的代码中,因为我对Java很新,但是我不怀疑你的建议是否正确 - 我需要花一些时间来工作这个

首先,查看SimpleDateFormat的文档。对应于毫秒的模式是大写S,而小写S对应于秒。问题是SimpleDateFormat通常不会抱怨并尝试以秒为单位解析423,将此金额添加到结束日期(给出不正确的结果)。

无论如何,SimpleDateFormat只是将String解析为java.util.Date或将Date格式化为String。如果你想要epoch millis值,你必须从Date对象获取它:

// input string

String s ="2017.07.19 11:42:30:423";

// use correct format ('S' for milliseconds)

SimpleDateFormat formatter = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss:SSS");

// parse to a date

Date date = formatter.parse(s);

// get epoch millis

long millis = date.getTime();

System.out.println(millis); // 1500475350423

问题是SimpleDateFormat使用系统的默认时区,因此上面的最终值(1500475350423)将等于系统时区中的特定日期和时间(可能与您的时区不同 - 仅用于记录,我的系统的默认时区是America/Sao_Paulo)。如果要指定此日期在哪个时区,则需要在格式化程序中设置(在调用parse之前):

// set a timezone to the formatter (using UTC as example)

formatter.setTimeZone(TimeZone.getTimeZone("UTC"));

这样,millis的结果将是1500464550423(相当于UTC中的指定日期和时间)。

要执行相反的操作(从millis值创建日期),您必须创建一个Date对象,然后将其传递给格式化程序(同时注意设置格式化程序的时区):

// create date from millis

Date date = new Date(1500464550423L);

// use correct format ('S' for milliseconds)

SimpleDateFormat formatter = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss:SSS");

formatter.setTimeZone(TimeZone.getTimeZone("UTC"));

// format date

String formatted = formatter.format(date);

Java新的日期/时间API

旧类(Date,Calendar和SimpleDateFormat)存在许多问题和设计问题,并且它们将被新API替代。

如果您使用的是Java 8,请考虑使用新的java.time API。与旧的API相比,它更容易,更少出错并且更不容易出错。

如果您使用Java <= 7,则可以使用ThreeTen Backport,这是Java 8的新日期/时间类的一个很好的后端。对于Android,还有ThreeTenABP(更多关于如何在这里使用它)。

以下代码适用于两者。

唯一的区别是包名称(在Java 8中是java.time,在ThreeTen Backport(或Android的ThreeTenABP)中是org.threeten.bp),但类和方法名称是相同的。

由于输入String没有时区信息(仅限日期和时间),首先我将其解析为LocalDateTime(表示没有时区的日期和时间的类)。然后我将此日期/时间转换为特定时区并从中获取millis值:

// input string

String s ="2017.07.19 11:42:30:423";

// use correct format ('S' for milliseconds)

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

// as the input string has no timezone information, parse it to a LocalDateTime

LocalDateTime dt = LocalDateTime.parse(s, formatter);

// convert the LocalDateTime to a timezone

ZonedDateTime zdt = dt.atZone(ZoneId.of("Europe/London"));

// get the millis value

long millis = zdt.toInstant().toEpochMilli(); // 1500460950423

该值现在1500460950423,相当于伦敦时区的指定日期和时间。

请注意,API使用IANA时区名称(始终采用Region/City格式,如America/Sao_Paulo或Europe/Berlin)。

避免使用3个字母的缩写(如CST或PST),因为它们不明确且不标准。

您可以通过调用ZoneId.getAvailableZoneIds()获取可用时区列表(并选择最适合您系统的时区)。

如果要使用UTC,也可以使用ZoneOffset.UTC常量。

相反,您可以获取millis值来创建Instant,将其转换为时区并将其传递给formatter:

// create Instant from millis value

Instant instant = Instant.ofEpochMilli(1500460950423L);

// use correct format ('S' for milliseconds)

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

// convert to timezone

ZonedDateTime z = instant.atZone(ZoneId.of("Europe/London"));

// format

String formatted = z.format(formatter);

你可以试试

long time = System.currentTimeMillis();

我认为op希望从字符串日期开始

你是对的......然而,这个问题没有说明

这只是对一个问题的回答......假设作者正在从系统中取出日期

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

很好的代码,但缺乏解释。仅限代码的答案很少有用,请解释您如何解决提问者的问题。

这个主题可能会有所帮助stackoverflow.com/questions/6687433/…

第一个建议是转移到java8 java.time API而不是学习损坏的java.date API

然后做:

Instant i = Instant.now();

System.out.println(i.toEpochMilli());

在你的情况下你可以做:

LocalDateTime myldt = LocalDateTime.parse("2017-06-14 14:29:04",

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

System.out.println(myldt.toInstant(ZoneOffset.UTC).toEpochMilli());

请注意,只要您使用api玩更多内容,您就会找到更多方法来实现相同的目标,最后您将结束调用toEpochMilli

感谢您的评论 - 我上面引用的代码是代码块的一部分,我不确定如何集成您建议的内容 - 理想情况下我需要了解是否/如何使用"SimpleDateFormat"函数返回epoch timestamp因为这意味着我不需要重新jig任何其他代码,因为我的理解是有限的

是。而不是使用SimpleDateFormat使用DateTimeFormatter

谢谢,我将有一个游戏,看看我是否可以在代码中为"DateTimeFormatter"字面交换"SimpleDateFormat"并使用"SSS"作为格式化程序(?) - 我对java很新,所以请原谅我的无知!

你将需要java 8来使用该类

如果你有java.util.Date那么调用getTime()将返回自纪元以来的millis数。例如:

SimpleDateFormat formatter = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss:sss");

Date dateToBeFormatted = new Date();

// this will print a datetime literal on the above format

System.out.println(formatter.format(dateToBeFormatted));

// this will print the number of millis since the Java epoch

System.out.println(dateToBeFormatted.getTime());

这里的关键点是,为了获得自纪元以来的毫秒数,您不需要SimpleDateFormatter,因为自纪元以来的毫秒数是Date的属性。

感谢您的评论 - 我上面引用的代码是代码块的一部分,我不确定如何集成您建议的内容 - 理想情况下我需要了解是否/如何使用"SimpleDateFormat"函数返回epoch timestamp因为这意味着我不需要重新jig任何其他代码,因为我的理解是有限的

我已经更新了答案以包含一个例子,希望有所帮助。

谢谢你的故障 - 这对我的理解有帮助!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值