有更好的比较日期的方法吗



我正在尝试比较两个日期。日期以字符串形式从数据库导入,可能是也可能不是空

这是我的代码

private String compareDates(String date1, String date2)
{
String earliestDate = null;
//        date2 is null and date1 is null
//            earliest = “not seen yet”
if (date2 == null && date1 == null)
{
earliestDate = "not seen yet";
}
//        date2 is null and date1 is not null
//            earliest = date1
if (date2 == null && date1 != null)
{
earliestDate = date1;
}
//        date2 is not null and date1 is null
//            earliest = date2
if (date2 != null && date1 == null)
{
earliestDate = date2;
}
//        date2 is not null and date1 is not null
//            compare dates
if (date2 != null && date1 != null)
{
LocalDate LDdate1 = LocalDate.parse(date1);
LocalDate LDdate2 = LocalDate.parse(date2);
if (LDdate1.isBefore(LDdate2) || LDdate1.isEqual(LDdate2))
{
earliestDate = LDdate1.toString();
}
else
{
earliestDate = LDdate2.toString();
}
}
return earliestDate;
}

这段代码给了我正确的输出,即最早的日期,或";尚未看到";如果两个日期都为空,但我想知道是否有更好/更有效的做事方式。

我想使用switch语句是一种选择,但用不同的方式做会更好吗?

数据库中的数据只有大约200个日期,所以它不处理很多数据,只是我有兴趣编写更好的代码

如果日期是标准的本地格式,并像一样按YYYY-MM-DD排序

"2018-01-24"

为什么要麻烦解析呢?只需做一个字符串比较。速度大约快100倍,也更容易。

public static String compareDatesStr(String date1, String date2) {
if (date1 == null)
if (date2 == null)
return "not seen yet";
else
return date2;
else if (date2 == null)
return date1;
else
return date1.compareTo(date2) > 0 ? date2 : date1;
}

一些非科学性能比较:

private static String compareDatesParse(String date1, String date2) {
String earliestDate;
if (date1 == null) {
if (date2 == null) {
earliestDate = "not seen yet";
}
else {
earliestDate = date2;
}
}
else {
if (date2 == null) {
earliestDate = date1;
}
else {
LocalDate LDdate1 = LocalDate.parse(date1);
LocalDate LDdate2 = LocalDate.parse(date2);
if (LDdate1.isAfter(LDdate2)) {
earliestDate = date2;
}
else {
earliestDate = date1;
}
}
}
return earliestDate;
}
public static void testDateComp(){
String[] dates = {"2020-10-30", "2020-10-29", "1990-10-30", "2021-06-01", null};
String result = null;
int loops = 400000;
long start, end = 0;
// System.out.println("Runs: " + (dates.length*dates.length*loops));

start = System.currentTimeMillis();
for (int i = 0; i < loops; i++) {
for (String date1:dates) {
for (String date2:dates) {
result = compareDatesStr(date1, date2);
}
}
}
end = System.currentTimeMillis();
System.out.println("Runtime String: " + (end - start)+ "ms");
start = System.currentTimeMillis();
for (int i = 0; i < loops; i++) {
for (String date1:dates) {
for (String date2:dates) {
result = compareDatesParse(date1, date2);
}
}
}
end = System.currentTimeMillis();
System.out.println("Runtime Parsing: " + (end - start) + "ms");
}

10MM方法执行:

Runtime String: 61ms
Runtime Parsing: 7361ms

如果条件如下,可以减少一个:

private String compareDates(String date1, String date2) {
String earliestDate = "not seen yet";
if (!StringUtils.isEmpty(date2) && !StringUtils.isEmpty(date1)) {
LocalDate LDdate1 = LocalDate.parse(date1);
LocalDate LDdate2 = LocalDate.parse(date2);
if (LDdate1.isBefore(LDdate2) || LDdate1.isEqual(LDdate2)) {
earliestDate = LDdate1.toString();
}
else {
earliestDate = LDdate2.toString();
}
} else if (!StringUtils.isEmpty(date2) && StringUtils.isEmpty(date1)) {
earliestDate = LDdate2;
} else if (StringUtils.isEmpty(date2) && !StringUtils.isEmpty(date1)) {
earliestDate = LDdate1;
}
return earliestDate;
} 

您可以使用自定义Comparator,它允许以声明性方式指定比较逻辑:

private String compareDates(String date1, String date2) {
Comparator<String> c = Comparator.nullsLast(
Comparator.comparing(LocalDate::parse));
int result = c.compare(date1, date2);
return result == 0 && date1 == null ?
"not seen yet"               :
result <= 0                  ?
date1                        :
date2;
}

除了一堆外观相似的if语句之外,还有其他一些选项。

  1. Comparator

    if (date1 == null && date2 == null) {
    return "not seen yet";
    }
    Comparator<String> c = Comparator.nullsLast((String a, String b) -> LocalDate.parse(a).compareTo(LocalDate.parse(b)));
    return c.compare(date1, date2) <= 0 ? date1 : date2;
    
  2. 使用ComparatorStream::reduce

    return Stream.of(date1, date2)
    .filter(Objects::nonNull)
    .reduce((a, b) -> LocalDate.parse(a).compareTo(LocalDate.parse(b)) <= 0 ? a : b)
    .orElse("not seen yet");
    

对我来说,这两个选项都比你现在的可读性更好,但我会选择选项1。人们可能会发现使用流有点过头了,在某种程度上,这是真的。

下面的怎么样?

private String compareDates(String date1, String date2) {
String earliestDate;
if (date1 == null) {
if (date2 == null) {
earliestDate = "not seen yet";
}
else {
earliestDate = date2;
}
}
else {
if (date2 == null) {
earliestDate = date1;
}
else {
LocalDate LDdate1 = LocalDate.parse(date1);
LocalDate LDdate2 = LocalDate.parse(date2);
if (LDdate1.isAfter(LDdate2)) {
earliestDate = date2;
}
else {
earliestDate = date1;
}
}
}
return earliestDate;
}

日期以字符串形式从数据库导入…

第一点:不要那样做。从数据库中提取日期作为LocalDate对象,并在程序中进行处理。有关如何从SQL数据库中获取LocalDate的信息,请参阅底部的链接。

接下来,我将使用流管道来查找前面的一个:

// Some example dates
LocalDate date1 = null;
LocalDate date2 = LocalDate.of(2020, Month.OCTOBER, 24);

String earlierDate = Stream.of(date1, date2)
.filter(Objects::nonNull)
.min(LocalDate::compareTo)
.map(LocalDate::toString)
.orElse("Not seen yet");
System.out.println(earlierDate);

输出:

2020-10-24

链接:问题插入&向SQL数据库(如H2 (提取java.time.LocalDate对象

相关内容

最新更新