算法,用于计算基于频率的一系列未来日期的 [英] Algorithm for calculating a series of future dates based on a frequency

查看:112
本文介绍了算法,用于计算基于频率的一系列未来日期的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我工作的一个支付调度该公司计划从 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');

这篇关于算法,用于计算基于频率的一系列未来日期的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆