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 个字母缩写,例如 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
等等。
【讨论】:
以上是关于Java/Android - 将 GMT 时间字符串转换为本地时间的主要内容,如果未能解决你的问题,请参考以下文章