【问题标题】:Java/Android - Convert a GMT time string to local timeJava/Android - 将 GMT 时间字符串转换为本地时间
【发布时间】: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 日,这是星期一而不是星期二。与示例代码不同。

标签: java android datetime simpledateformat


【解决方案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 个字母缩写,例如 EST 或 IST,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。指定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 使用 Locale 和 DateTimeFormatter 自动本地化。

      您所需的格式对日期部分使用中等长度的样式,而对时间部分使用短长度的样式。幸运的是,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、.Calendar 和 java.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 的试验场。您可以在这里找到一些有用的类,例如Interval、YearWeek、YearQuarter 等等。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-04-07
        • 2023-03-26
        • 2013-10-29
        • 2019-01-02
        • 2010-09-15
        相关资源
        最近更新 更多