在当前时间基础上添加 30 分钟

Ola*_*ide 2 java java-time localdatetime

我已经编写了下面的代码,但如果当前日期时间是2022-07-03 09:48:05.448并且我添加30 分钟,我的响应将返回2022-07-03 09:79:05.448

但分钟永远不可能是 79,它应该改为小时......

public static String getExpiryDate(int additionalMinutesToCurrentMinute) {
    LocalDateTime now = LocalDateTime.now();
    int year = now.getYear();
    int month = now.getMonthValue();
    int day = now.getDayOfMonth();
    int hour = now.getHour();
    int minute = now.getMinute() + additionalMinutesToCurrentMinute;
    int second = now.getSecond();
    int millis = now.get(ChronoField.MILLI_OF_SECOND); // Note: no direct getter available.

    String expiryDateAndTime = String.format("%d-%02d-%02d %02d:%02d:%02d.%03d", year, month, day, hour, minute, second, millis);
    return expiryDateAndTime;
}
Run Code Online (Sandbox Code Playgroud)

Zab*_*uza 5

解释

您的代码无法按预期工作的原因是因为您在“数学”中根本没有涉及 javas Date/Time API。

您用简单的 int 算术添加分钟

int minute = now.getMinute() + additionalMinutesToCurrentMinute;
Run Code Online (Sandbox Code Playgroud)

然后使用纯字符串格式

String.format("%d-%02d-%02d %02d:%02d:%02d.%03d", year, month, day, hour, minute, second, millis);
Run Code Online (Sandbox Code Playgroud)

这个链中没有任何东西是“聪明的”并且知道日期/时间细节。


解决方案

您必须使用日期/时间 API 来进行数学计算,这样它就会变得聪明并正确地调整时间。幸运的是,已经有一种方法LocalDateTime可以满足您的要求:

LocalDateTime expirationTime = LocalDateTime.now().plusMinutes(30);
Run Code Online (Sandbox Code Playgroud)

这几乎就是您所需要的。

对于格式化部分,可以使用默认表示形式:

return expirationTime.toString();
Run Code Online (Sandbox Code Playgroud)

或使用DateTimeFormatter

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy MM dd HH:mm:ss.AAA");
Run Code Online (Sandbox Code Playgroud)

进而

return expirationTime.format(formatter);
Run Code Online (Sandbox Code Playgroud)

笔记

立即的

您实际上使用了错误的过期时间类型。使用LocalDateTime将导致您的应用程序在某些情况下失败。例如,如果您的计算机跨越国家/地区移动,或者您的政府决定更改其时区。或者当 DST 到来时(夏令时与冬令时)或添加闰秒等等......

正确的类型是Instant,它代表时间线上的单个时刻,而不解释时钟时间或日历日期。

API是一样的,所以你可以用同样的方式使用它。

也就是说,您的方法也应该返回Instant而不是String. 尽可能长时间地保留巧妙的日期/时间类型,不要使用像字符串这样低级别和原始的类型。

int minute = now.getMinute() + additionalMinutesToCurrentMinute;
Run Code Online (Sandbox Code Playgroud)

设计

int additionalMinutes从设计角度来说,如果该方法甚至不采用单位,那就更好了。否则,用户很难阅读调用站点:

String.format("%d-%02d-%02d %02d:%02d:%02d.%03d", year, month, day, hour, minute, second, millis);
Run Code Online (Sandbox Code Playgroud)

有了这个单位,它会更容易阅读并且更难误解

LocalDateTime expirationTime = LocalDateTime.now().plusMinutes(30);
Run Code Online (Sandbox Code Playgroud)

在这一点上,人们可能会说这种方法现在有点过时了。