根据与 UTC(joda 间隔)不同的时区处理 Java 夏令时

Handle Java daylight saving based on different time zone from UTC (joda Interval)

我需要 return List<Interval> intervals 根据我从用户那里得到的输入。除非范围包括夏令时,否则一切正常。如果发生这种情况,我得到的响应在特定日期之后会有点混乱(在此示例中为美国东部标准时间 11 月 1 日)。

由于我的数据在数据库中存储为 UTC,因此我使用的是 UTC(请求是 UTC,我的响应也是 UTC),但是,在浏览器中,时间被转换为本地时区。在后端,我可以访问用户时区。
现在的问题是如何将响应时间转换为包括夏令时的 UTC。

public List<Interval> buildIntervals(BinInterval binSize) {
    final DateTime intervalStart = binSize.getInterval().getStart();
    final DateTime intervalEnd = binSize.getInterval().getEnd();

    final DateTimeZone tz = getCurrentUserTimezone();
    List<Interval> intervals = new ArrayList<>();

    MutableDateTime currentBinStart = new MutableDateTime(intervalStart);
    MutableDateTime currentBinEnd = new MutableDateTime(intervalStart.plus(binSize.getPeriod()));

    while (currentBinEnd.isBefore(intervalEnd)) {

    intervals.add(makeInterval(currentBinStart, currentBinEnd));

        currentBinStart = new MutableDateTime(currentBinStart.toDateTime().plus(binSize.getPeriod()));
        currentBinEnd = new MutableDateTime(currentBinEnd.toDateTime().plus(binSize.getPeriod()));

    }
} 

private static Interval makeInterval(BaseDateTime start, BaseDateTime end) {
    return new Interval(start.toDateTime().withZone(DateTimeZone.UTC),
                        end.toDateTime().withZone(DateTimeZone.UTC));
} 

以下是错误的回复示例:

第 17 行的正确版本应该是:endDate: "2015-11-02T05:00:00.000z"

从第 17 行开始,结束时间应为 +5。
从第 18 行开始,开始时间也应该是 +5,但由于某种原因,它在夏令时前后没有以正确的方式转换时间。

如果我 select 11 月 1 日之后的范围,它会完美地工作并将其全部转换为 +5。

我当地的时区是美国东部时间。

我假设您需要为发生夏令时的特殊情况创建不同大小的间隔。

我建议获取开始时间和结束时间的偏移量,并根据这些值决定是否需要更改结束日期。

public static void main(String[] args) {
    DateTimeZone EDT = DateTimeZone.forID("America/Toronto");
    DateTime start = new DateTime(2016, 5, 15, 4, 0, DateTimeZone.UTC);
    DateTime end = start.plusDays(2);

    int offset1 = (int) TimeUnit.MILLISECONDS.toMinutes(EDT.getOffset(start.getMillis()));
    int offset2  = (int) TimeUnit.MILLISECONDS.toMinutes(EDT.getOffset(end.getMillis()));
    if (offset1 != offset2) {
        end = end.plusMinutes(offset1 - offset2);
    }

    System.out.println(new Interval(start.toDateTime().withZone(EDT),
            end.toDateTime().withZone(EDT)));

}