1

2 週間のブロック時間枠で支払われるサービスがあります。

  • 03-31-13 から 04-13-13
  • 04-14-13 から 04-27-13
  • 04-28-13 から 05-11-13

1 週間前に終了した支払い期間を反映する日付に人々に支払いをしたいと考えています。

  • 04-20-13 は、03-31-13 から 04-13-13 の期間の支払い日になります。
  • 05-04-13 は、04-14-13 から 04-27-13 の期間の支払い日になります。

などなど

PHP でこれらの期間とやや「ローリング」間隔を計算する最良の方法は何でしょうか? 私はDateTimeクラスに慣れていませんが、これにどのようにアプローチするかはよくわかりません。

基本的には、ユーザーが請求ページにアクセスしたときに、現在の期間と、以前に終了した期間の支払いがいつ期待できるかを伝えることができるという考え方です。

アップデート

さらに考えてみると、どこから始めればよいかを知るために、何らかの基準点を与える必要があるように思えます。何か案は?

ありがとうございました。

更新 #2 - 私の解決策

class PayoutDate {

    const PERIOD_LENGTH     = 14;

    public static $now;
    public static $refStart;

    public static $currentMonth;
    public static $currentYear;

    public static $currPeriodStart;
    public static $currPeriodEnd;

    public static $prevPeriodStart;
    public static $prevPeriodEnd;

    public function initialize(Controller $controller) {

        self::$now                  = new DateTime();

        self::$currentMonth         = self::$now->format('m');
        self::$currentYear          = self::$now->format('Y');

        self::$refStart             = new DateTime("10/20/2013");

    }

    public function getPreviousPeriodStart() {

        $daysIntoCurrentPeriod      = ((int)self::$now->diff(self::$refStart)->format('%a') % self::PERIOD_LENGTH);

        self::$prevPeriodStart      = new DateTime('2 weeks ago');
        self::$prevPeriodStart->sub(new DateInterval('P'.$daysIntoCurrentPeriod.'D'));

        return self::$prevPeriodStart;

    }

    public function getPreviousPeriodEnd() {

        $daysLeftCurrentPeriod      = self::PERIOD_LENGTH - ((int)self::$now->diff(self::$refStart)->format('%a') % self::PERIOD_LENGTH) - 1;

        self::$prevPeriodStart      = new DateTime('2 weeks ago');
        self::$prevPeriodStart->add(new DateInterval('P'.$daysLeftCurrentPeriod.'D'));

        return (self::$prevPeriodStart);

    }

    public function getCurrentPeriodStart() {

        $daysIntoCurrentPeriod      = (int)self::$now->diff(self::$refStart)->format('%a') % self::PERIOD_LENGTH;

        self::$currPeriodStart      = clone self::$now;
        self::$currPeriodStart->sub(new DateInterval('P'.$daysIntoCurrentPeriod.'D'));

        return (self::$currPeriodStart);


    }

    public function getCurrentPeriodEnd() {

        $daysLeftCurrentPeriod      = self::PERIOD_LENGTH - ((int)self::$now->diff(self::$refStart)->format('%a') % self::PERIOD_LENGTH) - 1;

        self::$currPeriodEnd        = clone self::$now;
        self::$currPeriodEnd->add(new DateInterval('P'.$daysLeftCurrentPeriod.'D'));

        return (self::$currPeriodEnd);

    }

    public function getPreviousPeriodPayout() {

        $prevEnd = new DateTime(self::getPreviousPeriodEnd());

        return ($prevEnd->modify('next friday'));

    }

    public function getCurrentPeriodPayout() {

        $currentEnd = new DateTime(self::getCurrentPeriodEnd());

        return ($currentEnd->modify('next friday'));

    }



}

このソリューションへのフィードバックや改善を歓迎します:)

4

2 に答える 2

2

ええと、ある種の基準点が必要だというあなたの意見は正しいと思います。あなたの支払い期間の任意の開始時刻を選択します。それが過去であろうと未来であろうと関係ありません。また、支払い期間の長さを表す変数も必要になります。あとは、ちょっと計算してみるだけです。

$refStart = new DateTime('2013-03-31');
$periodLength = 14;

$now = new DateTime();

// do some modular arithmetic :)
$daysIntoCurrentPeriod = (int)$now->diff($refStart)->format('%a') % $periodLength;
$currentPeriodStart = clone $now;
$currentPeriodStart->sub(new DateInterval('P'.$daysIntoCurrentPeriod.'D'));

そのコードを実行する$currentPeriodStartと、現在の支払い期間の開始日が保存されます。(秒単位まで正確ではありませんが、日付は正確です。) 次に、そこから 14 日を減算して前の期間の開始を取得し、必要なものを加算/減算して給与日を取得できます。 .

このソリューションには、夏時間 (煩わしい場合があります) を使用できるという追加の利点がありDateTimeます。

于 2013-10-21T05:33:00.590 に答える
1

これは、いくつかのルールを使用して機能します。

  • 指定日の次の土曜日(給料日)を確定し、1週間を加算

要件に合わせていくつかの調整を行うことができます。

<?php
/*
 * Using:
 * http://stackoverflow.com/a/1485512/496176
 * http://www.php.net/manual/es/datetime.add.php
 */
date_default_timezone_set('Europe/London');
$interval = new DateInterval('P1W');

$payPeriod1 = new DateTime("2013-04-13");
$payPeriod1
  ->setISODate($payPeriod1->format("Y"), $payPeriod1->format("W"), 6)
  ->add($interval);
print "Pay day: " . $payPeriod1->format('Y-m-d') . "\n"; // Pay day: 2013-04-20

$payPeriod2 = new DateTime("2013-04-27");
$payPeriod2
  ->setISODate($payPeriod2->format("Y"), $payPeriod2->format("W"), 6)
  ->add($interval);
print "Pay day: " . $payPeriod2->format('Y-m-d') . "\n"; // Pay day: 2013-05-04 
?>
于 2013-10-21T05:12:26.210 に答える