Date对象到Calendar

我有一个类电影,我有一个开始date,持续时间和停止date。 开始和停止date是date对象(私人datestartDate …)(这是一个任务,所以我不能改变这一点)现在我想自动计算stopDate的持续时间(以分钟为单位)startDate。

据我所知,使用Date操作函数的时间已经过时,因此不好的做法,但另一方面,我看不到将date对象转换为日历对象,以便操纵时间并将其重新转换为Date对象。 有没有办法? 如果有什么是最好的做法

你可以做的是创build一个GregorianCalendar的实例,然后将Date设置为开始时间:

 Date date; Calendar myCal = new GregorianCalendar(); myCal.setTime(date); 

但是,另一种方法是根本不使用Date 。 你可以使用这样的方法:

 private Calendar startTime; private long duration; private long startNanos; //Nano-second precision, could be less precise ... this.startTime = Calendar.getInstance(); this.duration = 0; this.startNanos = System.nanoTime(); public void setEndTime() { this.duration = System.nanoTime() - this.startNanos; } public Calendar getStartTime() { return this.startTime; } public long getDuration() { return this.duration; } 

通过这种方式,您可以访问开始时间和从开始到停止的持续时间。 精度取决于你当然。

 Calendar tCalendar = Calendar.getInstance(); tCalendar.setTime(date); 

date是一个java.util.Date对象。 您也可以使用Calendar.getInstance()以获取Calendar实例(效率更高)。

Calendar.setTime()

查看API方法的签名和描述通常是非常有用的,而不仅仅是它们的名字:) – 即使在Java标准API中,名称有时也可能是误导性的。

您不需要为此转换为Calendar ,您可以使用getTime() / setTime()来代替。

getTime() :返回自此date对象表示的1970年1月1日00:00:00 GMT以来的毫秒数。

setTime(long time) :设置此Date对象以表示1970年1月1日00:00:00 GMT之后的时间毫秒数。 )

一秒钟有1000毫秒,一分钟有60秒。 只要做math。

  Date now = new Date(); Date oneMinuteInFuture = new Date(now.getTime() + 1000L * 60); System.out.println(now); System.out.println(oneMinuteInFuture); 

1000L后缀表示这是一个long文字; 这些计算通常很容易溢出。

TL;博士

 Instant stop = myUtilDateStart.toInstant() .plus( Duration.ofMinutes( x ) ) ; 

java.time

其他答案是正确的,特别是由Borgwardt答案 。 但那些答案使用过时的遗留类。

与Java捆绑在一起的最初的date – 时间类已经被java.time类所取代。 在java.timetypes中执行您的业务逻辑。 仅在需要使用尚未更新以处理java.timetypes的旧代码的情况下才转换为旧types。

如果您的Calendar实际上是一个GregorianCalendar您可以转换为ZonedDateTime 。 查找添加到旧类中的新方法,以便于转换为java.timetypes。

 if( myUtilCalendar instanceof GregorianCalendar ) { GregorianCalendar gregCal = (GregorianCalendar) myUtilCalendar; // Downcasting from the interface to the concrete class. ZonedDateTime zdt = gregCal.toZonedDateTime(); // Create `ZonedDateTime` with same time zone info found in the `GregorianCalendar` end if 

如果您的Calendar不是Gregorian ,请致电toInstant以获取Instant对象。 Instant类表示UTC时间轴上的时间,分辨率为纳秒 。

 Instant instant = myCal.toInstant(); 

同样,如果从java.util.Date对象开始,则转换为InstantInstant类表示UTC时间轴上的一个时刻,分辨率为纳秒 (最多九(9)位小数)。

 Instant instant = myUtilDate.toInstant(); 

应用时区来获取ZonedDateTime

 ZoneId z = ZoneId.of( "America/Montreal" ); ZonedDateTime zdt = instant.atZone( z ); 

要获取java.util.Date对象,请通过Instant

 java.util.Date utilDate = java.util.Date.from( zdt.toInstant() ); 

有关遗留date时间types和java.time之间转换的更多讨论,以及一个漂亮的图表,请参阅我对另一个问题的回答 。

Duration

将时间跨度表示为Duration对象。 您input的持续时间是问题中提到的几分钟。

 Duration d = Duration.ofMinutes( yourMinutesGoHere ); 

您可以添加到开始确定停止。

 Instant stop = startInstant.plus( d ); 

关于java.time

java.time框架内置于Java 8及更高版本中。 这些类取代了麻烦的旧的遗留date时间类,如java.util.DateCalendarSimpleDateFormat

Joda-Time项目现在处于维护模式 ,build议迁移到java.time。

要了解更多信息,请参阅Oracle教程 。 并search堆栈溢出了很多例子和解释。 规范是JSR 310 。

从何处获取java.time类?

  • Java SE 8SE 9及更高版本
    • 内置。
    • 带有捆绑实现的标准Java API的一部分。
    • Java 9增加了一些小function和修复。
  • Java SE 6SE 7
    • 大部分的java.timefunction都被移植到了ThreeTen-Backport中的 Java 6&7中。
  • Android的
    • ThreeTenABP项目专门针对Android,采用了ThreeTen-Backport (上文提到)。
    • 请参阅如何使用…。

ThreeTen-Extra项目将java.time扩展到其他类。 这个项目是未来可能增加java.time的一个试验场。 你可能会在这里find一些有用的类,比如IntervalYearWeekYearQuarter 等等 。

就像是

 movie.setStopDate(movie.getStartDate() + movie.getDurationInMinutes()* 60000);