获取前几个月的第一个和最后一个日期

Get previous months first and last date

我需要从数据库中查询上个月的数据。所以我需要 上个月的第一个和最后一个日期 才能进行“介于” SQL 查询。

当然,第一次约会总是从 1 开始,但硬编码看起来很糟糕。同样硬编码 日期格式“dd-MM-yyyy” 似乎是一种不好的做法。 有没有更简单的方法来做到这一点?现在我有一些业余但有效的东西,像这样:

        YearMonth thisMonth    = YearMonth.now();
        YearMonth lastMonth    = thisMonth.minusMonths(1);
        
        String dd = Integer.toString(lastMonth.lengthOfMonth());
        String mm = Integer.toString(lastMonth.getMonthValue());
        String yyyy = Integer.toString(lastMonth.getYear());
        
        String startDate = "01-" + mm + "-" + yyyy;
        String endDate = dd + "-" + mm + "-" + yyyy;

        System.out.println("startDate: " + startDate);
        System.out.println("endDate: " + endDate);

So I need the first and last date of previous month to be able to make the "between" SQL query.

您可以直接在数据库中进行计算。在 Oracle 中,您可以获得上个月的第一天和最后一天作为 dates,如下所示:

where mydate between add_months(trunc(sysdate, 'month'), -1)
                 and last_day(add_months(trunc(sysdate, 'month'), -1))

不过,一般来说,您并不真的需要 between 和最后一天。您可以使用半开间隔 - 这也更安全,因为它考虑了属于该月最后一天的日期:

where mydate >= add_months(trunc(sysdate, 'month'), -1)
  and mydate <  trunc(sysdate, 'month')

将 LocalDate 对象传输到您的 SQL 查询

不要将第一个和最后一个日期作为字符串发送到您的数据库查询。自 JDBC 4.2 传输 LocalDate 个对象。 Java 中有几种计算方法。我的首选方式是像您在问题中所做的那样使用 YearMonth

    YearMonth thisMonth    = YearMonth.now(ZoneId.of("Atlantic/Reykjavik"));
    YearMonth lastMonth    = thisMonth.minusMonths(1);
    
    LocalDate startDate = lastMonth.atDay(1);
    LocalDate endDate = lastMonth.atEndOfMonth();
    
    System.out.println("startDate: " + startDate);
    System.out.println("endDate: " + endDate);

今天运行时输出:

startDate: 2020-11-01
endDate: 2020-11-30

传给JDBC:

    String query = "select * from your_table where your_date_col between ? and ?;";
    PreparedStatement statement = yourDatabaseConnection.prepareStatement(query);
    statement.setObject(1, startDate);
    statement.setObject(2, endDate);

以下调节器任您使用:

  1. TemporalAdjusters.firstDayOfMonth()

  2. TemporalAdjusters.lastDayOfMonth()

演示:

import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;

class Main {
    public static void main(String[] args) {
        // Today's date
        LocalDate today = LocalDate.now();

        LocalDate oneMonthAgo = today.minusMonths(1);

        LocalDate firstDateOfLastMonth = oneMonthAgo.with(TemporalAdjusters.firstDayOfMonth());
        LocalDate lastDateOfLastMonth = oneMonthAgo.with(TemporalAdjusters.lastDayOfMonth());

        System.out.println(firstDateOfLastMonth);
        System.out.println(lastDateOfLastMonth);
    }
}

输出:

2020-11-01
2020-11-30

Trail: Date Time.

了解有关现代日期时间 API 的更多信息

如何在 JDBC 4.2 中使用 Java 8 Date and Time API (JSR-310):

String query = "SELECT column_name(s)
                FROM table_name
                WHERE column_name BETWEEN ? AND ?";

PreparedStatement st = conn.prepareStatement(query);
st.setObject(1, firstDateOfLastMonth);
st.setObject(2, lastDateOfLastMonth);
st.executeQuery();

//...Process ResultSet 

st.close();

您可以使用 TemporalAdjusters.firstDayOfMonth() 和 TemporalAdjusters.lastDayOfMonth()

参考文档:https://docs.oracle.com/javase/8/docs/api/java/time/temporal/TemporalAdjusters.html#lastDayOfMonth--

LocalDate currentDate = LocalDate.now();
LocalDate currentDateLastMonth = LocalDate.of(
                currentDate.getYear(), 
                currentDate.getMonth().minus(1), 
                currentDate.getDayOfMonth());

LocalDate firstDayOfMonth = currentDateLastMonth.with(TemporalAdjusters.firstDayOfMonth());
LocalDate lastDayOfMonth = currentDateLastMonth.with(TemporalAdjusters.lastDayOfMonth());

System.out.println("first day of the month "+ firstDayOfMonth);
System.out.println("last day of the month "+ lastDayOfMonth);