给定两个Date对象,比较它们的时间部分之间的差异,完全忽略年,月和日,有什么好方法?
这与this question完全相反。
更新:以下是未来参考的最终代码:
private long differenceBetween(Date currentTime, Date timeToRun)
{
Calendar currentCal = Calendar.getInstance();
currentCal.setTime(currentTime);
Calendar runCal = Calendar.getInstance();
runCal.setTime(timeToRun);
runCal.set(Calendar.DAY_OF_MONTH, currentCal.get(Calendar.DAY_OF_MONTH));
runCal.set(Calendar.MONTH, currentCal.get(Calendar.MONTH));
runCal.set(Calendar.YEAR, currentCal.get(Calendar.YEAR));
return currentCal.getTimeInMillis() - runCal.getTimeInMillis();
}
答案 0 :(得分:31)
如果要比较日期的基础二进制(long int)值,可以执行以下操作:
public int compareTimes(Date d1, Date d2)
{
int t1;
int t2;
t1 = (int) (d1.getTime() % (24*60*60*1000L));
t2 = (int) (d2.getTime() % (24*60*60*1000L));
return (t1 - t2);
}
附录1
此技术具有速度优势,因为它直接使用long
对象的基础Date
值,而不是在刻度和日历组件之间进行转换(这相当昂贵且速度慢)。它比弄乱Calendar
个对象要简单得多。
附录2
上面的代码将时间差作为int
返回,这对于任何一对都是正确的,因为它完全忽略日期的年/月/日部分,以及任何两次之间的差异不超过86,400,000 ms(= 1000 ms / sec×60 sec / min×60 min / hr×24 hr / day)。
答案 1 :(得分:19)
您可以考虑使用Joda时间的DateTimeComparator.getTimeOnlyInstance()
作为比较器,该比较器仅根据时间比较两个Joda日期。
例如:
DateTimeComparator comparator = DateTimeComparator.getTimeOnlyInstance();
comparator.compare(date1, date2);
答案 2 :(得分:5)
看一下Calendar
课程。它支持从给定的Date
中提取小时,分钟和秒。
Calendar calendar = Calendar.getInstance();
calendar.setTime(yourDateObject);
int hour = calendar.get(Calendar.HOUR);
int minute = calendar.get(Calendar.MINUTE);
int second = calendar.get(Calendar.SECOND);
答案 3 :(得分:2)
使用现代的 java.time 类。
请注意,您要求的比较可能没有意义,因为特定的一天在不同区域的不同日期可能具有不同的含义。
Duration // Span of time, with resolution of nanoseconds.
.between( // Calculate elapsed time.
LocalTime.now( // Get current time-of-day…
ZoneId.of( "Pacific/Auckland" ) // … as seen in a particular time zone.
) // Returns a `LocalTime` object.
,
myJavaUtilDate // Avoid terrible legacy date-time classes such as `java.util.Date`.
.toInstant() // Convert from `java.util.Date` to `java.time.Instant`, both representing a moment in UTC.
.atZone( // Adjust from UTC to a particular time zone. Same moment, same point on the timeline, different wall-clock time.
ZoneId.of( "Pacific/Auckland" ) // Specify time zone by proper naming in `Continent/Region` format, never 2-4 letter pseudo-zones such as `PST`, `CEST`, `CST`, `IST`, etc.
) // Returns a `ZonedDateTime` object.
.toLocalTime() // Extract the time-of-day without the date and without a time zone.
) // Returns a `Duration` object.
.toMillis() // Calculate entire span-of-time in milliseconds. Beware of data-loss as `Instant` uses a finer resolution the milliseconds, and may carry microseconds or nanoseconds.
我建议绕过类型安全且易于解释的Duration
对象,而不是仅仅整数毫秒。
现代方法使用 java.time 类代替了可怕的旧类,例如Date
,Calendar
,SimpleDateFormat
。
将您的java.util.Date
(以UTC表示的时间)转换为Instant
。使用添加到旧类中的新转换方法。
Instant instant = myJavaUtilDate.toInstant() ;
这代表UTC的时刻。确定日期和时间需要time zone。在任何给定的时刻,日期和时间在全球范围内都会有所不同。例如,Paris France午夜之后的几分钟是新的一天,而Montréal Québec仍然是“昨天”。
如果未指定时区,则JVM隐式应用其当前的默认时区。该默认值可能在运行时(!)期间change at any moment,因此您的结果可能会有所不同。最好将您的[期望/期望时区] [2]明确指定为参数。
以continent/region
的格式指定proper time zone name,例如America/Montreal
,Africa/Casablanca
或Pacific/Auckland
。切勿使用2-4个字母的缩写,例如EST
或IST
,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。
ZoneId z = ZoneId.of( "America/Montreal" ) ;
如果要使用JVM的当前默认时区,请提出要求并作为参数传递。如果省略,则会隐式应用JVM的当前默认值。最好明确一点,因为默认值可能会在运行时的任何时候被JVM中任何应用程序的任何线程中的任何代码更改。
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
将ZoneId
分配给Instant
以产生ZonedDateTime
对象。
ZonedDateTime zdt = instant.atZone( z ) ;
提取时间部分,不包含日期和时区。
LocalTime lt = zdt.toLocalTime() ;
比较。用Duration
计算经过的时间。
Duration d = Duration.between( ltStart , ltStop ) ;
请注意,这是不公平的比较。日期并非总是24小时长,并且并非所有时间值在所有区域的所有日期都有效。例如,在美国的夏令时转换中,可能根本没有凌晨2点。因此,凌晨1点到凌晨4点可能是一个日期3个小时,而另一个日期只有2个小时。
java.time框架已内置在Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和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。
答案 4 :(得分:1)
如果你不能使用JODA,
创建2个日历对象,将年,月和日设置为0。
比较他们......
答案 5 :(得分:1)
如果JODA不是一个选项,最短的方法之一可能是将时间转换为字符串然后进行比较。
DateFormat df = new SimpleDateFormat("HHmmssSZ");
df.format(date1).equals(df.format(date2));
答案 6 :(得分:0)
不知道这个练习有多好或有效,但是我使用Date对象编写了一个简单的函数,用于我的目的。它返回true或false是第一个日期值大于第二个日期值。输入d1&& d2是Date对象。
function CompareTimes(d1, d2) {
if (d1.getHours() < d2.getHours()) {
return false;
}
if (d1.getHours() > d2.getHours()) {
return true;
} else {
return (d1.getMinutes() > d2.getMinutes());
}
};
答案 7 :(得分:0)
如果您只想比较日期的时间部分,那么这将为您提供正确的结果 -
#welcome_text_div {
background-color:red;
width:800px;
height:300px;
display:flex;
align-items:center;
justify-content:center;
}
#welcome_text {
color: white;
font-family: sans-serif;
text-transform: uppercase;
font-weight: bold;
font-size: 55px;
}