Java 将字符串转换为日期(CEST工作正常,GMT和02:00不工作) 问题:

Java 将字符串转换为日期(CEST工作正常,GMT和02:00不工作) 问题:,java,android,datetime,datetime-parsing,Java,Android,Datetime,Datetime Parsing,为什么我的Android应用程序无法解析String str1=“2017年6月20日星期二15:56:29 CEST” 我发现了一些类似的问题,但没有一个对我有帮助 旁注 在我的项目中,我有一些运行在计算机上的Java应用程序和一些Android应用程序。他们能够互相交流 消息中包含时间戳。然而,我的Java应用程序正在以类似于2017年6月20日星期二15:56:29 CEST的格式发送时间戳,而我的Android应用程序则以类似于2017年6月20日星期二13:40:37 GMT+02:0

为什么我的Android应用程序无法解析
String str1=“2017年6月20日星期二15:56:29 CEST”

我发现了一些类似的问题,但没有一个对我有帮助

旁注 在我的项目中,我有一些运行在计算机上的Java应用程序和一些Android应用程序。他们能够互相交流

消息中包含时间戳。然而,我的Java应用程序正在以类似于2017年6月20日星期二15:56:29 CEST的格式发送时间戳,而我的Android应用程序则以类似于2017年6月20日星期二13:40:37 GMT+02:00的格式发送时间戳。要保存包含时间的消息,我必须将传入时间解析为日期

我的Android应用程序 在我的Android应用程序中,我无法正确解析字符串str1=“Tue Jun 20 15:56:29 CEST 2017”:

java.text.ParseException:不可解析日期:“2017年6月20日星期二15:56:29 CEST”

String str2=“星期二6月20日13:40:37 GMT+2017年2:00”
工作正常

代码: 我的Java应用程序 但是,我的Java应用程序可以正确解析这两个字符串

代码: 三十解 字符串到LocalDateTime 要转换传入字符串,我使用以下代码:

    String time = "Mon Jun 26 15:42:51 GMT 2017";
    DateTimeFormatter gmtDateTimeFormatter = DateTimeFormatter.ofPattern("EE MMM dd HH:mm:ss 'GMT' yyyy", Locale.ENGLISH));
    LocalDateTime timestamp = LocalDateTime.parse(time, gmtDateTimeFormatter);
LocalDateTime到字符串 要将LocalDateTime转换为字符串,我使用以下方法:

    LocalDateTime timestamp = LocalDateTime.now();
    DateTimeFormatter gmtDateTimeFormatter = DateTimeFormatter.ofPattern("EE MMM dd HH:mm:ss 'GMT' yyyy", Locale.ENGLISH));
    String time = gmtDateTimeFormatter.format(timestamp); 

也许Android处理
zzzz
模式的方式有所不同(可能Java的实现比Android更好地处理它,所以它以Android没有的方式“猜测”正确的时区)。我不知道

无论如何,我可以建议你避免使用那些旧的课程吗?这些旧类(
Date
Calendar
SimpleDateFormat
)具有和,它们正在被新的API所取代

如果使用<强> java 8 < />,请考虑使用这更容易


如果您使用的是JavaFYI,那么像、
Java.text.SimpleTextFormat
这样麻烦的旧日期时间类现在被这些类所取代。看见对于Android,请参阅ThreeTen Backport项目。如果您可以得到一个不包含四个字母时区缩写的字符串,那将是最好的选择。三个字母和四个字母的缩写通常是模棱两可的,有时——与CEST一样——只有半个时区。对于CEST,如果日期是在冬天,而CEST没有使用,我不知道会有什么结果。谢谢你的帮助。到目前为止,我在我的Android应用程序ThreeTenABP和Java应用程序ThreeTen中实现了。现在仍然存在一些小问题。Android应用程序用点打印日期,而Java应用程序没有。然而,我想没有简单的解决办法。我必须使用正则表达式并构建自己的字符串。你是说秒后有一个点吗?在我的示例中,我使用date对象调用
println
(它调用
toString
,并打印秒数)。如果要更改输出格式,请使用
DateTimeFormatter
。日期后面不显示点。但仅在Android应用程序中。(请参阅我编辑的问题->新问题)您正在创建一个没有区域设置的格式化程序,因此它使用JVM的默认设置。尝试使用模式的
DateTimeFormatter.ofPattern(“EE-MMM-dd-HH:mm:ss'GMT'yyyy”,Locale.ENGLISH)
(或
Locale.US
,可能两者都可以)。
    String time = "Mon Jun 26 15:42:51 GMT 2017";
    DateTimeFormatter gmtDateTimeFormatter = DateTimeFormatter.ofPattern("EE MMM dd HH:mm:ss 'GMT' yyyy", Locale.ENGLISH));
    LocalDateTime timestamp = LocalDateTime.parse(time, gmtDateTimeFormatter);
    LocalDateTime timestamp = LocalDateTime.now();
    DateTimeFormatter gmtDateTimeFormatter = DateTimeFormatter.ofPattern("EE MMM dd HH:mm:ss 'GMT' yyyy", Locale.ENGLISH));
    String time = gmtDateTimeFormatter.format(timestamp); 
// when parsing, if finds ambiguous CET or CEST, it uses Berlin as prefered timezone
Set<ZoneId> set = new HashSet<>();
set.add(ZoneId.of("Europe/Berlin"));

DateTimeFormatter fmt = new DateTimeFormatterBuilder()
    // your pattern (weekday, month, day, hour/minute/second)
    .appendPattern("EE MMM dd HH:mm:ss ")
    // optional timezone short name (like "CST" or "CEST")
    .optionalStart().appendZoneText(TextStyle.SHORT, set).optionalEnd()
    // optional GMT offset (like "GMT+02:00")
    .optionalStart().appendPattern("OOOO").optionalEnd()
    // year
    .appendPattern(" yyyy")
    // create formatter (using English locale to make sure it parses weekday and month names correctly)
    .toFormatter(Locale.US);
ZonedDateTime z1 = ZonedDateTime.parse("Tue Jun 20 14:53:08 CEST 2017", fmt);
System.out.println(z1);
// parse with UTC offset
ZonedDateTime z2 = ZonedDateTime.parse("Tue Jun 20 13:40:37 GMT+02:00 2017", fmt)
    // convert to Berlin timezone
    .withZoneSameInstant(ZoneId.of("Europe/Berlin"));
System.out.println(z2);
// convert ZonedDateTime to Date
Date date = Date.from(z1.toInstant());

// convert back to ZonedDateTime (using Berlin timezone)
ZonedDateTime z = date.toInstant().atZone(ZoneId.of("Europe/Berlin")); 
// convert ZonedDateTime to Date
Date date = DateTimeUtils.toDate(z1.toInstant());

// convert back to ZonedDateTime (using Berlin timezone)
ZonedDateTime z = DateTimeUtils.toInstant(date).atZone(ZoneId.of("Europe/Berlin"));