如何每月将 table 中的计数器列重置为零

How to reset a counter column to zero in a table every month

我有一列名为

duty_counter存放每个月的工作人数。 reset_date 存储上次重置日期。

我使用以下 sql 得到 reset_date 并将其设置为当前日期

select distinct TO_CHAR(reset_date,'DD')as day,TO_CHAR(reset_date,'HH24')as hour,TO_CHAR(reset_date,'mi')as min from hr_mgt;

将此处的输出视为日期 12,小时 18,分钟 00。

假设在每个月的 5 日,duty_counter_column 应该只重置为零一次。

    Calendar reqDate = Calendar.getInstance();
    reqDate.set(Calendar.DAY_OF_MONTH, Integer.valueOf(4));
    reqDate.set(Calendar.HOUR_OF_DAY, Integer.valueOf(23));
    reqDate.set(Calendar.MINUTE, Integer.valueOf(59));
    Calendar currDate = Calendar.getInstance();
    currDate.set(Calendar.DAY_OF_MONTH, Integer.valueOf(12));
    currDate.set(Calendar.HOUR_OF_DAY, Integer.valueOf(18));
    currDate.set(Calendar.MINUTE, Integer.valueOf(00));
    System.out.println("reqDate :  " + reqDate.toString());
    System.out.println("currDate :  " + currDate.toString());
    if (currDate.equals(reqDate) || currDate.after(reqDate)) {
        System.out.println("Reached the Req Date , reset the counter");
    }

但目前每当调度程序在每个月的 5 号 运行 秒后,它都会重置值班计数器。如何使此代码在每个月的 5 日仅 运行 一次?

感谢您的建议和时间。

java.time

您使用的Calendarclass早就过时了。 JSR 310,现代 Java 日期和时间 API 也称为 java.time,通常更易于使用。

/** On what day of each month should the count be reset? 1..28 */
private static final int DAY_OF_MONTH_TO_RESET_COUNT = 5;
/** In what time zone should above day-of-month be interpreted? */
private static final ZoneId timeZone = ZoneId.of("Asia/Pontianak");

public static void resetIfDue() {
    // substitute reset_date from DB here
    LocalDate lastResetDate = LocalDate.of(2017, Month.DECEMBER, 5);

    LocalDate nextResetDate = lastResetDate.plusMonths(1)
                                .withDayOfMonth(DAY_OF_MONTH_TO_RESET_COUNT);
    LocalDate today = LocalDate.now(timeZone);
    // "not after today" means today or before today
    if (! nextResetDate.isAfter(today)) {
        System.out.println("Reset the count and update the reset_date in the database");
    }
}

您是否同意此代码不仅比您的代码更短,而且更优雅、更易读?

在 Java 1.7 上,获取 ThreeTen Backport 并从 org.threeten.bp 包中导入 classes,上面的代码将起作用。从数据库中获取 java.sql.Date 的重置日期;例如,ResultSet.getDate() 会给你。然后立即使用 DateTimeUtils.toLocalDate(sqlDateFromDatabase) 将其转换为上述代码的 LocalDate 。使用 Java 8 您可以直接从结果集中获得 LocalDate

您需要决定是否将重置日期更新为计算出的下一个重置日期、今天的日期或其他日期。我把它留给你了。

我建议您为时区敏感的操作(例如获取今天的日期)指定明确的时区。所以如果不是 Asia/Pontianak 请填写你的时区。要使用 JVM 的时区设置,请使用 ZoneId.systemDefault()。请注意,该设置可能会被您程序的其他部分或同一 JVM 中的其他程序 运行 更改,因此如果有一天您发现更新发生得太早或太晚,这可能是错误的来源.

链接