我的应用程序通过日期选择器片段接受用户的日期,并将其存储在数据库中,其中日、月和年作为字符串类型的单独列。
现在,我正在创建一个函数,稍后将使用系统的当前日期检查每个日期。如果当前日期早于用户输入的日期(并存储在数据库中),则标志变量会递增。
这是代码:
public int checkDate() { //Method to check date and take action
//NOT COMPLETE. STILL FIGURING IT OUT.
String isstatus = "Ongoing";
String[] columns = new String[] {KEY_ROWID, DAY, MONTH, YEAR ,PROJECT_STATUS};
Cursor c = projectDatabase.query(DATABASE_TABLE, columns, PROJECT_STATUS + "=" + isstatus, null, null, null, null);
int result = 0;
int flag = 0;
int iRow = c.getColumnIndex(KEY_ROWID);
int iDay = c.getColumnIndex(DAY);
int iMonth = c.getColumnIndex(MONTH);
int iYear = c.getColumnIndex(YEAR);
final Calendar cal = Calendar.getInstance(); //fetch current system date
int cyear = cal.get(Calendar.YEAR);
int cmonth = cal.get(Calendar.MONTH);
int cday = cal.get(Calendar.DAY_OF_MONTH);
for(c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
String id = c.getString(iRow);
int fday = Integer.parseInt(c.getString(iDay));
int fmonth = Integer.parseInt(c.getString(iMonth));
int fyear = Integer.parseInt(c.getString(iYear));
if(cday>fday && cmonth>fmonth && cyear>fyear) {
flag++;
updateStatus(id, "Missed");
}
else
if(cday>fday && cmonth==fmonth && cyear==fyear) {
flag++;
updateStatus(id, "Missed");
}
else
if(cday==fday && cmonth>fmonth && cyear>fyear) {
flag++;
updateStatus(id, "Missed");
}
else
if(cday==fday && cmonth==fmonth && cyear>fyear) {
flag++;
updateStatus(id, "Missed");
}
else
if(cmonth>fmonth && cyear>fyear) {
flag++;
updateStatus(id, "Missed");
}
else
if(cmonth>fmonth && cyear==fyear) {
flag++;
updateStatus(id, "Missed");
}
result = flag;
}
return result;
}
如您所见,我必须比较未来日期的所有可能情况。而且我个人认为这不是最有效的方法。 有什么建议吗?
我从未真正处理过日期,但我将概述一种算法,至少可以减少需要进行的比较次数。
if(currentYear > dataYear) {
//We're obviously past that date. Move on
} else if(currentYear == dataYear) {
//We're in the same year. Let's check for months
if(currentMonth > dataMonth) {
//Missed the date again, move on
} else if(currentMonth == dataMonth) {
//We're in the same year and the same month! Let's check days
if(currentDay > dataDay) {
//Date is still in the past. Keep moving on
} else if(currentDay == dataDay) {
//Date is today
} else {
//Date is in the future
}
}
} else {
//Date is in the past
}
这也不会太高效,并且您可能可以通过策略性地使用
&&
来减少 if 语句的数量(尽管无论如何编译器优化可能会为您做到这一点)。
更好的方法是以 UNIX 时间保存日期,并获取当前 UNIX 时间并比较两个长整型。没有比这更简单的了。
您还可以根据存储的日期构造另一个 Calendar 对象并使用 before()。然而,原始的长与长比较比比较两个日历更有效。
建议使用joda日期时间库进行日期比较,有一些有用的功能,例如isBefore和isAfter
Date
进行比较
Date now = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(now); // make sure the time part is the same
for(c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
String id = c.getString(iRow);
int fday = Integer.parseInt(c.getString(iDay));
int fmonth = Integer.parseInt(c.getString(iMonth));
int fyear = Integer.parseInt(c.getString(iYear));
cal.set(Calendar.YEAR, fyear);
cal.set(Calendar.MONTH, fmonth);
cal.set(Calendar.DAY_OF_MONTH, fday);
Date d = cal.getTime();
if (now.after(d)) {
flag++;
updateStatus(id, "Missed");
}
result = flag;
}
LocalDate.now().isAfter( myResultSet.getObject( … , LocalDate.class ) )
在现代 Java 中,我们可以大幅减少代码。
JDBC 4.2 及更高版本要求每个 JDBC 驱动程序都使用 java.time 类型。
从类似于 SQL 标准类型
DATE
的类型的列中检索日期值。您的 JDBC 驱动程序返回一个类 LocalDate
的对象。
LocalDate ld = myResultSet.getObject( … , LocalDate.class ) ;
捕获当前日期。这需要一个时区。对于任何给定时刻,全球各地的日期都会因时区而异。
ZoneId z = ZoneId.of( "America/Edmonton" ) ; // Or perhaps `ZoneOffset.UTC`?
LocalDate today = LocalDate.now( z ) ;
比较。
if ( ld.isBefore( today ) ) { … }