算法,用于计算基于频率的一系列未来日期的算法、频率、日期、未来

由网友(爷丶独霸后宫)分享简介:我工作的一个支付调度该公司计划从 N 基于任意开始日期和一个一组频率(的每日,每周,每月,等付款...),并正在寻求一个通用的算法,这样做的。I'm working on a payment scheduler which plans out n payments based on an arbitrary star...

我工作的一个支付调度该公司计划从 N 基于任意开始日期和一个一组频率(的每日,每周,每月,等付款...),并正在寻求一个通用的算法,这样做的。

I'm working on a payment scheduler which plans out n payments based on an arbitrary start date and one of a set of frequencies (daily, weekly, monthly, etc...) and am seeking a general purpose algorithm for doing so.

我试图这样做,由外壳的频率,并根据需要加入一定数目的天,周,月的蛮力方法。这适用于大多数的目的。

I have attempted a brute force means of doing this, by casing the frequency and adding a certain number of days, weeks, months as needed. This works for most purposes.

在哪里失败是当任意开始日期是本月28日之后,频率为每月一次的地方,每年的,尤其是像每月的第一天和最后的每个月的频率。因为天29,30和31不会出现在所有个月,将每月像日期('2013年10月31号) - > addMonth(1)有联合国predictable结果。由于不添加个月像日期(2014年1月31日) - >。addDays(30),再次,由于二月份受到不必要的短

Where it fails is when the arbitrary start date is after the 28th of a month and the frequency is somewhere between monthly and annually, especially for frequencies like 'first of each month' and 'last of each month'. Because days 29, 30, and 31 do not appear on all months, adding a month like date('2013-10-31')->addMonth(1) has unpredictable results. As does adding months like date('2014-01-31')->addDays(30), again, due to February being unnecessarily short.

有没有通用的解决这个问题没有令人发指的复杂情况下,我需要通过任何一个月移动任何给定频率?

Is there a general solution to this problem without the hideously complex cases I need for moving any given frequency through any given month?

积分为PHP,但如果需要,我可以翻译。

Bonus points for PHP, but I can translate if needed.

推荐答案

添加了一个月,等等,烦恼,由于不同的月份长度,着实刺激。

The "add a month", etc., annoyance due to different month lengths is, indeed, irritating.

该解决方案,如果您有PHP> = 5.2,是的 DateTime类。

The solution, if you have PHP >= 5.2, is the DateTime class.

虽然它是简单的使用这个类来获得完全的控制,它不是的完全的小事。

Though it is simple to use this class to obtain total control, it is not entirely trivial.

下面是正确的code一个版本到一个月增加。

Here is one version of correct code to add a month.

// Variables defining the start date
// Example only - this could be any valid date
$year = '2013';
$month = '01';
$day = '31';

// set to the desired starting date and time
$the_date = new DateTime($year . '-' . $month . '-' . $day);

// Jump to the first day of this month
$the_date->modify("first day of this month");

// add 14 days, so we'll land on the 15th
$the_date->add(new DateInterval("P14D"));

// add 1 month - guaranteed to work!
$the_date->add(new DateInterval("P1M"));

// calculate how many days to add to 15 to get back to the **day** we started with...
// (as an integer, regardless of whether it is a valid day of the current month)
$number_days_to_add_back = intval($day) - 15;

// determine the last day of the month stored in $the_date
$test_last_date = clone $the_date;
$test_last_date->modify("last day of this month");
$day_last = $test_last_date->format('j'); // This provides the day, 01-31

// Test if adding $number_days_to_add_back runs past
// the end of the month; if so, adjust it so it won't run past
// the last day of the month
if (15 + $number_days_to_add_back > intval($day_last)) {
    $number_days_to_add_back = intval($day_last) - 15;
}

// Now make the final adjustment
$the_date->modify("" . $number_days_to_add_back . " day");

// Test it - a month has been added
$test = date_format($the_date, 'Y-m-d');
阅读全文

相关推荐

最新文章