Java 如何在没有时间部分的情况下比较两个日期?
我想要一个compareTo方法,它忽略java.util.Date的时间部分。我想有很多方法可以解决这个问题。最简单的方法是什么?我更喜欢直接使用Java 如何在没有时间部分的情况下比较两个日期?,java,datetime,Java,Datetime,我想要一个compareTo方法,它忽略java.util.Date的时间部分。我想有很多方法可以解决这个问题。最简单的方法是什么?我更喜欢直接使用java.util.Date的库insetad,因为Joda区分了日期和时间(请参见和类) 但是,如果您确实希望使用java.util.Date,我建议您编写一个实用方法;e、 g public static Date setTimeToMidnight(Date date) { Calendar calendar = Calendar.ge
java.util.Date
的库insetad,因为Joda区分了日期和时间(请参见和类)
但是,如果您确实希望使用java.util.Date
,我建议您编写一个实用方法;e、 g
public static Date setTimeToMidnight(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime( date );
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
return calendar.getTime();
}
更新:虽然Joda Time在当时是一个很好的建议,但尽可能使用Java8+中的库
我的偏好是使用它,这使得这非常容易:
DateTime first = ...;
DateTime second = ...;
LocalDate firstDate = first.toLocalDate();
LocalDate secondDate = second.toLocalDate();
return firstDate.compareTo(secondDate);
编辑:如注释中所述,如果您使用它,则更简单:)
(“使用Joda Time”是几乎所有关于java.util.Date
或java.util.Calendar
的问题的基础。它是一个非常优秀的API。如果你在日期/时间方面做了任何有意义的事情,你应该尽可能使用它。)
如果您完全被迫使用内置API,则应使用适当的日期和时区创建Calendar
的实例。然后,您可以将每个日历中的每个字段(小时、分钟、秒和毫秒)设置为0,并比较结果时间。但与Joda解决方案相比,绝对令人讨厌:)
时区部分很重要:java.util.Date
始终基于UTC。在大多数情况下,如果我对某个日期感兴趣,那就是某个特定时区的日期。这本身将迫使您使用日历
或Joda时间(除非您想自己解释时区,我不建议这样做)
android开发者的快速参考
//Add joda library dependency to your build.gradle file
dependencies {
...
implementation 'joda-time:joda-time:2.9.9'
}
示例代码(示例)
DateTimeComparator DateTimeComparator=DateTimeComparator.getDateOnlyInstance();
日期myDateOne=。。。;
日期myDateTwo=。。。;
int retVal=dateTimeComparator.compare(myDateOne,myDateTwo);
如果(retVal==0)
//两个日期相同
else if(retVal<0)
//myDateOne在MyDate2之前
否则如果(返回值>0)
//myDateOne在MyDate2之后
如果您真的想使用java.util.Date,您可以这样做:
public class TimeIgnoringComparator implements Comparator<Date> {
public int compare(Date d1, Date d2) {
if (d1.getYear() != d2.getYear())
return d1.getYear() - d2.getYear();
if (d1.getMonth() != d2.getMonth())
return d1.getMonth() - d2.getMonth();
return d1.getDate() - d2.getDate();
}
}
公共类TimeIgnoringComparator实现Comparator{
公共整数比较(日期d1、日期d2){
如果(d1.getYear()!=d2.getYear())
返回d1.getYear()-d2.getYear();
如果(d1.getMonth()!=d2.getMonth())
返回d1.getMonth()-d2.getMonth();
返回d1.getDate()-d2.getDate();
}
}
或者,改用日历(首选,因为getYear()等不推荐使用)
公共类TimeIgnoringComparator实现Comparator{
公共整数比较(日历c1、日历c2){
如果(c1.get(日历年)!=c2.get(日历年))
返回c1.get(日历年)-c2.get(日历年);
if(c1.get(日历月)!=c2.get(日历月))
返回c1.get(日历月)-c2.get(日历月);
返回c1.get(日历月日)-c2.get(日历月日);
}
}
我也喜欢,但这里有一个替代方案:
long oneDay = 24 * 60 * 60 * 1000
long d1 = first.getTime() / oneDay
long d2 = second.getTime() / oneDay
d1 == d2
编辑
我把UTC的东西放在下面,以防您需要比较UTC以外的特定时区的日期。如果你真的有这样的需要,那么我真的建议你去找乔达
long oneDay = 24 * 60 * 60 * 1000
long hoursFromUTC = -4 * 60 * 60 * 1000 // EST with Daylight Time Savings
long d1 = (first.getTime() + hoursFromUTC) / oneDay
long d2 = (second.getTime() + hoursFromUTC) / oneDay
d1 == d2
恐怕没有什么方法可以比较两个日期,可以称之为“简单”或“简单” 在比较精度降低的两个时间实例时(例如,仅比较日期),必须始终考虑时区对比较的影响 例如,如果
date1
指定的事件发生在+2时区,而date2
指定的事件发生在EST,则必须注意正确理解比较的含义
您的目的是想知道这两个事件是否发生在各自时区的同一日历日期?或者,您是否需要知道这两个日期是否属于特定时区的同一日历日期(例如UTC或您当地的TZ)
一旦你弄清楚你想要比较的是什么,你只需要在一个合适的时区里把年-月-日的日期增加三倍,然后进行比较
Joda time可能会使实际的比较操作看起来更清晰,但比较的语义仍然需要您自己去弄清楚。对此备选方案有何看法
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
sdf.format(date1).equals(sdf.format(date2));
几乎无处不在。那么这个呢
if (DateUtils.isSameDay(date1, date2)) {
// it's same
} else if (date1.before(date2)) {
// it's before
} else {
// it's after
}
我的主张:
Calendar cal = Calendar.getInstance();
cal.set(1999,10,01); // nov 1st, 1999
cal.set(Calendar.AM_PM,Calendar.AM);
cal.set(Calendar.HOUR,0);
cal.set(Calendar.MINUTE,0);
cal.set(Calendar.SECOND,0);
cal.set(Calendar.MILLISECOND,0);
// date column in the Thought table is of type sql date
Thought thought = thoughtDao.getThought(date, language);
Assert.assertEquals(cal.getTime(), thought.getDate());
这就是我的工作原理:
var Date1 = new Date(dateObject1.toDateString()); //this sets time to 00:00:00
var Date2 = new Date(dateObject2.toDateString());
//do a normal compare
if(Date1 > Date2){ //do something }
以下是来自此博客的解决方案:
i、 e.您可以查看以毫秒为单位的时差是否小于一天的长度。如果您只想比较两个没有时间的日期,则以下代码可能会帮助您:
final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
Date dLastUpdateDate = dateFormat.parse(20111116);
Date dCurrentDate = dateFormat.parse(dateFormat.format(new Date()));
if (dCurrentDate.after(dLastUpdateDate))
{
add your logic
}
如果您只想比较两个日期的月、日和年,以下代码适用于我:
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
sdf.format(date1).equals(sdf.format(date2));
谢谢Rob。已经提到了apache commons utils:
org.apache.commons.lang.time.DateUtils.truncate(date, Calendar.DAY_OF_MONTH)
为您提供仅包含日期而不包含时间的日期对象,您可以将其与日期进行比较。compareTo使用SimpleDataFormat的GetDate实例,我们只能比较两个不包含时间的日期对象。执行下面的代码
public static void main(String[] args) {
Date date1 = new Date();
Date date2 = new Date();
DateFormat dfg = SimpleDateFormat.getDateInstance(DateFormat.DATE_FIELD);
String dateDtr1 = dfg.format(date1);
String dateDtr2 = dfg.format(date2);
System.out.println(dateDtr1+" : "+dateDtr2);
System.out.println(dateDtr1.equals(dateDtr2));
}
只需结合年份属性检查年份的日期
boolean isSameDay =
firstCal.get(Calendar.YEAR) == secondCal.get(Calendar.YEAR) &&
firstCal.get(Calendar.DAY_OF_YEAR) == secondCal.get(Calendar.DAY_OF_YEAR)
编辑:
现在我们可以使用Kotlin扩展函数的强大功能
fun Calendar.isSameDay(second: Calendar): Boolean {
return this[Calendar.YEAR] == second[Calendar.YEAR] && this[Calendar.DAY_OF_YEAR] == second[Calendar.DAY_OF_YEAR]
}
fun Calendar.compareDatesOnly(other: Calendar): Int {
return when {
isSameDay(other) -> 0
before(other) -> -1
else -> 1
}
}
`
`在Java 8中,您可以使用LocalDate,它与Joda Time中的非常相似。另一个简单的比较方法是基于这里的答案和我的导师指导
public static int compare(Date d1, Date d2) {
Calendar c1 = Calendar.getInstance();
Calendar c2 = Calendar.getInstance();
c1.setTime(d1);
c1.set(Calendar.MILLISECOND, 0);
c1.set(Calendar.SECOND, 0);
c1.set(Calendar.MINUTE, 0);
c1.set(Calendar.HOUR_OF_DAY, 0);
c2.setTime(d2);
c2.set(Calendar.MILLISECOND, 0);
c2.set(Calendar.SECOND, 0);
c2.set(Calendar.MINUTE, 0);
c2.set(Calendar.HOUR_OF_DAY, 0);
return c1.getTime().compareTo(c2.getTime());
}
编辑:
根据@Jonathan Drapeau的说法,上述代码在某些情况下失败(我希望看到这些情况,请),据我所知,他建议如下:
public static int compare2(Date d1, Date d2) {
Calendar c1 = Calendar.getInstance();
Calendar c2 = Calendar.getInstance();
c1.clear();
c2.clear();
c1.set(Calendar.YEAR, d1.getYear());
c1.set(Calendar.MONTH, d1.getMonth());
c1.set(Calendar.DAY_OF_MONTH, d1.getDay());
c2.set(Calendar.YEAR, d2.getYear());
c2.set(Calendar.MONTH, d2.getMonth());
c2.set(Calendar.DAY_OF_MONTH, d2.getDay());
return c1.getTime().compareTo(c2.getTime());
}
请注意,Date类已被弃用,因为它不适合国际化。Calendar类用于
boolean isSameDay =
firstCal.get(Calendar.YEAR) == secondCal.get(Calendar.YEAR) &&
firstCal.get(Calendar.DAY_OF_YEAR) == secondCal.get(Calendar.DAY_OF_YEAR)
fun Calendar.isSameDay(second: Calendar): Boolean {
return this[Calendar.YEAR] == second[Calendar.YEAR] && this[Calendar.DAY_OF_YEAR] == second[Calendar.DAY_OF_YEAR]
}
fun Calendar.compareDatesOnly(other: Calendar): Int {
return when {
isSameDay(other) -> 0
before(other) -> -1
else -> 1
}
}
SimpleDateFormat sdf= new SimpleDateFormat("MM/dd/yyyy")
Date date1=sdf.parse("03/25/2015");
Date currentDate= sdf.parse(sdf.format(new Date()));
return date1.compareTo(currentDate);
public static int compare(Date d1, Date d2) {
Calendar c1 = Calendar.getInstance();
Calendar c2 = Calendar.getInstance();
c1.setTime(d1);
c1.set(Calendar.MILLISECOND, 0);
c1.set(Calendar.SECOND, 0);
c1.set(Calendar.MINUTE, 0);
c1.set(Calendar.HOUR_OF_DAY, 0);
c2.setTime(d2);
c2.set(Calendar.MILLISECOND, 0);
c2.set(Calendar.SECOND, 0);
c2.set(Calendar.MINUTE, 0);
c2.set(Calendar.HOUR_OF_DAY, 0);
return c1.getTime().compareTo(c2.getTime());
}
public static int compare2(Date d1, Date d2) {
Calendar c1 = Calendar.getInstance();
Calendar c2 = Calendar.getInstance();
c1.clear();
c2.clear();
c1.set(Calendar.YEAR, d1.getYear());
c1.set(Calendar.MONTH, d1.getMonth());
c1.set(Calendar.DAY_OF_MONTH, d1.getDay());
c2.set(Calendar.YEAR, d2.getYear());
c2.set(Calendar.MONTH, d2.getMonth());
c2.set(Calendar.DAY_OF_MONTH, d2.getDay());
return c1.getTime().compareTo(c2.getTime());
}
Date date1 = new Date();
Date date2 = new Date();
if (DateUtils.truncatedCompareTo(date1, date2, Calendar.DAY_OF_MONTH) == 0)
// TRUE
else
// FALSE
LocalDate date1 = LocalDate.of(2016, 2, 14);
LocalDate date2 = LocalDate.of(2015, 5, 23);
date1.isAfter(date2);
import org.apache.commons.lang3.time.DateUtils
DateUtils.truncatedEquals(first, second, Calendar.DAY_OF_MONTH)
public static Date getZeroTimeDate(Date fecha) {
Date res = fecha;
Calendar calendar = Calendar.getInstance();
calendar.setTime( fecha );
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
res = calendar.getTime();
return res;
}
Date currentDate = getZeroTimeDate(new Date());// get current date
public class ArnesClass implements Comparable<ArnesClass> {
private static final ZoneId arnesTimeZone = ZoneId.systemDefault();
private Instant when;
@Override
public int compareTo(ArnesClass o) {
// question is what to put here
}
}
public int compareTo(ArnesClass o) {
LocalDate dateWithoutTime = when.atZone(arnesTimeZone).toLocalDate();
LocalDate otherDateWithoutTime = o.when.atZone(arnesTimeZone).toLocalDate();
return dateWithoutTime.compareTo(otherDateWithoutTime);
}
LocalDate dateWithoutTime = when.toInstant().atZone(arnesTimeZone).toLocalDate();
private static final TimeZone arnesTimeZone = TimeZone.getTimeZone("Europe/Stockholm");
private static final DateFormat formatter = new SimpleDateFormat("yyyyMMdd");
static {
formatter.setTimeZone(arnesTimeZone);
}
private Date when;
@Override
public int compareTo(ArnesClass o) {
return formatter.format(when).compareTo(formatter.format(o.when));
}
myJavaUtilDate1.toInstant()
.atZone( ZoneId.of( "America/Montreal" ) )
.toLocalDate()
.isEqual (
myJavaUtilDate2.toInstant()
.atZone( ZoneId.of( "America/Montreal" ) )
.toLocalDate()
)
Instant instant1 = myJavaUtilDate1.toInstant();
Instant instant2 = myJavaUtilDate2.toInstant();
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt1 = instant1.atZone( z );
ZonedDateTime zdt2 = instant2.atZone( z );
LocalDate localDate1 = zdt1.toLocalDate();
LocalDate localDate2 = zdt2.toLocalDate();
Boolean sameDate = localDate1.isEqual( localDate2 );
public Date saveDateWithoutTime(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime( date );
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.HOUR, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
return calendar.getTime();
}
Calendar last = Calendar.getInstance();
last.setTimeInMillis(firstTimeInMillis);
Calendar current = Calendar.getInstance();
if (last.get(Calendar.DAY_OF_MONTH) != current.get(Calendar.DAY_OF_MONTH)) {
//not the same day
}
SimpleDateFormat dtf = new SimpleDateFormat("dd/MM/yyyy");
Date td_date = new Date();
String first_date = dtf.format(td_date); //First seted in String
String second_date = "30/11/2020"; //Second date you can set hear in String
String result = (first_date.equals(second_date)) ? "Yes, Its Equals":"No, It is not Equals";
System.out.println(result);
@Test
public void dateTruncate() throws InterruptedException {
Instant now = Instant.now();
Thread.sleep(1000*5);
Instant later = Instant.now();
assertThat(now, not(equalTo(later)));
assertThat(now.truncatedTo(ChronoUnit.DAYS), equalTo(later.truncatedTo(ChronoUnit.DAYS)));
}
// Create one day 00:00:00 calendar
int oneDayTimeStamp = 1523017440;
Calendar oneDayCal = Calendar.getInstance();
oneDayCal.setTimeInMillis(oneDayTimeStamp * 1000L);
oneDayCal.set(Calendar.HOUR_OF_DAY, 0);
oneDayCal.set(Calendar.MINUTE, 0);
oneDayCal.set(Calendar.SECOND, 0);
oneDayCal.set(Calendar.MILLISECOND, 0);
// Create current day 00:00:00 calendar
Calendar currentCal = Calendar.getInstance();
currentCal.set(Calendar.HOUR_OF_DAY, 0);
currentCal.set(Calendar.MINUTE, 0);
currentCal.set(Calendar.SECOND, 0);
currentCal.set(Calendar.MILLISECOND, 0);
if (oneDayCal.compareTo(currentCal) == 0) {
// Same day (excluding time)
}
public Boolean compareDateWithoutTime(Date d1, Date d2) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
return sdf.format(d1).equals(sdf.format(d2));
}