Динамическое определение даты и условия - PullRequest
1 голос
/ 16 сентября 2011

Я строю небольшую комбинацию классов, чтобы вычислить точную дату начала семестра. Правила определения начала семестра сводятся к следующему:

The monday of week number ## and after dd-mm-yyyy date

ie: for winter its week number 2 and it must be after the january 8th of that year

Я создаю класс ресурсов, который содержит эти данные для всех семестров (всего 4). Но теперь я столкнулся с проблемой, основанной на public holidays. Поскольку некоторые из них могут быть в понедельник, в этих случаях мне нужно узнать дату вторника.

Проблема, над которой я сейчас работаю, заключается в следующем:

The target semester begins on or after august 30 and must be on week 35. 

Я также должен учитывать государственный праздник, который случается в первый понедельник сентября.

Условие в терминах PHP следующее

if (date('m', myDate) == 9 // if the month is september
    && date('w', myDate) == 1 // if the day of the week is monday
    && date('d', myDate) < 7 // if we are in the first 7 days of september
)

Как лучше всего «сформулировать» это как условие и сохранить его в массиве?

EDIT

Возможно, я не был достаточно ясен, найти дату здесь не проблема. Фактическая проблема заключается в сохранении условия в массиве конфигурации, которое выглядит следующим образом:

$_ressources = array(
    1 => array(
        'dateMin' => '08-01-%',
        'weekNumber' => 2,
        'name' => 'Winter',
        'conditions' => array()
    ),
    2 => array(
        'dateMin' => '30-04-%',
        'weekNumber' => 18,
        'name' => 'Spring',
        'conditions' => array()
    ),
    3 => array(
        'dateMin' => '02-07-%',
        'weekNumber' => 27,
        'name' => 'Summer',
        'conditions' => array()
    ),
    4 => array(
        'dateMin' => '30-08-%',
        'weekNumber' => 35,
        'name' => 'Autumn',
        'conditions' => array("date('m', %date%) == 9  && date('w', %date%) == 1 && date('d', %date%) < 7")
    )
);

Проблема, с которой я сейчас столкнулся, заключается в том, что мне придется использовать функцию eval(), чего я бы не хотел.

Ответы [ 2 ]

1 голос
/ 16 сентября 2011

Вы сказали:

Целевой семестр начинается 30 августа или позже и должен быть на 35 неделе.

Если это так, вы можете просто проверить на неделючисло.

if(date('W', myDate) == 35)

Или, если ваше условие тестирования правильное, тогда вы должны сравнить номер дня до 7, начиная с 1.

if((date('m', myDate) == 9 // september
    && date('w', myDate) == 1 // monday
    && date('d', myDate) <= 7 // first 7 days of september
)

И затем в операторе if, как только вы нашлипонедельник, который был бы в порядке, ЕСЛИ это не выходной, сделайте это

if(...){
    while(!array_search (myDate, aray_of_public_holidays))
        date_add($myDate, date_interval_create_from_date_string('1 days'));
}

Здесь array_of_public_holidays содержит список выходных дней.

Обновление с кодом
Следующий код должен работать для ваших целей

<?php
    // array with public holidays
    $public_holidays = array(/* public holidays */);

    // start on 30th august
    $myDate = new DateTime('August 30');

    // loop till week number does not cross 35
    while($myDate->format('W') <= 35){
        // if its a monday
        if($myDate->format('w') == 1){
            // find the next date not a public holiday
            while(array_search($myDate, $public_holidays))
                $myDate->add(date_interval_create_from_date_string('1 days'));

            // now myDate stores the valid semester start date so exit loop
            break;
        }
        // next date
        $myDate->add(date_interval_create_from_date_string('1 days'));
    }

    // now myDate is the semester start date
?>

Обновление в соответствии с обновленным вопросом
Следующий код должен работать для ваших нужд.Вам не нужно хранить условие в вашем массиве как код PHP.Следующий код показывает, как это можно сделать

// semester conditions
$sem_conditions = array(
    1 => array(
        'dateMin' => '08-01-%',
        'weekNumber' => 2,
        'name' => 'Winter'
    ),
    2 => array(
        'dateMin' => '30-04-%',
        'weekNumber' => 18,
        'name' => 'Spring'
    ),
    3 => array(
        'dateMin' => '02-07-%',
        'weekNumber' => 27,
        'name' => 'Summer'
    ),
    4 => array(
        'dateMin' => '30-08-%',
        'weekNumber' => 35,
        'name' => 'Autumn'
    )
);

// array with public holidays format (d-M)
$public_holidays = array('05-09', '10-01');

// store sem starts
$sem_starts = array();

// for each semester
foreach($sem_conditions as $sem){
    // start date
    $myDate = date_create_from_format('d-m', substr($sem['dateMin'], 0, -2));

    // loop till week number does not cross $sem['weekNumber']
    while($myDate->format('W') <= $sem['weekNumber']){
        // if its a monday
        if($myDate->format('w') == 1){
            // find the next date not a public holiday
            while(array_search($myDate->format('d-m'), $public_holidays) !== false)
                $myDate->add(date_interval_create_from_date_string('1 days'));

            // now myDate stores the valid semester start date so exit loop
            break;
        }
        // next date
        $myDate->add(date_interval_create_from_date_string('1 days'));
    }

    // add to sem starts
    $sem_start[$sem['name']] = $myDate->format('d-m-Y');
}

var_dump($sem_start);
1 голос
/ 16 сентября 2011

Целевой семестр начинается 30 августа или позже и должен быть на неделе 35

Начало семестра - минимальная дата между 35 и 30 августа:

$week35 = new DateTime("January 1 + 35 weeks");
$august30 = new DateTime("August 30");

$start = min($week35, $august30);

В качестве альтернативы:

$start = min(date_create("January 1 + 52 weeks"), date_create("August 30"));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...