Java Calendar对象,分别设置日期和时间

Java Calendar object, setting date and time separately

创建日历对象并设置 date/time 使用 SimpleDateFormat 解析字符串时,是否可以在两行单独的代码中设置日期和时间?例如,在我的 SQLite 数据库中,日期 (mm-dd-yyyy) 与时间 (hh:mm) 存储在不同的列中。做下面这样的事情是否合乎犹太洁食:

Calendar cal = Calendar.getInstance();
SimpleDateFormat sdfDate = new SimpleDateFormat("MM-dd-yyyy");
SimpleDateFormat sdfTime = new SimpleDateFormat("hh:mm zzz");
cal.setTime(sdfDate.parse(DATE));
cal.setTime(sdfTime.parse(TIME));

第二 cal.setTime 行是否会将日历对象的日期部分重置为现在并仅更改时间?

是的。

setTime() 设置时间,不管日期是否包含时间值 (00:00:00) 或没有日期值 (01.01.1970)。

Calendar cal = Calendar.getInstance();
SimpleDateFormat sdfDate = new SimpleDateFormat("MM-dd-yyyy hh:mm zzz");
cal.setTime(sdfDate.parse(DATE+ " " + TIME));

应该适合你。

tl;博士

ZonedDateTime.of( 
    LocalDate.parse( "12-23-2015" , DateTimeFormatter.ofPattern( "MM-dd-yyyy") ) ,
    LocalTime.parse( "21:43" ) , 
    ZoneId.of( "Pacific/Auckland" )
)
.toString()

2015-12-23T21:43+13:00[Pacific/Auckland]

详情

Jan 的 是正确的。

java.time

或者,您可以使用新的日期时间框架,java.time。

java.time framework built into Java 8 and later supplants the troublesome old java.util.Date/.Calendar classes. The new classes are inspired by the highly successful Joda-Time framework, intended as its successor, similar in concept but re-architected. Defined by JSR 310. Extended by the ThreeTen-Extra project. See the Tutorial.

如果您的输入缺少 offset-from-UTC, then we could treat the date and the time-of-day separately. The new classes include LocalDate to represent a date-only value without a time-of-day, and LocalTime 来表示没有日期的仅时间值。然后你可以将它们组合起来并调整到它们想要的时区。

DateTimeFormatter formatterDate = DateTimeFormatter.ofPattern( "MM-dd-yyyy");
LocalDate localDate = LocalDate.parse( "12-23-2015" , formatterDate );
LocalTime localTime = LocalTime.parse( "21:43" );
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.of( localDate , localTime , zoneId );

但是您的时间字符串 确实 包含与 UTC 的偏移量。所以我们应该采用与 Jan 的回答相同的方法,连接这对字符串然后解析。

String input = "12-23-2015" + " " + "21:43-05:00" ;
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "MM-dd-yyyy HH:mmxxx");
ZonedDateTime zdt = ZonedDateTime.parse( input , formatter );

ISO 8601

顺便说一下,将来在将日期、时间或日期时间序列化为字符串时,就像您在 SQLite 数据库中所做的那样,我强烈建议使用标准 ISO 8601 格式:YYYY-MM-DDHH:MMYYYY-MM-DDTHH:MM:SS.S±00:00。例如,2007-12-03T10:15:30+01:00。这些格式是标准化的,易于人类阅读和辨别,也易于计算机解析而不会产生歧义。

java.time 框架默认解析并生成这些格式的字符串。此外,java.time 通过在方括号中附加时区名称来扩展 ISO 8601。例如,2007-12-03T10:15:30+01:00[Europe/Paris].


关于java.time

java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

Joda-Time project, now in maintenance mode, advises migration to the java.time 类.

要了解更多信息,请参阅 Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310

对于 JDBC driver complying with JDBC 4.2 或更高版本,您可以直接与数据库交换 java.time 对象。不需要字符串或 java.sql.* 类.

java.time类在哪里获取?

  • Java SE 8, Java SE 9,及以后
    • 内置。
    • 标准 Java API 的一部分,带有捆绑实施。
    • Java 9 添加了一些小功能和修复。
  • Java SE 6 and Java SE 7
  • Android
    • Android java.time 类.
    • 捆绑实施的更高版本
    • 对于较早的 Android,ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See

ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.