English 中文(简体)
Java/Android - 将格林尼T时间字符串转换为本地时间
原标题:Java/Android - Convert a GMT time string to local time

OK, 所以我有一个字符串, 说“ 5月 21 日 14: 32: 00 GMT 2012 ” 我想将这个字符串转换为本地时间, 格式为 2012 年 5 月 21 日、 2012 2: 32 下午 。 我尝试了 SlaimDateFormat (“ MM dd, yyyyy hh: mm a ” 。 parse (), 但是它抛出了一个例外 。 那么我该怎么做?

例外是“未报告的例外java.text.

Date date 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);
    }
}
最佳回答

您为 paring 提供的格式字符串与您实际得到的文本格式不匹配。 您需要先分析, 然后格式化。 看起来您想要 :

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));

方法简单DateFormat.parse 抛出一个分析例外 。

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

例外是“未报告的例外 java. text. assetexpendion; “ 强度” 必须被捕获或宣布丢弃 。

折行 进行切换 与试捕, 你应该是金的。

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

R R

您正在使用麻烦的旧的约会时间课程 现在由java.time课程取代。

Wrong input data

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

Using java.time

避免对日期- 时间值的文字表达使用这种格式 。 特别是, 永远不要使用以这种格式看到的3-4个字母缩写, 如 EST IST , 因为它们不是真正的时区, 没有标准化, 甚至不是独一无二 (!) 。 请指定一个 < a href=" "https:// en.wikipedia. org/wiki/List_of_tz_ zones_ by_ name" rel= "nofolfollown noreferrer" > > a proccount time name 。 在此特定情况下, java.time 可以将这种缩写为 < code> GMT 翻译为 < a href=" https:// en.wikipedia.org/ wiki/ Coordandardd_ Universal_Time" rel= " rel=" "Noferreferr > > > > > > > > UTC < 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 );

调放到控制台 。 to String 方法产生一个字符串, 标准为 < a href=" https://en.wikipedia.org/wiki/ISO_ 861, rel="nofollow noreferrer" > ISO 8601 格式, 扩展后附加括号中区的名称。 这些标准格式对于您需要将日期- 时间值序列到文本时来说, 是一个更好的选择 。

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

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

Generate String

您可以在任何您想要的格式中生成一个字符串来代表此值 。 一般来说, 最好让 java. time 自动本地化, 使用 < a href="https://docs. oracle.com/javase/8/ docs/ api/java/ util/ locale. html" rel= "nofollown noreferrrr"\\ code > dateTimeFormatter 和 < a href=" https://docs. oracle. com/javase/8/ java/time/ format/ DateTime Formatter. html" rel=" noforerrr"\code > DateTime Formatter 。

您想要的格式对日期部分使用中长样式, 但对时间段则使用短时样式。 幸运的是, < code> DateTimeFormatter 允许您将每个部分分别定位, 从这里可以看到, 我们通过一对 < href= > https://docs. oracle.com/javase/8/docs/ api/java/time/ format/ FormatStyle. html" rel=" nofolverrer"\\code > 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-22-22T14:52Z[GMT] | output: May 22, 2012 2:52 PM

About java.time

http://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html" rel=“不跟随无悔者”>java.time 框架建在Java 8 及以后。这些班级取代旧的麻烦时代班,如 java.util.Date , .Calendar , & amp; java.text.SuproDateFormat

"http://www.joda.org/joda-time/" rel="no follown noreferrer" >Joda-Time 项目,现载于https://en.wikipedia.org/wiki/Maintenance_mode" rel="nofollown noreferrer" > 维护模式 ,建议移民到java.time。

更多信息,请见Oracle Toutor 。并搜索Stack overflow, 查找许多实例和解释。

大部分java.time功能都重新移植到 Java 6 & amp; 7 的“href=”http://www. 33enten.org/ threetenbp/” rel=“notfolle noreferr” >TreeTen-Backport ,并进一步改编为“a href=”https://en.wikipedia.org/wiki/Android_(操作_System)” rel=“nofollow noreferr”>>Aroid in(见 如何使用 < )。

< a href=>""http://www. threeten.org/ threeten-extra/" rel="nofollow noreferrer" > ThreeTen-Extra project 扩展 java.time 并增加 java.time 。 此项目是未来可能添加 java.time 的证明依据。 您可以在此找到一些有用的分类, 如 < code > Interval 、 < code > yearWeek 、 < code > yearQuarter 等, < code > 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
        }
    }
}

我创建了三种超载方法,即 < strong > changeFormat(...) ,并有以下参数;

  1. dateTime (String -> date or time or dateTime)
  2. fromFormat (String/Int -> Current format of dateTime) - optional (i.e. if not provided default will be used)
  3. toFormat (String/Int -> New format for dateTime) - optional (i.e. if not provided default will be used)
  4. convertInTimeZone (Enum -> Convert in specified TimeZone)
  5. needOnlyTime (Boolean -> Will return only converted Time if true else converted dateTime

希望这将来能帮上忙





相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...

热门标签