我有一个班级,我用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;
}
答案 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}}时区)。