subtract/add "zone diff time" from/to java 中的 LocalDateTime 最有效的方法是什么 8

What is the most efficient way to subtract/add the "zone diff time" from/to the LocalDateTime in java 8

我的客户坐在其他区域。在 UI 上,可以通过 DateRange(开始和结束日期)进行搜索。 客户端以字符串形式发送开始和结束日期。例如 -> startDate = "DD/MM/YYYY", endDate = "DD/MM/YYYY"。 服务器将日期转换为 searchStartDate = "DD/MM/YYYY 00:00:01"searchEndDate = "DD/MM/YYYY 23:59:59"。但是在数据库中搜索之前,我需要在 searchStartDatesearchEndDate 中添加 "zone time difference"。 不同的客户坐在不同的区域。我们如何使用 java 8 个 API add/subtract 区域差异时间?

例如 - 我的服务器在 UTC 中是 运行。客户坐在 IST 中。在搜索数据库之前,我将从 searchStartDatesearchEndDate 中减去 5H:30M。

我有什么 - LocalDateTime searchStartDate and searchEndDate。我想要什么 searchStartDate = searchStartDate.plus(<UtcIstTimeZoneDiff>).

编辑 - 服务器知道每个客户端的时区。

没有什么可做的,因为您已经以 UTC 格式存储了所有 date/time 条目,并且您知道客户的时区。您需要做的就是转换 UTC date/time to/from 客户端的时区。为此使用 ZonedDateTime.withZoneSameInstant()

Returns a copy of this date-time with a different time-zone, retaining the instant. This method changes the time-zone and retains the instant. This normally results in a change to the local date-time.

下面是一些从 UTC 转换为 IST 的示例代码:

public class Main {

    public static void main(String[] args) {

        // Get some arbitrary UTC value for the search start date (regardless of caller's time zone).
        // Note that the zone ID for UTC is "Z".
        ZonedDateTime utcSearchStartDate = ZonedDateTime.now(ZoneOffset.UTC);

        // Convert the UTC date/time to the target time zone.
        ZoneId clientZone = Main.getClientZoneId();
        ZonedDateTime adjustedSearchStartDate = utcSearchStartDate.withZoneSameInstant(clientZone);

        System.out.println("Current date/time for " + utcSearchStartDate.getZone().getId() +  " = " + utcSearchStartDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss")));
        System.out.println("Current date/time for " + adjustedSearchStartDate.getZone().getId() +  " = " + adjustedSearchStartDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss")));
    }

    // Your logic to get the actual ZoneID of the client goes in this method.
    static ZoneId getClientZoneId() {

        return ZoneId.of("Asia/Kolkata"); // For example...
    }
}

运行 该代码的输出如下所示,其中 IST 的 date/time 已调整 +5:30:

Current date/time for Z = 2018-02-21 06:09:19
Current date/time for Asia/Kolkata = 2018-02-21 11:39:19
    DateTimeFormatter searchDateFormatter = DateTimeFormatter.ofPattern("dd/MM/uuuu");
    ZoneId clientZone = ZoneId.of("Asia/Colombo");
    String startDate = "29/01/2018";
    String endDate = "04/02/2018";

    Instant searchStartTime = LocalDate.parse(startDate, searchDateFormatter)
            .atStartOfDay(clientZone)
            .toInstant();
    Instant searchEndTime = LocalDate.parse(endDate, searchDateFormatter)
            .plusDays(1)
            .atStartOfDay(clientZone)
            .toInstant();

    System.out.println("" + searchStartTime + " inclusive to " 
                        + searchEndTime + " exclusive");

此示例打印

2018-01-28T18:30:00Z inclusive to 2018-02-04T18:30:00Z exclusive

使用half-open间隔:与其试图决定一天中的最后一个时钟小时并考虑是否要在秒上保留多少位小数,不如这样将搜索结束时间设置为第二天的第一刻,然后仅检索该时间之前严格的记录。

我给你的开始和结束时间是 Instant 秒。大多数 JDBC 驱动程序都乐于使用它们,我认为这是一个优势,因为它们固有地代表时间轴上的点,这正是您需要它们的原因。如果您的搜索确实需要 LocalDateTime,可以通过以下方式获取:

    LocalDateTime searchStartTime = LocalDate.parse(startDate, searchDateFormatter)
            .atStartOfDay(clientZone)
            .toOffsetDateTime()
            .withOffsetSameInstant(ZoneOffset.UTC)
            .toLocalDateTime();

搜索结束时间情况类似。