如何转换日期”格式(包括IST)

时间:2019-04-23 07:38:41

标签: java android

我有一个字符串日期jQuery.each( translations, function( key, value ) { console.log(key + " -> " + translations[key]); $body = jQuery("body"); replaceThis = new RegExp(key, "g"); alert(replaceThis); $body.html($body.html().replace(replaceThis, translations[key])); }); 要转换为日期,但以下格式无法正常工作。

"Tue May 07 15:41:50 IST 2019"

当我尝试使用z或zzz或Z或ZZZ解析IST但在Android中未成功解析时。

3 个答案:

答案 0 :(得分:0)

通常,使用z可以为您提供正确的时区,在此处使用HongKong:

System.out.println(
    new SimpleDateFormat("EEE MMM dd HH:mm:ss yyyy z", Locale.ENGLISH)
        .parse("Tue May 07 15:41:50 2019 HKT")
);
  

CEST 2019年5月7日星期二09:41:50

文档

但是,正如TimeZone中所述,“三字母时区ID”不是唯一的,这就是不应使用它的原因。

  

[...]还支持其他三个字母的时区ID(例如“ PST”,“ CTT”,“ AST”)。 但是,不赞成使用它们,因为同一缩写经常用于多个时区(例如,“ CST”可以是美国的“ Central Standard Time”和“ China Standard Time”),而Java平台只能识别其中之一。

概念证明

我们可以使用此脏代码检查IST代表多个时区,以获取与SimpleDateFormatter支持的每个“ IST”区域的ZoneId相匹配的每个Timezone

String shortZoneID = "IST";
Arrays.stream(
            new SimpleDateFormat().getDateFormatSymbols().getZoneStrings())
            .filter(s -> shortZoneID.equals(s[2]) || shortZoneID.equals(s[4]))
            .map(s -> TimeZone.getTimeZone(s[0]))
            .map(t -> String.format("%-50s %s", t.getDisplayName(), Duration.of(t.getRawOffset(), ChronoUnit.MILLIS)))
            .distinct()
            .forEach(System.out::println)
            ;

输出:

Israel Standard Time                               PT2H  
India Standard Time                                PT5H30M  
Greenwich Mean Time                                PT0S  

解释为什么IST”似乎出现在GMT中。

System.out.println(
    new SimpleDateFormat("EEE MMM dd HH:mm:ss yyyy z", Locale.ENGLISH)
        .parse("Tue May 07 15:41:50 2019 IST")
);
  

2019年5月7日星期二15:41:50

在这种情况下,不确定Java如何确定时区的优先级,采用第一个时区还是基于当前语言环境(我位于GMT + 01:00时区)?
但是即使有这些信息,结果也可能不正确。

解决方案

同时,这是恢复时区的一些正确形式:

使用偏移量

System.out.println(
        new SimpleDateFormat("EEE MMM dd HH:mm:ss yyyy XXX", Locale.ENGLISH)
            .parse("Tue May 07 15:41:50 2019 +05:30"));

使用区域的全名

System.out.println(
        new SimpleDateFormat("EEE MMM dd HH:mm:ss yyyy zzzz", Locale.ENGLISH)
            .parse("Tue May 07 15:41:50 2019 India Standard Time"));

两个输出:

  

2019年5月7日星期二12:11:50

答案 1 :(得分:0)

String dateString = "Tue May 07 15:41:50 IST 2019"  
SimpleDateFormat sdf = new SimpleDateFormat("EE MMM dd HH:mm:ss z yyyy");
Date date = sdf.parse(dateString);
System.out.println(date);

答案 2 :(得分:0)

java.time

我建议您使用 java.time,现代 Java 日期和时间 API,用于您的日期和时间工作。

由于 IST 是不明确的(因为有很多三个字母的时区缩写),您需要在解析包含此缩写的字符串时指定您的首选解释。为了便于演示,我使用了这种方法(它可能不是用于生产的方法):

static ZonedDateTime parseWithPreferredTimeZone(String input, ZoneId preferredZone) {
    DateTimeFormatter parser = new DateTimeFormatterBuilder()
            .appendPattern("EEE MMM dd HH:mm:ss ")
            .appendZoneText(TextStyle.SHORT, Collections.singleton(preferredZone))
            .appendPattern(" yyyy")
            .toFormatter(Locale.ENGLISH);
    return ZonedDateTime.parse(input, parser);
}

现在让我们看看它的实际效果:

    String stringToParse = "Tue May 07 15:41:50 IST 2019";
    
    System.out.println(parseWithPreferredTimeZone(stringToParse,
            ZoneId.of("Atlantic/Reykjavik")));
    System.out.println(parseWithPreferredTimeZone(stringToParse,
            ZoneId.of("Europe/Dublin")));
    System.out.println(parseWithPreferredTimeZone(stringToParse,
            ZoneId.of("Asia/Jerusalem")));
    System.out.println(parseWithPreferredTimeZone(stringToParse,
            ZoneId.of("Asia/Kolkata")));

我的 Java 9 上的输出是:

<块引用>
2019-05-07T15:41:50Z[Atlantic/Reykjavik]
2019-05-07T15:41:50+01:00[Europe/Dublin]
2019-05-07T15:41:50+03:00[Asia/Jerusalem]
2019-05-07T15:41:50+05:30[Asia/Kolkata]

如您所见,您可以获得想要的解释。

问题:java.time 不需要 Android API 级别 26 吗?

java.time 在较旧和较新的 Android 设备上都能很好地工作。它只需要至少 Java 6

  • 在 Java 8 及更高版本以及更新的 Android 设备(从 API 级别 26 开始)中,内置了现代 API。
  • 在非 Android Java 6 和 7 中获得 ThreeTen Backport,现代类的向后移植(ThreeTen for JSR 310;请参阅底部的链接)。
  • 在较旧的 Android 上,使用脱糖或 ThreeTen Backport 的 Android 版本。它被称为 ThreeTenABP。在后一种情况下,请确保使用子包从 org.threeten.bp 导入日期和时间类。

链接