我搜索到这是因为有这么多帖子提出这个问题,但所有答案都是difference In Milliseconds / (24* 1000 * 60 * 60)
,它给出了两个日期之间的24小时数。
但我需要两个日期之间的天数。
即。如果date1
为09/09/13 09:00
且date2
为10/09/13 22:00
,则我需要0
而不是1
,因为date1
和{{ 1}}是连续的天数(即使它们之间的间隔超过24小时)。
注意:我知道删除时间部分并使用date2
方法。我正在寻找更好的解决方案。
更新:应用程序首次在difference In Milliseconds / (24* 1000 * 60 * 60)
星期三使用,然后该应用程序于星期四10/09/13 22:00使用。现在用户已经在周三和周四使用了应用程序,即使有超过24小时的差距。现在,如果我计算两个日期之间的24小时数,则给出一个。因为2个日期之间有一天的差距。我需要它给零,因为用户使用它周三和周四星期三和星期四之间没有天。
希望你理解我的问题。如果你还没有离开它,我试着通过最好的解释。
答案 0 :(得分:1)
这是一个简单的解决方案:
Calendar calendar = Calendar.getInstance();
calendar.setTime(startDate);
while(calendar.getTime().before(endDate))
{
noOfDays++;
calendar.add(Calendar.DAY_OF_MONTH,1);
}
其中startDate和endDate是Date类的实例。
注意:您需要初始化日期对象,以便它们具有相同的时间但只是日期不同。将它们设置为上午12点应该可以解决问题:
date.set(Calendar.HOUR_OF_DAY, 0);
date.set(Calendar.MINUTE, 0);
date.set(Calendar.SECOND, 0);
date.set(Calendar.MILLISECOND, 0);
答案 1 :(得分:1)
import java.util.Date;
import java.util.concurrent.TimeUnit;
import java.text.SimpleDateFormat;
import java.text.ParseException;
public class test {
public static void main(String[] args) throws ParseException {
String dateStart = "09/09/13 09:00";
String dateStop = "10/09/13 22:00";
SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm");
Date date1 = format.parse(dateStart);
Date date2 = format.parse(dateStop);
// calculate difference in milliseconds
long diff = (date2.getTime() - date1.getTime()) - 86400000;
diff = (diff <= 0 ? 0 : diff);
System.out.println(TimeUnit.MILLISECONDS.toDays(diff));
}
}
这将给出2个日期之间的差异。并减去一天(如果它是负数,它将差异设置为0天)。只要dateStop大于dateStart,这将起作用,否则它只会打印0;
答案 2 :(得分:1)
我已经避免使用Joda Time多年了,但是在过去的一周里,我完全使用它来解决这个问题。这非常值得!
在处理普通Java时,很容易引入一些奇怪的日期处理错误 - 例如夏令时变化时会发生什么。 Joda Time已经构建了所有这些例外。
点击此处查看相关问题:
<强>更新强>
从Java 8开始,时间&amp;日期功能已经改进,Joda Time团队建议使用它而不是他们的库。以下是他们在着陆页上所说的内容:
请注意,从Java SE 8开始,系统会要求用户迁移到 java.time(JSR-310) - JDK的核心部分,取代了它 项目
答案 3 :(得分:0)
您可以使用此技巧:如果date1
在date2
之前,您可以将date1
中的小时设置为1
,将date2
设置为0
}。这样,整个时差的小时部分永远不会超过24小时,因此不会影响计算,因此只有几天/几个月/几年才会起作用。
这是代码示例
public static long daysBetween(Date date1, Date date2) {
Calendar c1 = Calendar.getInstance();
c1.setTime(date1);
Calendar c2 = Calendar.getInstance();
c2.setTime(date2);
if (date1.before(date2)) {
c1.set(Calendar.HOUR_OF_DAY, 1);
c2.set(Calendar.HOUR_OF_DAY, 0);
} else {
c2.set(Calendar.HOUR_OF_DAY, 1);
c1.set(Calendar.HOUR_OF_DAY, 0);
}
return (c2.getTimeInMillis() - c1.getTimeInMillis())
/ (24 * 60 * 60 * 1000);
}
//DEMO
public static void main(String[] args) throws Exception {
DateFormat df = new SimpleDateFormat("dd/MM/yy hh:mm");
Date date1 = df.parse("09/09/13 09:00");
Date date2 = df.parse("11/09/13 22:00");
System.out.println(daysBetween(date1, date2));
}
输出:1
对于日期11/09/13 09:00
09/09/13 22:00
,结果将为-1
,因为date1
位于date2
之后
答案 4 :(得分:0)
ChronoUnit.DAYS.between(
earlierInstant.atZone( ZoneId.of( "Africa/Tunis" ) ).toLocalDate() ,
Instant.now().atZone( ZoneId.of( "Africa/Tunis" ) ).toLocalDate()
)
现代方法使用 java.time 类来取代麻烦的旧日期时间类,例如Date
&amp; Calendar
。
如果要计算经过的天数作为日历日期的数量而不是24小时的时间段数,请使用仅限日期的类而不是日期时间类。
LocalDate
类表示没有时间且没有时区的仅限日期的值。
时区对于确定日期至关重要。对于任何给定的时刻,日期在全球范围内因地区而异。例如,在Paris France午夜后的几分钟是新的一天,而Montréal Québec中仍然是“昨天”。
如果未指定时区,则JVM会隐式应用其当前的默认时区。该默认值可能随时更改,因此您的结果可能会有所不同。最好明确指定您期望/预期的时区作为参数。
以continent/region
的格式指定proper time zone name,例如America/Montreal
,Africa/Casablanca
或Pacific/Auckland
。切勿使用诸如EST
或IST
之类的3-4字母缩写,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。
ZoneId z = ZoneId.of( "America/Montreal" ) ;
通常最好以UTC思考,工作,记录,序列化和交换值。为此,请使用Instant
。 Instant
类代表UTC中时间轴上的一个时刻,分辨率为nanoseconds(小数部分最多九(9)位)。
Instant earlier = Instant.now() ;
…
Instant later = Instant.now() ;
通过调用Instant::toString
和Instant::parse
,以标准ISO 8601格式序列化为文本。
要获取您过去的日期,请应用时区(ZoneId
)来获取ZonedDateTime
个对象。
ZonedDateTime zdtEarlier = earlier.atZone( z ) ;
ZonedDateTime zdtLater = later.atZone( z ) ;
提取仅限日期的值。
LocalDate ldEarlier = zdtEarlier.toLocalDate() ;
LocalDate ldLater = zdtLater.toLocalDate() ;
现在我们可以获得日期之间经过的天数。
long daysElapsed = ChronoUnit.DAYS.between( ldEarlier , ldLater ) ;
此计算是根据半开放方法完成的,其中开头是包含,而结尾是独占。因此,例如,一个月从该月的第一天开始,一直运行,但不包括 月的第一天。在整个业务逻辑,数据库查询等中始终如一地使用此方法将使您的代码库不易出错,并且更易于读取/调试/维护。
我知道您希望使用完全开放的方法,其中开头和结尾都是独占的。我强烈建议你重新考虑这个立场。但如果你坚持,只需从上面的计算中减去1
。
long daysElapsedFullyOpen = ( ChronoUnit.DAYS.between( ldEarlier , ldLater ) - 1 ) ; // Subtract 1 to get a fully-Open answer. NOT recommended.
顺便说一下,您可能需要考虑工作中的Period
课程。同样,您可能会发现ThreeTen-Extra项目中的LocalDateRange
类很有用。
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和&amp; 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。