如何仅更改 Java 中 Date 对象的时间而保留日期信息不变
How to change just the time of the Date object in Java leaving the date information intact
我有一个 Date 变量,可以说是 deliveryDate。它以这种格式保存在 MonngoDB 中。
ISODate("2020-10-07T03:10:00Z")
现在我想更改交货日期的时间属性。但它必须基于一些 String 来完成,它告诉要设置什么时间。例如 String time = "7:20 AM" [这个时间是马来西亚吉隆坡]。那么结果应该是这样的:
deliveryDate = ISODate("2020-10-07T11:20:00Z")
一些一般说明:7:20 星期一上午,在马来西亚吉隆坡联邦直辖区吉隆坡,11:20 星期日下午,协调世界时 (UTC)。
现在给出字符串时间和日期交货日期。我怎样才能获得所有情况下的上述结果?
我期待的是:
public static Date adjustTimeOfDay(Date deliveryDate, String timeOfDay) {
// Adjust the time of the day of deliveryDate on the basis of timeOfDay
// Keep the offset and zone same while adjusting
return deliveryDate
}
您可以使用兼容性方法 java.util.Date.toInstant()
,操纵 Instant
的时间,这会创建一个不同的 Instant
,然后通过以下方式转换回 Date
Date.from(Instant instant)
.
这是一个操作示例方法:
public static Instant adjustTimeOfDay(Instant instant, String timeOfDay) {
// convert the instant to an offset-aware datetime object
OffsetDateTime deliveryOdt = OffsetDateTime.ofInstant(instant, ZoneOffset.UTC);
/*
* provide a formatter that parses a time-of-day String.
* PLEASE NOT that this formatter is not very lenient,
* the String must be of the pattern "hh:mm a"
*/
DateTimeFormatter dtf = new DateTimeFormatterBuilder().appendPattern("hh")
.appendLiteral(':')
.appendPattern("mm")
.appendLiteral(' ')
.appendPattern("a")
.parseCaseInsensitive()
.toFormatter();
// parse that String to a LocalTime
LocalTime localTime = LocalTime.parse(timeOfDay, dtf);
/*
* create a new OffsetDateTime
* adding the new LocalTime to the old LocalDate at UTC
*/
OffsetDateTime adjustedOdt = OffsetDateTime.of(deliveryOdt.toLocalDate(),
localTime,
ZoneOffset.UTC);
return adjustedOdt.toInstant();
}
我在 main
中这样使用:
public static void main(String[] args) {
/*
* instead of creating a Date,
* I directly use Instant here and parse your example String,
* so just use your deliveryDate.toInstant()
*/
String input = "2020-10-07T03:10:00Z";
Instant instant = Instant.parse(input);
// then take a time of day to be set
String timeOfDayUpdate = "07:20 AM";
Instant adjusted = adjustTimeOfDay(instant, timeOfDayUpdate);
System.out.println(input + " ==> " + OffsetDateTime.ofInstant(adjusted, ZoneOffset.UTC)
.format(DateTimeFormatter.ISO_INSTANT));
}
创建了以下输出:
2020-10-07T03:10:00Z ==> 2020-10-07T07:20:00Z
编辑
您可以将该方法重写为
public static Date adjustTimeOfDay(Date date, String timeOfDay) {
// convert the date to an instant and the instant to an offset-aware datetime object
OffsetDateTime deliveryOdt = OffsetDateTime.ofInstant(date.toInstant(), ZoneOffset.UTC);
// provide a formatter that parses a time-of-day String
DateTimeFormatter dtf = new DateTimeFormatterBuilder().appendPattern("hh")
.appendLiteral(':')
.appendPattern("mm")
.appendLiteral(' ')
.appendPattern("a")
.parseCaseInsensitive()
.toFormatter();
// parse that String to a LocalTime
LocalTime localTime = LocalTime.parse(timeOfDay, dtf);
/*
* create a new OffsetDateTime
* adding the new LocalTime to the old LocalDate at UTC
*/
OffsetDateTime adjustedOdt = OffsetDateTime.of(deliveryOdt.toLocalDate(),
localTime,
ZoneOffset.UTC);
// return a Date from the Instant you get out of the OffsetDateTime
return Date.from(adjustedOdt.toInstant());
}
传递 Date
并返回一个。
如果我正确理解了您的要求,您正在寻找类似的东西:
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
// Test
System.out.println(adjustTimeOfDay("2020-10-07T03:10:00Z", "7:20 AM"));
}
public static String adjustTimeOfDay(String deliveryDate, String timeOfDay) {
// Define the formatter to parse time like 7:20 AM
DateTimeFormatter timeFormatter = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("h:m a")
.toFormatter(Locale.ENGLISH);
return ZonedDateTime.parse(deliveryDate)
.toLocalDate()
.atTime(LocalTime.parse(timeOfDay, timeFormatter))
.atZone(ZoneId.of("Asia/Kuala_Lumpur"))
.withZoneSameInstant(ZoneOffset.UTC)
.format(DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss")) + 'Z';
}
}
输出:
2020-10-06T23:20:00Z
我建议您使用 HH
来表示 24 小时格式的时间。但是,如果你想通过忽略 AM/PM
来获得时间字符串,你可以在上面给出的模式中使用 hh
然后你会得到 2020-10-06T11:20:00Z
(但我不推荐它,因为它任何人都会感到困惑)。
我有一个 Date 变量,可以说是 deliveryDate。它以这种格式保存在 MonngoDB 中。
ISODate("2020-10-07T03:10:00Z")
现在我想更改交货日期的时间属性。但它必须基于一些 String 来完成,它告诉要设置什么时间。例如 String time = "7:20 AM" [这个时间是马来西亚吉隆坡]。那么结果应该是这样的:
deliveryDate = ISODate("2020-10-07T11:20:00Z")
一些一般说明:7:20 星期一上午,在马来西亚吉隆坡联邦直辖区吉隆坡,11:20 星期日下午,协调世界时 (UTC)。
现在给出字符串时间和日期交货日期。我怎样才能获得所有情况下的上述结果?
我期待的是:
public static Date adjustTimeOfDay(Date deliveryDate, String timeOfDay) {
// Adjust the time of the day of deliveryDate on the basis of timeOfDay
// Keep the offset and zone same while adjusting
return deliveryDate
}
您可以使用兼容性方法 java.util.Date.toInstant()
,操纵 Instant
的时间,这会创建一个不同的 Instant
,然后通过以下方式转换回 Date
Date.from(Instant instant)
.
这是一个操作示例方法:
public static Instant adjustTimeOfDay(Instant instant, String timeOfDay) {
// convert the instant to an offset-aware datetime object
OffsetDateTime deliveryOdt = OffsetDateTime.ofInstant(instant, ZoneOffset.UTC);
/*
* provide a formatter that parses a time-of-day String.
* PLEASE NOT that this formatter is not very lenient,
* the String must be of the pattern "hh:mm a"
*/
DateTimeFormatter dtf = new DateTimeFormatterBuilder().appendPattern("hh")
.appendLiteral(':')
.appendPattern("mm")
.appendLiteral(' ')
.appendPattern("a")
.parseCaseInsensitive()
.toFormatter();
// parse that String to a LocalTime
LocalTime localTime = LocalTime.parse(timeOfDay, dtf);
/*
* create a new OffsetDateTime
* adding the new LocalTime to the old LocalDate at UTC
*/
OffsetDateTime adjustedOdt = OffsetDateTime.of(deliveryOdt.toLocalDate(),
localTime,
ZoneOffset.UTC);
return adjustedOdt.toInstant();
}
我在 main
中这样使用:
public static void main(String[] args) {
/*
* instead of creating a Date,
* I directly use Instant here and parse your example String,
* so just use your deliveryDate.toInstant()
*/
String input = "2020-10-07T03:10:00Z";
Instant instant = Instant.parse(input);
// then take a time of day to be set
String timeOfDayUpdate = "07:20 AM";
Instant adjusted = adjustTimeOfDay(instant, timeOfDayUpdate);
System.out.println(input + " ==> " + OffsetDateTime.ofInstant(adjusted, ZoneOffset.UTC)
.format(DateTimeFormatter.ISO_INSTANT));
}
创建了以下输出:
2020-10-07T03:10:00Z ==> 2020-10-07T07:20:00Z
编辑
您可以将该方法重写为
public static Date adjustTimeOfDay(Date date, String timeOfDay) {
// convert the date to an instant and the instant to an offset-aware datetime object
OffsetDateTime deliveryOdt = OffsetDateTime.ofInstant(date.toInstant(), ZoneOffset.UTC);
// provide a formatter that parses a time-of-day String
DateTimeFormatter dtf = new DateTimeFormatterBuilder().appendPattern("hh")
.appendLiteral(':')
.appendPattern("mm")
.appendLiteral(' ')
.appendPattern("a")
.parseCaseInsensitive()
.toFormatter();
// parse that String to a LocalTime
LocalTime localTime = LocalTime.parse(timeOfDay, dtf);
/*
* create a new OffsetDateTime
* adding the new LocalTime to the old LocalDate at UTC
*/
OffsetDateTime adjustedOdt = OffsetDateTime.of(deliveryOdt.toLocalDate(),
localTime,
ZoneOffset.UTC);
// return a Date from the Instant you get out of the OffsetDateTime
return Date.from(adjustedOdt.toInstant());
}
传递 Date
并返回一个。
如果我正确理解了您的要求,您正在寻找类似的东西:
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
// Test
System.out.println(adjustTimeOfDay("2020-10-07T03:10:00Z", "7:20 AM"));
}
public static String adjustTimeOfDay(String deliveryDate, String timeOfDay) {
// Define the formatter to parse time like 7:20 AM
DateTimeFormatter timeFormatter = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("h:m a")
.toFormatter(Locale.ENGLISH);
return ZonedDateTime.parse(deliveryDate)
.toLocalDate()
.atTime(LocalTime.parse(timeOfDay, timeFormatter))
.atZone(ZoneId.of("Asia/Kuala_Lumpur"))
.withZoneSameInstant(ZoneOffset.UTC)
.format(DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss")) + 'Z';
}
}
输出:
2020-10-06T23:20:00Z
我建议您使用 HH
来表示 24 小时格式的时间。但是,如果你想通过忽略 AM/PM
来获得时间字符串,你可以在上面给出的模式中使用 hh
然后你会得到 2020-10-06T11:20:00Z
(但我不推荐它,因为它任何人都会感到困惑)。