我在Java 8 Maven项目中使用Google Calendar API。我想从日期值中减去15分钟。但我找不到任何解决方案。我不想使用第三方图书馆,这不应该那么难。我也不想更改为Calendar对象或Localdatetime等。
我无法从Date,DateTime和EventDateTime对象的值中减去。
DateTime来自com.google.api.client.util.DateTime
只想减去15分钟。时间值是白天。 (医生任命)
谢谢。
例如:
appdate = 2/19/2019
startTime = 04:15 pm
SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy hh:mm a", Locale.US);
formatter.setTimeZone(TimeZone.getTimeZone("America/New_York"));
String dateInString = appDate + " " + startTime;
Date date = formatter.parse(dateInString);
DateTime startDateTime = new DateTime(date, TimeZone.getTimeZone("America/New_York"));
EventDateTime start = new EventDateTime().setDateTime(startDateTime).setTimeZone("America/New_York");
event.setStart(start);
答案 0 :(得分:0)
String inputDate = "2/19/2019" ;
String inputTime = "04:15 pm".toUpperCase() ; // AM/PM is properly localized in US as all uppercase.
DateTimeFormatter fDate = DateTimeFormatter.ofPattern( "M/d/uuuu" ) ;
LocalDate ld = LocalDate.parse( inputDate , fDate ) ;
System.out.println( "ld.toString(): " + ld ) ;
DateTimeFormatter fTime = DateTimeFormatter.ofPattern( "hh:mm a" , Locale.US ) ; // Specify `Locale` to determine the human language and cultural norms to use in translating the AM/PM portion.
LocalTime lt = LocalTime.parse( inputTime , fTime ) ;
System.out.println( "lt.toString(): " + lt ) ;
ZoneId z = ZoneId.of( "America/New_York" ) ;
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;
System.out.println( "zdt.toString(): " + zdt ) ;
ZonedDateTime zdtEarlier = zdt.minusMinutes( 15 ) ;
System.out.println( "zdtEarlier.toString(): " + zdtEarlier ) ;
Instant instant = zdtEarlier.toInstant() ; // Adjust from zoned to UTC. Same moment, different wall-clock time.
System.out.println( "instant.toString(): " + instant ) ;
java.util.Date d = java.util.Date.from( instant ) ;
System.out.println( "d.toString(): " + d + "\nCAUTION: The `Date::toString` method lies, applying the JVM’s current default tim ezone while generating the text from a value that is actually in UTC." ) ; ;
请参阅此code run live at IdeOne.com。
ld.toString():2019-02-19
lt.toString():16:15
zdt.toString():2019-02-19T16:15-05:00 [美国/纽约]
zdtEarlier.toString():2019-02-19T16:00-05:00 [美国/纽约]
instant.toString():2019-02-19T21:00:00Z
d.toString():2019年2月19日星期二21:00:00 GMT
注意:
Date::toString
方法的作用在于,应用JVM当前的默认时区,同时根据实际UTC值生成文本。
要理解这些价值……想象一下,在工作时间下午4点结束时,坐在纽约办公室的爱丽丝给鲍勃的手机打电话。鲍勃坐在Iceland雷克雅未克的家里。爱丽丝(Alice)和鲍勃(Bob)都保持通话记录,因此他们各自同时瞥了一眼各自墙上的时钟。每个人在什么时间记录在自己的通话记录中?
提示:
如果这是您要调整的未来约会,则应从LocalTime
值而不是ZonedDateTime
中减去四分之一小时。
我们暂时保留将来的约会不是。如果政客要更改时钟(更改该日期所在时区中使用的UTC偏移量),则对于约会,我们希望通过不同的时刻(时间轴上的不同点)保持相同的挂钟时间。 / p>
LocalTime ltEarlier = lt.minusMinutes( 15 ) ;
…
ZonedDateTime zdtEarlier = ZonedDateTime.of( ld , ltEarlier , z ) ;
您正在使用错误的错误类。 java.util.Date
代表UTC的时刻。因此,除非您预约的是雷克雅未克冰岛,否则您将无法使用该课程。
您正在使用非常麻烦的有缺陷的日期时间类,其中充斥着糟糕的设计选择和缺陷。通过采用JSR 310, java.time 类完全取代了它们。
LocalDate ld = LocalDate.of( 2019 , Month.FEBRUARY , 19 ) ;
LocalTime lt = LocalTime.of( 16 , 15 ) ;
ZoneId z = ZoneId.of( "America/New_York" ) ;
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;
减去15分钟。按照不可变对象模式,您将获得一个新的ZonedDateTime
对象,而不是更改原始对象。
ZonedDateTime zdtEarlier = zdt.minusMinutes( 15 ) ;
或者如上所述,对于将来的约会:
ZonedDateTime zdtEarlier = ZonedDateTime.of( ld , lt.minusMinutes( 15 ) , z ) ;
如果您必须具有java.util.Date
才能与尚未更新为 java.time 的旧代码进行互操作,请进行转换。您可以通过调用添加到旧类中的新方法来在旧类与现代类之间来回转换。
要转换为java.util.Date
,您需要一个Instant
,现代类表示UTC的时刻。您只需从我们的Instant
中提取一个ZonedDateTime
,就可以将时区调整为UTC。同一时刻,时间轴上的同一点,不同的时钟时间。
Instant instant = zdtEarlier.toInstant() ;
Date d = java.util.Date.from( instant ) ;
请注意,java.util.Date
的许多缺陷中有一个很糟糕的设计决策,那就是让Date::toString()
方法在生成表示此刻的文本时动态地将时区应用于UTC值。换句话说, Date::toString
方法位于,将UTC值错误地表示为已分区。本来是好主意,但不幸的是,这给无数试图学习日期时间处理的程序员带来了无尽的痛苦和困惑。避免上此类课的众多原因之一。
如果从字符串输入开始,则进行解析。尽可能将标准ISO 8601格式用于此类输入。否则,您需要指定一个格式匹配的格式。
DateTimeFormatter fDate = DateTimeFormatter.ofPattern( "M/d/uuuu" ) ;
LocalDate ld = LocalDate.parse( "2/19/2019" , fDate ) ;
您一天中的输入内容违反了美国的文化规范。 am
/ pm
应该全部大写,AM
/ PM
。因此,在解析之前请致电String::toUpperCase()
。
DateTimeFormatter fTime = DateTimeFormatter.ofPattern( “hh:mm a" , Locale.US ) ;
LocalTime lt = LocalTime.parse( "4:15 pm".toUpperCase() , fTime ) ;
java.time框架已内置在Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和SimpleDateFormat
。
目前位于Joda-Time的maintenance mode项目建议迁移到java.time类。
要了解更多信息,请参见Oracle Tutorial。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310。
您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*
类。
在哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展了java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。您可能会在这里找到一些有用的类,例如Interval
,YearWeek
,YearQuarter
和more。