UTC偏移到本地时间转换

时间:2018-03-08 05:44:55

标签: java datetime timezone jodatime

我有一个班级,我用utcoffset millis将日期格式化为当地时间。

我处于一种奇怪的情况,其中日期总是格式化为UTC而不是当地时间。

我从以下方法中获取的时间戳或日期始终为UTC。我应该如何使用UTC offset millis转换为本地时间。

public Object[] format(ReportContext context) {
        Map<String, String> queryParams = context.getQueryParams();

        DateRange dateRange = queryParams.containsKey(DATE_RANGE) ?
                DateRange.getDateRange(queryParams.get(DATE_RANGE)) :
                DateRange.LAST_24_HOURS;
        String messageKey = MESSAGE_KEY + dateRange.getRestParam();
        Object args[];
        Locale locale = context.getLocale();
        DateTimeZone dateTimeZone = DateTimeZone.forOffsetMillis(19800000);
        DateTimeFormatter dateFormatterWithZone = dateFormatter.withZone(dateTimeZone);

        LocalDateTime startDateTime = parseParam(queryParams, START_TIME);
        String startDate = dateFormatterWithZone.print(startDateTime);

        if (dateRange == DateRange.TODAY || dateRange == DateRange.YESTERDAY) {
            args = new Object[]{startDate};
        } else {
            LocalDateTime endDateTime = parseParam(queryParams, END_TIME);

            if (dateRange == DateRange.LAST_24_HOURS) {
                DateTimeFormatter timeFormatterWithZone = timeFormatter.withZone(dateTimeZone);
                String startTime = timeFormatterWithZone.print(startDateTime);
                String endDate = dateFormatterWithZone.print(endDateTime);
                String endTime = timeFormatterWithZone.print(endDateTime);
                args = new Object[] {startDate, startTime, endDate, endTime};
                System.out.println("UTC time" + startDate + " " + startTime + " " + endDate + " " + endTime);
            } else if (dateRange == DateRange.LAST_HOUR) {
                DateTimeFormatter timeFormatterWithZone = timeFormatter.withZone(dateTimeZone);
                String startTime = timeFormatterWithZone.print(startDateTime);
                String endTime = timeFormatterWithZone.print(endDateTime);
                args = new Object[] {startDate, startTime, endTime};
            } else {
                String endDate = dateFormatterWithZone.print(endDateTime);
                args = new Object[] {startDate, endDate};
            }
        }

        return ars;
    }

1 个答案:

答案 0 :(得分:2)

LocalDateTime表示日期(日,月和年)和时间(小时,分钟,秒,毫秒),没有任何时区概念。如果我创造了这个:

// March 8th 2018, at 10 AM (no timezone)
LocalDateTime startDateTime = new LocalDateTime(2018, 3, 8, 10, 0);

startDateTime变量代表“2018年3月8日,上午10点”,但没有时区,所以可能是2018年3月8日,上午10点(或者没有特别的地方) ,没关系)。如果格式化此日期,则在格式化程序中设置的时区无关紧要,它不会影响输出,因为LocalDateTime没有时区概念且不会受其影响。

如果要在特定位置(地理区域,AKA为时区)中表示此日期和时间,则必须提供DateTimeZone(表示时区的对象)并转换{{1} }到LocalDateTime

DateTime

请注意,我使用名称DateTimeZone zone = DateTimeZone.forID("Asia/Kolkata"); DateTime dt = startDateTime.toDateTime(zone); 而不是固定数值作为偏移量。这是因为时区可以随时改变 - 政治家可能决定改变国家的偏差“因为原因” - 所以使用适当的时区名称(和keeping your timezone data updated)会使你的代码更可靠,面向未来。

此代码使Asia/Kolkata等于“2018年3月8日,亚洲/加尔各答时区上午10点”。现在它不再是本地日期/时间:它代表特定位置的日期和时间(由时区表示)。

时区之间的转换

如果您的结果有误,您必须知道dt所指的时区,然后转换为您想要的时区。

示例:如果我知道LocalDateTime是UTC,我想将其转换为“Asia / Kolkata”,我该怎么办?

首先,我将LocalDateTime转换为UTC:

LocalDateTime

然后,我将此// LocalDateTime is in UTC DateTime utcDateTime = startDateTime.toDateTime(DateTimeZone.UTC); 转换为我想要的时区:

utcDateTime

DateTimeZone zone = DateTimeZone.forID("Asia/Kolkata"); // convert utcDateTime to Asia/Kolkata timezone DateTime kolkataDateTime = utcDateTime.withZone(zone); 将相当于“2018年3月8日,亚洲/加尔各答下午3:30”(因为UTC上午10点相当于{{ 1}}时区)。