将yyyy-MM-dd'T'HH:mm:ss.mmm'Z'转换为正常的"HH:mm a"格式

Ros*_*ose -2 java datetime android timestamp simpledateformat

我在应用程序中显示日期时遇到问题.

我得到时间戳为:

2017-08-02T06:05:30.000Z

但就此而言,实际时间是:

2017:08:02 11:35 AM

但在使用我的代码转换后,它将时间显示为:

上午6:00

如何显示当前时间?

我的代码如下:

private static SimpleDateFormat timestampformat = 
                   new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.mmm'Z'");

private static SimpleDateFormat sdftimeformat = new SimpleDateFormat("HH:mm a");

private static SimpleDateFormat getSdftimeformat() {
    return sdftimeformat;
}
public static String timeStampConvertToTime(String time) {
    Date date1 = null;

    try {
        date1 = timestampformat.parse(time);
    } catch (ParseException e) {
        e.printStackTrace();
    }
    String formattedTime = getSdftimeformat().format(date1);
    return formattedTime;
}
Run Code Online (Sandbox Code Playgroud)

小智 9

第一件事是你正在使用mm:ss.mmm你的格式.根据SimpleDateFormatjavadoc,m表示分钟,因此您必须将其更改为mm:ss.SSS因为S表示毫秒.

另一个细节是,Z最终是UTC时区指示符,它不能被忽略(至少它不应该被忽略).您必须使用相应的模式,即X:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX");
Date date = sdf.parse("2017-08-02T06:05:30.000Z");
Run Code Online (Sandbox Code Playgroud)

PS:所述X图案是在Java 7中引入了如果您使用的Java <= 6,唯一的选择是治疗Z为文字(难看的解决方法,我承认),并设置为UTC由分析器中使用的时区:

// treat "Z" as literal
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
// use UTC as timezone
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = sdf.parse("2017-08-02T06:05:30.000Z");
Run Code Online (Sandbox Code Playgroud)

这样,日期将具有与UTC中的06:05相对应的值.要将时间格式化为您的时区,您必须使用SimpleDateFormat具有相应时区的另一个时区:

// output format: hour:minute AM/PM
SimpleDateFormat outputFormat = new SimpleDateFormat("hh:mm a", Locale.ENGLISH);
// assuming a timezone in India
outputFormat.setTimeZone(TimeZone.getTimeZone("Asia/Kolkata"));
System.out.println(outputFormat.format(date));
Run Code Online (Sandbox Code Playgroud)

输出将是:

上午11:35

如果您没有设置时区,它将使用系统的默认值.但是即使在运行时也可以在不事先通知的情况下更改默认值,因此最好明确设置上面的特定时区.

我还习惯java.util.Locale将语言设置为英语,因为某些语言环境可以为AM/PM设置不同的符号.如果你没有指定一个,它将使用系统默认值,并且不保证符号是你需要的符号(一些语言环境使用"am/pm"或其他不同的格式,所以最好使用一个明确的语言环境).


Java新的日期/时间API

老班(Date,CalendarSimpleDateFormat)有很多问题设计问题,他们正在被新的API取代.

如果您使用的是Java 8,请考虑使用新的java.time API.与旧的API相比,它更容易,更少出错并且更不容易出错.

如果您使用Java <= 7,则可以使用ThreeTen Backport,这是Java 8的新日期/时间类的一个很好的后端.对于Android,还有ThreeTenABP(更多关于如何在这里使用它).

以下代码适用于两者.唯一的区别是包名称(在Java 8中java.time和在ThreeTen Backport(或Android的ThreeTenABP)中org.threeten.bp),但类和方法名称是相同的.

要解析输入,您可以使用ZonedDateTime完全支持时区的类,它可以非常轻松地转换到其他区域.然后使用a DateTimeFormatter来格式化输出:

// parse the input
ZonedDateTime parsed = ZonedDateTime.parse("2017-08-02T06:05:30.000Z");
// convert to another timezone
ZonedDateTime z = parsed.withZoneSameInstant(ZoneId.of("Asia/Kolkata"));
// format output
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("hh:mm a", Locale.ENGLISH);
System.out.println(fmt.format(z));
Run Code Online (Sandbox Code Playgroud)

输出将是:

上午11:35

如果输入总是Z在最后,你还可以使用Instant类:

// parse the input
Instant instant = Instant.parse("2017-08-02T06:05:30.000Z");
// convert to a timezone
ZonedDateTime z = instant.atZone(ZoneId.of("Asia/Kolkata"));
Run Code Online (Sandbox Code Playgroud)

请注意,我用hh了几个小时:这将使用1到12的值格式化(这是有道理的,因为我也使用AM/PM指示符).如果您想要0到23之间的值,请使用HH- 请查看javadoc以获取更多详细信息.

另请注意,API使用IANA时区名称(始终采用格式Region/City,如Asia/KolkataEurope/Berlin).避免使用3个字母的缩写(如CSTIST),因为它们不明确且不标准.

您可以通过调用获取可用时区列表(并选择最适合您系统的时区)ZoneId.getAvailableZoneIds().

您也可以使用系统的默认时区ZoneId.systemDefault(),但即使在运行时也可以在不事先通知的情况下进行更改,因此最好明确使用特定的时区.