英文:
How to change just the time of the Date object in Java leaving the date information intact
问题
public static Date adjustTimeOfDay(Date deliveryDate, String timeOfDay) {
// 将交付日期的时间部分进行调整,基于给定的时间字符串 timeOfDay
// 在调整时保持偏移量和时区不变
return adjustedDeliveryDate; // 返回调整后的交付日期
}
英文:
I have a Date variable lets say deliveryDate. It's saved in MonngoDB in this format.
ISODate("2020-10-07T03:10:00Z")
Now I want to change the time property of delivery Date. But it has to be done based on some String which tells what time to be set. for eg String time = "7:20 AM" [ this time is based of Kuala Lumpur, Malaysia ]. Then the result should be something like :
deliveryDate = ISODate("2020-10-07T11:20:00Z")
Some general note : 7:20 AM Monday, in Kuala Lumpur, Federal Territory of Kuala Lumpur, Malaysia is 11:20 PM Sunday, Coordinated Universal Time (UTC).
Now given the String time and Date delivery Date. How can I obtain the results above for all cases ?
The thing that I am expecting is :
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
}
答案1
得分: 2
你可以使用兼容性方法 java.util.Date.toInstant()
,操作该 Instant
的时间部分,从而创建一个不同的 Instant
,然后通过 Date.from(Instant instant)
转换回一个 Date
。
下面是一个用于操作的示例方法:
public static Instant adjustTimeOfDay(Instant instant, String timeOfDay) {
// 将 instant 转换为带有偏移的日期时间对象
OffsetDateTime deliveryOdt = OffsetDateTime.ofInstant(instant, ZoneOffset.UTC);
/*
* 提供一个解析时间字符串的格式化器。
* 请注意,这个格式化器不是非常宽松的,
* 字符串必须符合 "hh:mm a" 模式。
*/
DateTimeFormatter dtf = new DateTimeFormatterBuilder().appendPattern("hh")
.appendLiteral(':')
.appendPattern("mm")
.appendLiteral(' ')
.appendPattern("a")
.parseCaseInsensitive()
.toFormatter();
// 将该字符串解析为 LocalTime
LocalTime localTime = LocalTime.parse(timeOfDay, dtf);
/*
* 创建一个新的 OffsetDateTime,
* 将新的 LocalTime 添加到旧的 UTC 日期上
*/
OffsetDateTime adjustedOdt = OffsetDateTime.of(deliveryOdt.toLocalDate(),
localTime,
ZoneOffset.UTC);
return adjustedOdt.toInstant();
}
我在类似以下的 main
方法中使用了它:
public static void main(String[] args) {
/*
* 不是创建 Date,
* 我直接在这里使用 Instant 并解析了你的示例字符串,
* 所以只需使用你的 deliveryDate.toInstant()
*/
String input = "2020-10-07T03:10:00Z";
Instant instant = Instant.parse(input);
// 然后取一个要设置的时间
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
EDIT
你可以将该方法重写为:
public static Date adjustTimeOfDay(Date date, String timeOfDay) {
// 将日期转换为 instant,然后将 instant 转换为带有偏移的日期时间对象
OffsetDateTime deliveryOdt = OffsetDateTime.ofInstant(date.toInstant(), ZoneOffset.UTC);
// 提供一个解析时间字符串的格式化器
DateTimeFormatter dtf = new DateTimeFormatterBuilder().appendPattern("hh")
.appendLiteral(':')
.appendPattern("mm")
.appendLiteral(' ')
.appendPattern("a")
.parseCaseInsensitive()
.toFormatter();
// 将该字符串解析为 LocalTime
LocalTime localTime = LocalTime.parse(timeOfDay, dtf);
/*
* 创建一个新的 OffsetDateTime,
* 将新的 LocalTime 添加到旧的 UTC 日期上
*/
OffsetDateTime adjustedOdt = OffsetDateTime.of(deliveryOdt.toLocalDate(),
localTime,
ZoneOffset.UTC);
// 从 OffsetDateTime 获取的 Instant 返回一个 Date
return Date.from(adjustedOdt.toInstant());
}
传入一个 Date
,并返回一个日期。
英文:
You can use the compatibility method java.util.Date.toInstant()
, manipulate the time of day of that Instant
which creates a different Instant
and then convert back to a Date
by Date.from(Instant instant)
.
Here's an example method for the manipulation:
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();
}
I used in a main
like this:
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));
}
which created the following output:
2020-10-07T03:10:00Z ==> 2020-10-07T07:20:00Z
EDIT
You can rewrite that method to
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());
}
passing a Date
and getting one returned.
答案2
得分: 2
如果我正确理解您的要求,您正在寻找类似以下的内容:
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) {
// 测试
System.out.println(adjustTimeOfDay("2020-10-07T03:10:00Z", "7:20 AM"));
}
public static String adjustTimeOfDay(String deliveryDate, String timeOfDay) {
// 定义解析时间为 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
我建议您在24小时制中使用`HH`。然而,如果您想要忽略`AM/PM`并获得时间字符串,您可以在上述模式中使用`hh`,然后您将获得`2020-10-06T11:20:00Z`(但我不建议这样做,因为这会令人困惑)。
英文:
If I understood your requirement correctly, you are looking for something like:
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';
}
}
Output:
2020-10-06T23:20:00Z
I recommend you use use HH
for a time in 24-hour format. However, if you want to get a time string by ignoring AM/PM
, you can use hh
in the pattern given above and then you will get 2020-10-06T11:20:00Z
(but I do not recommend it as it will be confusing for anyone).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论