How to convert timestamp string to epoch time?
我有格式
我想将它转换为纪元时间,所以我在下面做:
1 2 3 4 |
我收到以下错误:
java.time.format.DateTimeParseException: Text '2017-18-08 11:45:30.345' could not be parsed: Unable to obtain ZonedDateTime from TemporalAccessor
我也尝试过不同的格式,但仍然会出错。
注意:最初问题的输入是
输入中还有另一个细节:
-
分钟值是
60 ,不接受:有效值从0到59(实际上有一种方法可以接受这个,请参阅下面的"宽容解析") -
hh 是mid-hour-am-pm字段,因此它还需要完全解析AM / PM指示符。由于您没有它,您应该使用hh 模式
所以模式必须是
一种替代方法是将其解析为
1 2 3 4 5 6 7 8 9 | // change 60 minutes to 59 (otherwise it doesn't work) String timeDateStr ="2017-18-08 12:59:30.345"; DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-dd-MM HH:mm:ss.SSS"); // parse to LocalDateTime LocalDateTime dt = LocalDateTime.parse(timeDateStr, dtf); // assume the LocalDateTime is in UTC Instant instant = dt.toInstant(ZoneOffset.UTC); System.out.println(instant.toEpochMilli()); |
这将输出:
1503061170345
这相当于UTC中的
如果您希望在另一个时区中使用日期,则可以使用
1 2 3 | // get the LocalDateTime in some timezone ZonedDateTime z = dt.atZone(ZoneId.of("Europe/London")); System.out.println(z.toInstant().toEpochMilli()); |
输出是:
1503057570345
请注意,结果是不同的,因为相同的本地日期/时间表示每个时区中的不同
另请注意,API使用IANA时区名称(始终采用
避免使用3个字母的缩写(如
您可以通过调用
您也可以将系统的默认时区与
还可以选择将
1 2 | // get the LocalDateTime in +03:00 offset System.out.println(dt.toInstant(ZoneOffset.ofHours(3)).toEpochMilli()); |
输出将等于偏移量
1503050370345
宽松解析
正如@MenoHochschild在评论中提醒我的那样,你可以使用宽松的解析来接受分钟字段中的
1 2 3 4 5 6 | String timeDateStr ="2017-18-08 12:60:30.345"; DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-dd-MM HH:mm:ss.SSS") // use lenient parsing .withResolverStyle(ResolverStyle.LENIENT); // parse to LocalDateTime LocalDateTime dt = LocalDateTime.parse(timeDateStr, dtf); |
在这种情况下,60分钟调整到下一个小时,
2017-08-18T13:00:30.345
夏令时
如果您决定使用UTC或固定偏移量(使用
但是,如果您决定使用时区(
在圣保罗,夏令时开始于2017年10月15日:午夜,时钟从午夜向凌晨1点转移到凌晨1点。因此,此时区内不存在00:00至00:59之间的所有当地时间。如果我在此间隔中创建本地日期,则会将其调整为下一个有效时刻:
1 2 3 4 5 6 | ZoneId zone = ZoneId.of("America/Sao_Paulo"); // October 15th 2017 at midnight, DST starts in Sao Paulo LocalDateTime d = LocalDateTime.of(2017, 10, 15, 0, 0, 0, 0); ZonedDateTime z = d.atZone(zone); System.out.println(z);// adjusted to 2017-10-15T01:00-02:00[America/Sao_Paulo] |
夏令时结束时:2018年2月18日午夜,时钟从17日午夜到晚上23点转移1小时。因此,从23:00到23:59的所有当地时间都存在两次(在DST和非DST中),您必须决定您想要哪一个:
1 2 3 4 5 6 7 8 9 10 | // February 18th 2018 at midnight, DST ends in Sao Paulo // local times from 23:00 to 23:59 at 17th exist twice LocalDateTime d = LocalDateTime.of(2018, 2, 17, 23, 0, 0, 0); // by default, it gets the offset before DST ends ZonedDateTime beforeDST = d.atZone(zone); System.out.println(beforeDST); // before DST end: 2018-02-17T23:00-02:00[America/Sao_Paulo] // get the offset after DST ends ZonedDateTime afterDST = beforeDST.withLaterOffsetAtOverlap(); System.out.println(afterDST); // after DST end: 2018-02-17T23:00-03:00[America/Sao_Paulo] |
请注意,DST结束前后的日期具有不同的偏移量(
您必须检查DST何时开始并以您选择的时区结束,并相应地检查调整。
更正了有关yyyy-dd-MM的代码。微小的值也可能是1-59而不是60.你提供了60.这是解决问题的另一种简单方法。只需使用DateFormat类。
1 2 3 4 5 6 7 8 | String timeDateStr ="2017-18-08 12:59:30.345"; DateFormat df = new SimpleDateFormat("yyyy-dd-MM hh:mm:ss.SSS", Locale.ENGLISH); try { Date d = df.parse(timeDateStr); System.out.println(d.toInstant().toEpochMilli()); } catch (ParseException e) { e.printStackTrace(); } |
您的代码将因以下3个原因而失败。
代码应如下所示:
1 2 3 4 5 |
只是我在nagendra547的答案中做了一些改变
请访问以下代码: -
1 2 3 4 5 6 7 8 | String timeDateStr ="2017-18-08 12:59:30.345"; DateFormat df = new SimpleDateFormat("yyyy-dd-mm hh:mm:ss.SSS", Locale.ENGLISH); try { Date d = df.parse(timeDateStr); System.out.println(d.toInstant().toEpochMilli()); } catch (ParseException e) { e.printStackTrace(); } |