You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Date::Manip::Recur处理月末重复日期缺失问题求助

解决Date::Manip::Recur生成还款日期时小月缺失的问题

问题分析

当设置的还款日为29/30/31号时,Date::Manip::Recur遇到没有对应日期的月份(如2月)会直接跳过该月份的日期——模块文档明确说明,为了性能不会自动修正无效日期,而是返回undef。要实现自动适配当月最后有效日期的需求,需要手动处理每个月份的日期构造逻辑。

解决方案

放弃直接依赖Recur的自动生成逻辑,改为遍历每个目标月份,手动构造还款日:若指定日期在当月无效,则自动替换为当月最后一天,再筛选出在起止日期范围内的日期。

修改后的代码

#!/usr/bin/perl

use strict;
use warnings;

use Date::Manip::Date;
use DateTime::Format::Strptime;
use String::Util qw(trim);

my $reoccur_date = 30;

# 创建起止日期对象
my $start_manip = Date::Manip::Date->new();
my $end_manip = Date::Manip::Date->new();

$start_manip->parse_format('%d/%m/%Y', '29/10/2023');
$end_manip->parse_format('%d/%m/%Y', '28/09/2024');

# 转换为DateTime对象方便日期操作
my $dt_format = DateTime::Format::Strptime->new(
    pattern   => '%Y%m%d%H:%M:%S',
    on_error  => 'croak',
);
my $start_dt = $dt_format->parse_datetime(trim($start_manip->value));
my $end_dt = $dt_format->parse_datetime(trim($end_manip->value));

my @dates_reoccur;

# 初始化当前日期为起始月的还款日(若起始日晚于还款日则从下月开始)
my $current_dt = $start_dt->clone();
if ($current_dt->day > $reoccur_date) {
    $current_dt->add(months => 1);
}
# 尝试设置还款日,无效则替换为当月最后一天
eval {
    $current_dt->set(day => $reoccur_date);
};
$current_dt->set(day => $current_dt->month_length) if $@;

# 遍历所有符合范围的月份
while ($current_dt <= $end_dt) {
    push @dates_reoccur, $current_dt->clone() if $current_dt >= $start_dt;
    
    # 进入下一个月并调整还款日
    $current_dt->add(months => 1);
    eval {
        $current_dt->set(day => $reoccur_date);
    };
    $current_dt->set(day => $current_dt->month_length) if $@;
}

# 输出结果
my $dates_found = @dates_reoccur;
print "There are $dates_found list members\n";

foreach my $dt (@dates_reoccur){
    print "Found date: " . $dt->strftime('%d %B %Y') . "\n";
}

关键逻辑说明

  • 手动遍历每个月份,彻底避免Date::Manip::Recur跳过无效日期的问题
  • 通过eval捕获设置无效日期的异常,自动调用month_length获取当月最后一天进行替换
  • 提前判断起始日与还款日的先后关系,避免生成早于起始时间的无效提醒

内容的提问来源于stack exchange,提问作者bsddude

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 09:12:42