我想有一个compareTo方法忽略java.util.Date的时间部分.我想有很多方法可以解决这个问题.什么是最简单的方法?
Jon*_*eet 207
更新:虽然当时Joda Time是一个很好的推荐,但请java.time尽可能使用Java 8+中的库.
我的偏好是使用Joda Time,这非常容易:
DateTime first = ...;
DateTime second = ...;
LocalDate firstDate = first.toLocalDate();
LocalDate secondDate = second.toLocalDate();
return firstDate.compareTo(secondDate);
Run Code Online (Sandbox Code Playgroud)
编辑:如评论中所述,如果你使用DateTimeComparator.getDateOnlyInstance()它甚至更简单:)
// TODO: consider extracting the comparator to a field.
return DateTimeComparator.getDateOnlyInstance().compare(first, second);
Run Code Online (Sandbox Code Playgroud)
("使用Joda Time"是几乎所有询问java.util.Date或者问题的SO问题的基础java.util.Calendar.它是一个非常优秀的API.如果你正在做任何有关日期/时间的重要事项,你应该尽可能地使用它.)
如果您绝对被迫使用内置API,则应创建具有Calendar适当日期并使用适当时区的实例.然后,您可以将每个日历中的每个字段(小时,分钟,秒和毫秒)设置为0,并比较生成的时间.绝对icky与Joda解决方案相比虽然:)
时区部分是很重要的:java.util.Date是始终基于UTC.在大多数情况下,我对某个日期感兴趣,这是特定时区的日期.这本身就会迫使你使用CalendarJoda Time(除非你想自己考虑时区,我不建议这样做.)
Android开发人员的快速参考
//Add joda library dependency to your build.gradle file
dependencies {
...
implementation 'joda-time:joda-time:2.9.9'
}
Run Code Online (Sandbox Code Playgroud)
示例代码(示例)
DateTimeComparator dateTimeComparator = DateTimeComparator.getDateOnlyInstance();
Date myDateOne = ...;
Date myDateTwo = ...;
int retVal = dateTimeComparator.compare(myDateOne, myDateTwo);
if(retVal == 0)
//both dates are equal
else if(retVal < 0)
//myDateOne is before myDateTwo
else if(retVal > 0)
//myDateOne is after myDateTwo
Run Code Online (Sandbox Code Playgroud)
And*_*dré 118
Apache commons-lang几乎无处不在.那么这个怎么样?
if (DateUtils.isSameDay(date1, date2)) {
// it's same
} else if (date1.before(date2)) {
// it's before
} else {
// it's after
}
Run Code Online (Sandbox Code Playgroud)
Jor*_*orn 58
如果你真的想使用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();
}
}
Run Code Online (Sandbox Code Playgroud)
或者,使用日历(首选,因为getYear()等不推荐使用)
public class TimeIgnoringComparator implements Comparator<Calendar> {
public int compare(Calendar c1, Calendar c2) {
if (c1.get(Calendar.YEAR) != c2.get(Calendar.YEAR))
return c1.get(Calendar.YEAR) - c2.get(Calendar.YEAR);
if (c1.get(Calendar.MONTH) != c2.get(Calendar.MONTH))
return c1.get(Calendar.MONTH) - c2.get(Calendar.MONTH);
return c1.get(Calendar.DAY_OF_MONTH) - c2.get(Calendar.DAY_OF_MONTH);
}
}
Run Code Online (Sandbox Code Playgroud)
Ada*_*ski 36
我倾向于直接使用Joda库的insetad java.util.Date,因为Joda区分了日期和时间(参见YearMonthDay和DateTime类).
但是,如果您确实希望使用java.util.Date我会建议编写实用方法; 例如
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();
}
Run Code Online (Sandbox Code Playgroud)
Rob*_*own 26
对此替代方案有何看法?
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
sdf.format(date1).equals(sdf.format(date2));
Run Code Online (Sandbox Code Playgroud)
小智 16
如果您只想比较两个日期的月,日和年,以下代码适用于我:
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
sdf.format(date1).equals(sdf.format(date2));
Run Code Online (Sandbox Code Playgroud)
谢谢Rob.
Dan*_*ral 13
我也更喜欢Joda Time,但这里有另一种选择:
long oneDay = 24 * 60 * 60 * 1000
long d1 = first.getTime() / oneDay
long d2 = second.getTime() / oneDay
d1 == d2
Run Code Online (Sandbox Code Playgroud)
编辑
我将UTC内容放在下面,以防您需要比较UTC以外的特定时区的日期.如果你有这样的需求,那么我真的建议去Joda.
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
Run Code Online (Sandbox Code Playgroud)
myJavaUtilDate1.toInstant()
.atZone( ZoneId.of( "America/Montreal" ) )
.toLocalDate()
.isEqual (
myJavaUtilDate2.toInstant()
.atZone( ZoneId.of( "America/Montreal" ) )
.toLocalDate()
)
Run Code Online (Sandbox Code Playgroud)
避免麻烦的旧的遗留日期时间类,例如Date&Calendar,现在由java.time类取代.
A java.util.Date表示UTC时间轴上的时刻.java.time中的等价物是Instant.您可以使用添加到旧类的新方法进行转换.
Instant instant1 = myJavaUtilDate1.toInstant();
Instant instant2 = myJavaUtilDate2.toInstant();
Run Code Online (Sandbox Code Playgroud)
您想按日期进行比较.时区对于确定日期至关重要.对于任何给定的时刻,日期在全球范围内因地区而异.例如,法国巴黎午夜过后几分钟是新的一天,而在魁北克蒙特利尔仍然是"昨天" .
指定适当的时区名称,格式continent/region,如America/Montreal,Africa/Casablanca或Pacific/Auckland.切勿使用3-4字母缩写,例如EST或IST因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!).
ZoneId z = ZoneId.of( "America/Montreal" );
Run Code Online (Sandbox Code Playgroud)
应用ZoneId到Instant获得ZonedDateTime.
ZonedDateTime zdt1 = instant1.atZone( z );
ZonedDateTime zdt2 = instant2.atZone( z );
Run Code Online (Sandbox Code Playgroud)
该LocalDate级表示没有时间一天和不同时区的日期,唯一的价值.我们可以LocalDate从a中提取a ZonedDateTime,有效地消除了时间部分.
LocalDate localDate1 = zdt1.toLocalDate();
LocalDate localDate2 = zdt2.toLocalDate();
Run Code Online (Sandbox Code Playgroud)
现在比较,使用方法,如isEqual,isBefore和isAfter.
Boolean sameDate = localDate1.isEqual( localDate2 );
Run Code Online (Sandbox Code Playgroud)
请参阅IdeOne.com上的此代码.
instant1:2017-03-25T04:13:10.971Z | instant2:2017-03-24T22:13:10.972Z
zdt1:2017-03-25T00:13:10.971-04:00 [美国/蒙特利尔] | zdt2:2017-03-24T18:13:10.972-04:00 [美国/蒙特利尔]
localDate1:2017-03-25 | localDate2:2017-03-24
sameDate:false
该java.time框架是建立在Java 8和更高版本.这些类取代麻烦的老传统日期时间类,如java.util.Date,Calendar,和SimpleDateFormat.
现在处于维护模式的Joda-Time项目建议迁移到java.time类.
要了解更多信息,请参阅Oracle教程.并搜索Stack Overflow以获取许多示例和解释.规范是JSR 310.
从哪里获取java.time类?
该ThreeTen-额外项目与其他类扩展java.time.该项目是未来可能添加到java.time的试验场.您可以在此比如找到一些有用的类Interval,YearWeek,YearQuarter,和更多.
已经提到过apache commons-utils:
org.apache.commons.lang.time.DateUtils.truncate(date, Calendar.DAY_OF_MONTH)
Run Code Online (Sandbox Code Playgroud)
为您提供仅包含日期的Date对象,没有时间,您可以将其与之进行比较 Date.compareTo
我担心没有办法比较两个可称为"简单"或"简单"的日期.
当比较具有任何降低精度的两个时间实例(例如仅比较日期)时,必须始终考虑时区如何影响比较.
例如,如果date1要指定在+2时区中发生的事件并date2指定在EST中发生的事件,则必须注意正确理解比较的含义.
您的目的是确定这两个事件是否发生在各自时区的同一日历日期?或者您需要知道这两个日期是否属于特定时区(UTC或您当地的TZ)的同一日历日期.
一旦你弄清楚你想要比较的实际情况,只需要在适当的时区内获得年 - 月 - 日三重并进行比较.
Joda时间可能会使实际的比较操作看起来更清晰,但比较的语义仍然是你需要弄清楚自己的东西.
只需结合 YEAR 属性检查 DAY_OF_YEAR
boolean isSameDay =
firstCal.get(Calendar.YEAR) == secondCal.get(Calendar.YEAR) &&
firstCal.get(Calendar.DAY_OF_YEAR) == secondCal.get(Calendar.DAY_OF_YEAR)
Run Code Online (Sandbox Code Playgroud)
编辑:
现在我们可以使用 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
}
}
Run Code Online (Sandbox Code Playgroud)
如果您使用的是Java 8,则应使用这些java.time.*类来比较日期 - 它是各种java.util.*类的首选
例如; https://docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html
LocalDate date1 = LocalDate.of(2016, 2, 14);
LocalDate date2 = LocalDate.of(2015, 5, 23);
date1.isAfter(date2);
Run Code Online (Sandbox Code Playgroud)
如果您只想比较两个没有时间的日期,那么以下代码可能会帮助您:
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
}
Run Code Online (Sandbox Code Playgroud)
我不知道这是新想法还是其他,但我向你展示了我所做的
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);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
260632 次 |
| 最近记录: |