将GMT日期转换为Java字符串,将结尾处的-6转换为CST

时间:2015-02-19 18:05:01

标签: java android date timezone simpledateformat

我有一个字符串,其中包含gmt日期值,最后是-06:00。将此转换为CST的最佳方法是什么?我查看了其他问题,但最后没有人在-06:00回答我的问题。

这是我尝试的,它出错为java.text.ParseException:Unparseable date:“2015-02-19T11:50:09.5953377-06:00”

 private DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss:SSSSSSS'Z'");
    private DateFormat gmtFormat = new SimpleDateFormat();
    private TimeZone cstTime = TimeZone.getTimeZone("CST");

    gmtFormat.setTimeZone(cstTime);
    sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
    try {
                System.out.println("cst start date is " + gmtFormat.format("2015-02-19T11:50:09.5953377-06:00"));
            } catch (ParseException e) {
                e.printStackTrace();
            }

2 个答案:

答案 0 :(得分:0)

之前我遇到过类似的问题,我实际上是以3种不同的iso格式获取日期,而且非常沮丧...这不是很好,但它可能有助于指出你朝着正确的方向......

我收到信息的3种格式:

private static final String ISO_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
private static final String ISO_FORMAT2 = "yyyy-MM-dd'T'HH:mm:ss'Z'";
private static final String ISO_FORMAT3 = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";

实际上试图解析它们(不必事先弄清楚正确的类型,在所有3个都失败的情况下返回一个新的Date对象,所以因为日期格式化异常而没有崩溃):

public static Date parseIso(String date){
    SimpleDateFormat sdf = new SimpleDateFormat(ISO_FORMAT, Locale.US);
    sdf.setTimeZone(TimeZone.getTimeZone("UTC"));

    try {
        return sdf.parse(date);
    } 
    catch (ParseException e) {
        Log.g(TAG, "Failed 1st date parse with " + ISO_FORMAT + " for " + date);

        sdf = new SimpleDateFormat(ISO_FORMAT2, Locale.US);
        sdf.setTimeZone(TimeZone.getTimeZone("UTC"));

        try {
            return sdf.parse(date);
        } 
        catch (ParseException e2) {
            Log.g(TAG, "Failed 2nd date parse with " + ISO_FORMAT2 + " for " + date);

            sdf = new SimpleDateFormat(ISO_FORMAT3, Locale.US);
            sdf.setTimeZone(TimeZone.getTimeZone("UTC"));

            try {
                return sdf.parse(date);
            } 
            catch (ParseException e3) {
                Log.g(TAG, "Failed 3rd date parse with " + ISO_FORMAT3 + " for " + date);                   
            }
        }
    }
    return new Date();
}

然后将该日期实际转换为本地化日期:

public static String format(long mils, String format){
    return format(getInstance(mils), format);
}

public static String format(Calendar calendar, String format){
    SimpleDateFormat sdf = new SimpleDateFormat(format, Locale.US);
    sdf.setTimeZone(TimeZone.getTimeZone("UTC"));

    return sdf.format(new Date(calendar.getTime().getTime() + TimeZone.getDefault().getOffset(new Date().getTime())));
}

public static Calendar getInstance(long timeInMils){
    Calendar cal = Calendar.getInstance();
    cal.setTimeZone(TimeZone.getTimeZone("UTC"));
    cal.setTimeInMillis(timeInMils);
    return cal;
}

所以现在你基本上可以打电话了

CalendarHelper.format(myDateObject.getTime(), "MMM dd, yyyy");

,它将从您收到的原始UTC日期返回本地化的格式化日期。

同样,不是很漂亮,但我希望这可以指出你在UTC和客户的时区之间进行转换的正确方向。祝你好运〜

PS。我认为ISO_FORMAT_3实际上会帮助你。我想我可能已经开始了解这些信息,但我不是一个聪明的人。

答案 1 :(得分:0)

ISO 8601

您似乎误解了输入字符串2015-02-19T11:50:09.5953377-06:00的含义。您没有" gmt日期值"。

该格式似乎是标准的ISO 8601格式。

  • 中间的T将日期部分与时间部分分开。
  • 末尾的-06:00UTC的偏移量。这意味着"此处显示的日期时间值比UTC"落后六小时。

CST

因此,如果CST表示Central Time Zone(美洲大陆的某些中间部分),那么您无需转换即可执行。时间11点50分的那个字符串意味着在伊利诺伊州,阿肯色州和路易斯安那州的#34;几乎中午。如果添加 6小时到11:50,您将在同一时刻学习UTC(GMT)日期时间:同一天17:50。

避免3-4个字母代码

顺便说一句,避免使用三个或四个字母的时区代码,例如" CST"。这些代码不是标准化的也不是唯一的Many duplicates存在。例如,取CST

  • 中央标准时间(美洲)
  • 中国标准时间
  • 中央标准时间(澳大利亚)
  • 中央夏令时(澳大利亚)
  • 古巴标准时间

而是使用proper time zones。其中大部分是大陆加斜线加上城市/地区。示例:America/ReginaAmerica/MonterreyAmerica/Indiana/Knox

Joda-Time | java.time

java.util.Date / .Calendar类非常麻烦。避免它们。

使用Joda-Time库或java.time中内置的新Java 8包。 java.time包的灵感来自Joda-Time,但是经过重新设计。每个人都有自己的优点和缺点。

Joda-Time和java.time都使用ISO 8601格式作为解析和生成日期时间值的字符串表示的默认值。

由于这个问题确实是重复的,已经发布了数百个这样的问题和答案,我只给出一个简单的例子。

String input = "2015-02-19T11:50:09.5953377-06:00";
DateTimeZone zoneAmerica_Regina = DateTimeZone.forID( "America/Regina" );
DateTime dateTimeAmericaRegina = new DateTime( input, zoneAmerica_Regina ); 
DateTime dateTimeLosAngeles = dateTimeAmericaRegina.withZone( DateTimeZone.forID( "America/Los_Angeles" ) );
DateTime dateTimeUtc = dateTimeAmericaRegina.withZone( DateTimeZone.UTC );

小数秒

您的输入字符串只有很短的一秒。 Joda-Time(如java.util.Date)仅处理millisecond分辨率 - 小数点后三位数。 java.item包处理nanosecond分辨率。有些系统使用microsecond分辨率,例如像Postgres这样的数据库。有些系统遵循整个秒的旧Unix convention