Java/Android - 将 GMT 时间字符串转换为本地时间

Posted

技术标签:

【中文标题】Java/Android - 将 GMT 时间字符串转换为本地时间【英文标题】:Java/Android - Convert a GMT time string to local time 【发布时间】:2012-05-30 07:32:42 【问题描述】:

好的,我有一个字符串,比如“Tue May 21 14:32:00 GMT 2012”,我想将此字符串转换为当地时间,格式为 2012 年 5 月 21 日下午 2:32。我尝试了 SimpleDateFormat("MM dd, yyyy hh:mm a").parse(),但它引发了异常。那我该怎么办?

异常是“未报告的异常 java.text.ParseException;必须被捕获或声明为抛出。”

在线Date date = inputFormat.parse(inputText);

我在 TextMate 上运行的代码:

public class test
    public static void main(String arg[]) 
        String inputText = "Tue May 22 14:52:00 GMT 2012";
        SimpleDateFormat inputFormat = new SimpleDateFormat(
            "EEE MMM dd HH:mm:ss 'GMT' yyyy", Locale.US);
        inputFormat.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
        SimpleDateFormat out = new SimpleDateFormat("MMM dd, yyyy h:mm a");
        Date date = inputFormat.parse(inputText);
        String output = out.format(date);
       System.out.println(output);
    

【问题讨论】:

顶部的示例文本是 21 日,这是星期一而不是星期二。与示例代码不同。 【参考方案1】:

您为 解析 提供的格式字符串与您实际获得的文本格式不对应。你需要先解析,然后格式化。看起来像你想要的:

SimpleDateFormat inputFormat = new SimpleDateFormat(
    "EEE MMM dd HH:mm:ss 'GMT' yyyy", Locale.US);
inputFormat.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));

SimpleDateFormat outputFormat = new SimpleDateFormat("MMM dd, yyyy h:mm a");
// Adjust locale and zone appropriately

Date date = inputFormat.parse(inputText);
String outputText = outputFormat.format(date);

编辑:这是一个简短但完整的程序形式的相同代码,带有您的示例输入:

import java.util.*;
import java.text.*;

public class Test 
    public static void main(String[] args) throws ParseException 
        String inputText = "Tue May 21 14:32:00 GMT 2012";
        SimpleDateFormat inputFormat = new SimpleDateFormat
            ("EEE MMM dd HH:mm:ss 'GMT' yyyy", Locale.US);
        inputFormat.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));

        SimpleDateFormat outputFormat =
            new SimpleDateFormat("MMM dd, yyyy h:mm a");
        // Adjust locale and zone appropriately
        Date date = inputFormat.parse(inputText);
        String outputText = outputFormat.format(date);
        System.out.println(outputText);
    

你能编译和运行那个确切的代码吗?

【讨论】:

我试过了,但是 Date date = inputFormat.parse(inputText);仍然抛出我上面提到的异常:( @user1066956:请张贴当时涉及的exact字符串 - 因为我使用了你在问题中给我的字符串,这很好。 "Tue May 21 14:32:00 GMT 2012" 是我使用的确切字符串。我在 TextMate 中运行了以下代码,得到了上面提到的错误。 @user1066956:我在答案中编辑了一个简短但完整的程序。你能在你的桌面上运行那个确切的代码吗?当它失败时,是在 android 中运行它还是在 Java 中运行它? 顺便说一句,如果我们不知道时区(例如,有时字符串与 America/Los_Angeles 一起出现),我们应该用什么来替换“GMT”?我们应该放 zzzz 吗?【参考方案2】:

您用来解析的格式化程序必须定义为您期望的格式。这是一个适用于您提供的值的示例,但是您可能需要根据某些极端情况对输入的作用进行更改:

String date = "Tue May 21 14:32:00 GMT 2012";
DateFormat inputFormat = new SimpleDateFormat("EE MMM dd HH:mm:ss zz yyy");
Date d = inputFormat.parse(date);
DateFormat outputFormat = new SimpleDateFormat("MMM dd, yyy h:mm a zz");
System.out.println(outputFormat.format(d));

【讨论】:

【参考方案3】:

SimpleDateFormat.parse 方法抛出解析异常。

你得到的例外是告诉你这个......

异常是“未报告的异常java.text.ParseException;必须被捕获或声明为抛出。

用 try-catch 换行进行解析,你应该是金色的..

Date d=null;
try
    d = inputFormat.parse(date);
catch(ParseException e)
   // handle the error here....

R

【讨论】:

【参考方案4】:

您正在使用麻烦的旧日期时间类,现在已被 java.time 类取代。

输入数据错误

您的第一个示例字符串不正确,因为 21 日是星期一而不是星期二。第二个带有 22nd 的示例字符串是正确的,并在下面的示例代码中使用。

使用 java.time

避免将这种格式用于日期时间值的文本表示。特别是,切勿使用这种格式中出现的 3-4 个字母缩写,例如 ESTIST,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。指定proper time zone name。在这种特殊情况下,java.time 能够将 GMT 转换为 UTC,但其他值可能会失败。

String input = "Tue May 22 14:52:00 GMT 2012";
DateTimeFormatter f = DateTimeFormatter.ofPattern ( "EEE MMM dd HH:mm:ss z uuuu" ).withLocale ( Locale.US );
ZonedDateTime zdt = ZonedDateTime.parse ( input , f );

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

转储到控制台。 toString 方法生成标准ISO 8601 格式的字符串,通过在括号中附加区域名称来扩展。当您需要将日期时间值序列化为文本时,这些标准格式是更好的选择。

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

zdt: 2012-05-22T14:52Z[GMT]

生成字符串

您可以生成一个字符串来以您想要的任何格式表示此值。通常最好让 java.time 使用 LocaleDateTimeFormatter 自动本地化。

您所需的格式对日期部分使用中等长度的样式,而对时间部分使用短长度的样式。幸运的是,DateTimeFormatter 允许您分别本地化每个部分,如此处所示,我们传递了一对 FormatStyle 对象。

Locale l = Locale.US;  // Or Locale.CANADA_FRENCH, or Locale.ITALY, etc.
DateTimeFormatter fOutput = DateTimeFormatter.ofLocalizedDateTime ( FormatStyle.MEDIUM , FormatStyle.SHORT ).withLocale ( l );
String output = zdt.format ( fOutput );

转储到控制台。

System.out.println ( "zdt: " + zdt + " | output: " + output );

zdt: 2012-05-22T14:52Z[GMT] |输出:2012 年 5 月 22 日下午 2:52

关于java.time

java.time 框架内置于 Java 8 及更高版本中。这些类取代了旧的麻烦的日期时间类,例如 java.util.Date.Calendarjava.text.SimpleDateFormat

Joda-Time 项目现在位于maintenance mode,建议迁移到 java.time。

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

大部分 java.time 功能在ThreeTen-Backport 中向后移植到Java 6 和7,并进一步适应ThreeTenABP 中的Android(参见How to use…)。

ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuarter 等等。

【讨论】:

以上是关于Java/Android - 将 GMT 时间字符串转换为本地时间的主要内容,如果未能解决你的问题,请参考以下文章

如何将 GMT 时间转换为字符串时间

如何将字符串转换为gmt时间

将带有 GMT 的字符串转换为日期时间格式 - php [重复]

Spark:考虑夏令时将 GMT 时间戳转换为东部时间

datetime 将 GMT 附加到字符串的末尾?

雪花 GMT 字符串到日期转换