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);
1000
的L
后缀表示这是一个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
对象开始,则转换为Instant
。 Instant
类表示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.Date
, Calendar
和SimpleDateFormat
。
Joda-Time项目现在处于维护模式 ,build议迁移到java.time。
要了解更多信息,请参阅Oracle教程 。 并search堆栈溢出了很多例子和解释。 规范是JSR 310 。
从何处获取java.time类?
- Java SE 8和SE 9及更高版本
- 内置。
- 带有捆绑实现的标准Java API的一部分。
- Java 9增加了一些小function和修复。
- Java SE 6和SE 7
- 大部分的java.timefunction都被移植到了ThreeTen-Backport中的 Java 6&7中。
- Android的
- ThreeTenABP项目专门针对Android,采用了ThreeTen-Backport (上文提到)。
- 请参阅如何使用…。
ThreeTen-Extra项目将java.time扩展到其他类。 这个项目是未来可能增加java.time的一个试验场。 你可能会在这里find一些有用的类,比如Interval
, YearWeek
, YearQuarter
等等 。
就像是
movie.setStopDate(movie.getStartDate() + movie.getDurationInMinutes()* 60000);