将UTC日期转换为其他时区

时间:2011-05-22 15:07:18

标签: android datetime timezone

我正在使用此方法将UTC时间转换为另一个时区:

SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date parsed = format.parse("2011-03-01 15:10:37");
TimeZone tz = TimeZone.getTimeZone("America/Chicago");
format.setTimeZone(tz);

String result = format.format(parsed);

因此输入为2011-03-01 15:10:37,但此输出(结果值)为2011-03-01 05:40:37。虽然似乎没有,但根据this link,它应该是2011-03-01 09:10:37

我做错了什么?

6 个答案:

答案 0 :(得分:68)

事实证明代码几乎是正确的,我没有考虑的是,在最初解析String以获取Date对象时,它使用默认系统TimeZone ,所以源日期不是我预期的UTC。

诀窍是在将日期解析为UTC时设置时区,然后将其设置为目标TimeZone。像这样:

SimpleDateFormat sourceFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sourceFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Date parsed = sourceFormat.parse("2011-03-01 15:10:37"); // => Date is in UTC now

TimeZone tz = TimeZone.getTimeZone("America/Chicago");
SimpleDateFormat destFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
destFormat.setTimeZone(tz);

String result = destFormat.format(parsed);

答案 1 :(得分:14)

将格式为“2011-06-23T15:11:32”的日期字符串转换为时区。

 private String getDate(String dateString) {
    SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
    formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
    Date value = null;
    try {
        value = formatter.parse(dateString);
    } catch (ParseException e) {
        e.printStackTrace();
    }
    SimpleDateFormat dateFormatter = new SimpleDateFormat("dd/MM/yyyy hh:mmaa");
    dateFormatter.setTimeZone(TimeZone.getDefault());
    String dt = dateFormatter.format(value);

    return dt;
}

答案 2 :(得分:3)

以下代码可以很好地将日期从一个tz更改为另一个。它也考虑了DayLightSaving。

public static Calendar changeTimezoneOfDate(Date date, TimeZone fromTZ, TimeZone toTZ) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    long millis = calendar.getTimeInMillis();
    long fromOffset = fromTZ.getOffset(millis);
    long toOffset = toTZ.getOffset(millis);
    long convertedTime = millis - (fromOffset - toOffset);
    Calendar c = Calendar.getInstance();
    c.setTimeInMillis(convertedTime);
    return c;
}

答案 3 :(得分:2)

您需要考虑夏令时。我这样做是通过计算偏移量(从UTC)以毫秒为单位。这样的事情应该有效。

int currentOffsetFromUTC = tz.getRawOffset() + (tz.inDaylightTime(parsed) ? tz.getDSTSavings() : 0);
String result = format.format(parsed.getTime() + currentOffsetFromUTC);

inDayLightTime(...)方法返回一个布尔值,必须传递一个Date对象,以便它决定该'date'是否在DST期间代表一个。

答案 4 :(得分:2)

您可以根据自己的要求解析日期格式和时区。 试试这段代码我希望它对你有所帮助。

private String getFormattedDate(String OurDate) {
    try {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); // According to your Server TimeStamp
        formatter.setTimeZone(TimeZone.getTimeZone("UTC")); //your Server Time Zone
        Date value = formatter.parse(OurDate); // Parse your date

        SimpleDateFormat dateFormatter = new SimpleDateFormat("MM-dd-yyyy"); //this format changeable according to your choice
        dateFormatter.setTimeZone(TimeZone.getDefault());
        OurDate = dateFormatter.format(value);

    } catch (Exception e) {
        OurDate = "00-00-0000 00:00";

    }
    return OurDate;
}

答案 5 :(得分:1)

java.time

考虑使用现代Java日期和时间API java.time进行日期和时间工作。

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");
    ZoneId targetZone = ZoneId.of("America/Chicago");
    
    LocalDateTime parsed = LocalDateTime.parse("2011-03-01 15:10:37", formatter);
    ZonedDateTime converted = parsed.atOffset(ZoneOffset.UTC).atZoneSameInstant(targetZone);

    String result = converted.format(formatter);
    System.out.println(result);

预期的输出是

2011-03-01 09:10:37

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

java.time在较新和较旧的Android设备上均可正常运行。它只需要至少 Java 6

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

链接