[英]Java/Android - Convert a GMT time string to local time
好的,所以我有一个字符串,比如“2012 年 5 月 21 日星期二 14:32:00 GMT”我想将这个字符串转换为当地时间,格式为 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);
}
}
您提供的用于解析的格式字符串与您实际获得的文本格式不符。 您需要先解析,然后格式化。 它看起来像你想要的:
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);
}
}
你能编译并运行那些确切的代码吗?
您用于解析的格式化程序必须定义为您期望的格式。 下面是一个适用于您提供的值的示例,但您可能需要根据某些边缘情况对输入的作用进行更改:
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));
SimpleDateFormat.parse方法抛出一个解析异常。
你得到的例外是告诉你这个......
例外情况是“未报告的异常java.text.ParseException; 必须被捕获或声明被抛出”。
使用try-catch包装进行解析的行,你应该是金色的..
Date d=null;
try{
d = inputFormat.parse(date);
catch(ParseException e){
// handle the error here....
}
[R
您正在使用现在由java.time类取代的麻烦的旧日期时间类。
您的第一个示例字符串不正确,因为21日是星期一而不是星期二。 带有22nd的第二个示例字符串是正确的,并在下面的示例代码中使用。
避免将此类格式用于日期时间值的文本表示。 特别是,永远不要使用这种格式中看到的3-4字母缩写,例如EST
或IST
,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。 指定正确的时区名称 。 在这种特殊情况下,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格式的String,通过在括号中附加区域名称进行扩展。 当您需要将日期时间值序列化为文本时,这些标准格式是更好的选择。
System.out.println ( "zdt: " + zdt );
zdt:2012-05-22T14:52Z [GMT]
您可以生成一个String,以您希望的任何格式表示此值。 通常最好让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 8及更高版本中。 这些类取代了旧的麻烦的日期时间类,如java.util.Date
, .Calendar
和java.text.SimpleDateFormat
。
现在处于维护模式的Joda-Time项目建议迁移到java.time。
要了解更多信息,请参阅Oracle教程 。 并搜索Stack Overflow以获取许多示例和解释。
大部分的java.time功能后移植到Java 6和7 ThreeTen,反向移植 ,并进一步适应的Android在ThreeTenABP (见如何使用...... )。
ThreeTen-Extra项目使用其他类扩展了java.time。 该项目是未来可能添加到java.time的试验场。 您可以在这里找到一些有用的课程,如Interval
, YearWeek
, YearQuarter
等。
const val DATE_HYPHEN_FORMAT = "yyyy-MM-dd"
const val DATE_MMM_DD_YYYY_FORMAT = "MMM dd, yyyy"
const val DATE_MMMM_DD_YYYY_FORMAT = "MMMM dd, yyyy"
const val FULL_DAY_NAME_FORMAT = "EEEE"
const val DATE_EEE_DD_MMMM_YYYY_FORMAT = "EEE dd, MMMM yyyy"
const val DATE_EEEE_DD_MMMM_YYYY_FORMAT = "EEEE dd, MMMM yyyy"
const val DATETIME_24_FORMAT = "dd-MM-yyyy'T'HH:mm:ss"
const val DATETIME_24_YMD_FORMAT = "yyyy-MM-dd'T'HH:mm:ss"
const val DATE_WITH_MONTH_NAME_MMM_DY_FORMAT = DateFormat.MEDIUM
const val DATE_WITH_MONTH_FULL_NAME_MMMM_DY_FORMAT = DateFormat.LONG
const val TIME_24H_FORMAT = "HH:mm:ss"
const val TIME_FORMAT_AM_PM = "hh:mm aa"
const val TIME_24H_FORMATWithoutSS = "HH:mm"
enum class TimeZoneTo {
NONE, UTC, LOCAL
}
fun changeFormat(
dateTime: String,
fromFormat: Int = DATE_WITH_MONTH_NAME_MMM_DY_FORMAT,
toFormat: String = DATETIME_24_FORMAT,
convertIn: TimeZoneTo = TimeZoneTo.NONE,
needOnlyTime: Boolean = false
): String {
try {
val parser = DateFormat.getDateInstance(fromFormat)
val finalDateTime = trimDateTime(dateTime)
val date = parser.parse(finalDateTime)
val sdf = SimpleDateFormat(toFormat)
return format(
date = date!!, formatter = sdf, convertIn = convertIn, needOnlyTime = needOnlyTime
)
} catch (e: AssertionError) {
e.printStackTrace()
} catch (e: Exception) {
e.printStackTrace()
}
return dateTime // Return Same DateTime - only iff unable to change format
}
fun changeFormat(
dateTime: String,
fromFormat: String = DATETIME_24_FORMAT,
toFormat: Int = DATE_WITH_MONTH_NAME_MMM_DY_FORMAT,
convertIn: TimeZoneTo = TimeZoneTo.NONE,
needOnlyTime: Boolean = false
): String {
try {
val sfdInput = SimpleDateFormat(fromFormat, Locale.ROOT)
val finalDateTime = trimDateTime(dateTime)
val date: Date = sfdInput.parse(finalDateTime)!!
val outputFormatter = DateFormat.getDateInstance(toFormat)
return format(
date = date,
formatter = outputFormatter,
convertIn = convertIn,
needOnlyTime = needOnlyTime
)
} catch (e: AssertionError) {
e.printStackTrace()
} catch (e: Exception) {
e.printStackTrace()
}
return dateTime // Return Same DateTime - only iff unable to change format
}
fun changeFormat(
dateTime: String,
fromFormat: String = DATETIME_24_FORMAT,
toFormat: String = DATE_HYPHEN_FORMAT,
convertInTimeZone: TimeZoneTo = TimeZoneTo.NONE,
needOnlyTime: Boolean = false
): String {
try {
val sfdInput = SimpleDateFormat(fromFormat, Locale.ROOT)
val finalDateTime = trimDateTime(dateTime)
val date: Date = sfdInput.parse(finalDateTime)!!
val sdfOutput = SimpleDateFormat(toFormat)
return format(
date = date,
formatter = sdfOutput,
convertIn = convertInTimeZone,
needOnlyTime = needOnlyTime
)
} catch (e: AssertionError) {
e.printStackTrace()
} catch (e: Exception) {
e.printStackTrace()
}
return dateTime // Return Same DateTime - only iff unable to change format
}
// Format Given Date as per specified timeZone
private fun format(
date: Date,
formatter: DateFormat,
convertIn: TimeZoneTo,
needOnlyTime: Boolean
): String {
return when (convertIn) {
TimeZoneTo.LOCAL -> {
val zone = TimeZone.getTimeZone(Calendar.getInstance().timeZone.id)
val newDate = Date(date.time + zone.getOffset(date.time))
formatter.timeZone = zone
val result = formatter.format(newDate)
if (needOnlyTime) return result.substringAfter('T')
else result
}
TimeZoneTo.UTC -> {
formatter.timeZone = TimeZone.getTimeZone("UTC")
val result = formatter.format(date)
if (needOnlyTime) return result.substringAfter('T')
else result
}
else -> {
val result = formatter.format(date)
if (needOnlyTime) return result.substringAfter('T')
else result
}
}
}
我创建了 3 个重载方法,即带有以下参数的changeFormat(...) ;
希望这可以帮助将来的人。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.