Форум dkLab и Denwer
Здесь общаются Web-разработчики.
Генеральный спонсор:
Хостинг «Джино»

Функция построения календаря (Gapter)
Author Message
Gapter
Участник форума



Joined: 29 Mar 2004
Posts: 49
Карма: 5
   поощрить/наказать


PostPosted: Sun Jul 04, 2004 12:48 pm ()
   Post subject: Функция построения календаря
Reply with quote

Данная функция строит календарь на указанный месяц указанного года. Также, можно вызывать функцию без параметров - в таком случае она построит календарь для текущего месяца и года. Можно указать только месяц - в этом случае год будет взят также текущий.

Функция возвращает массив с правильным расположением только чисел месяца в порядке от понедельника к воскресению. Графическое представление массива - на картинке в прикреплённом файле.
Code (php): скопировать код в буфер обмена
function build_calendar($month = false, $year = false)
{
        if ($year == false)
        {
                $year = date (www.php.net/date)("Y");
        }
        if ($month == false)
        {
                $month = date (www.php.net/date)("m");
        }
        $seconds_in_a_day = 60*60*24;
        $start_day= mktime (www.php.net/mktime)(0, 0, 0, $month, 1, $year);       
        $date_array = getdate (www.php.net/getdate)($start_day);
        $calendar = array (www.php.net/array)();
        for($i = 0; $i < 6; $i++)
        {
                for ($j = 0; $j < 7; $j++)
                {
                        $current_day = getdate (www.php.net/getdate)($start_day);
                        if ($current_day["mon"] != $date_array["mon"]) break;
                        if ($current_day["wday"]-1 == $j && $current_day["wday"] != 0)
                        {
                                $calendar[$i][$j] = $current_day["mday"];
                                $start_day += $seconds_in_a_day;
                        }
                        else if ($current_day["wday"] == 0 && $j == 6)
                        {
                                $calendar[$i][$j] = $current_day["mday"];
                                $start_day += $seconds_in_a_day;
                        }
                        else
                        {
                                $calendar[$i][$j] = "";
                        }
                }
        }
        return $calendar;
}
Пример использования:
Code (php): скопировать код в буфер обмена
$month = 7;
$year = 2004;

$calendar = build_calendar($month, $year);
// эквивалентно для текущей даты: $calendar = build_calendar($month);
// эквивалентно для текущей даты: $calendar = build_calendar();

$months = Array (www.php.net/array)(1 => 'Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь',
                                'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь');
$days = Array (www.php.net/array)('П', 'В', 'С', 'Ч', 'П', 'С', 'В');

// построение таблицы для вывода указанного месяца и года
echo (www.php.net/echo) "<table border='0' width='10%' cellspacing='2' cellpadding='2'>";
echo (www.php.net/echo) "<tr><td colspan='7'><p align='center'>".$months[$month]." $year</td><tr>";

// вывод дней недели
foreach($days as $day)
{
        echo (www.php.net/echo) "<td>$day</td>";
}
echo (www.php.net/echo) "</tr>";

// проход массива для вывода чисел месяца в таблицу
foreach ($calendar as $v1)
{
        echo (www.php.net/echo) "<tr>";
        foreach ($v1 as $v2)
        {
                echo (www.php.net/echo) "<td>$v2</td>";
        }
        echo (www.php.net/echo) "</tr>";
}
echo (www.php.net/echo) "</table>";



calendar.gif
 Description:
Графическое представление массива с числами месяца
 Filesize:  14.2 KB
 Viewed:  1555 Time(s)

calendar.gif
Щелкните, чтобы посмотреть полноразмерное изображение.





Last edited by Gapter on Sun Jul 11, 2004 10:55 am; edited 2 times in total
Back to top
View user's profile Send private message
Rumata
Профессионал



Joined: 17 Aug 2003
Posts: 1850
Карма: 185
   поощрить/наказать


PostPosted: Sun Jul 04, 2004 5:27 pm (спустя 4 часа 39 минут)
   Post subject:
Reply with quote

как-то сложноват алгоритм. можно упростить.

еще предлагаю функцию оформить так:
Code (php): скопировать код в буфер обмена
function build_calendar($month=false, $year=false)
{
//
}
чтобы можно было использовать для текущего года и месяца:
Code (php): скопировать код в буфер обмена
$actual = build_calendar(7, 2004);
$default = build_calendar();
Back to top
View user's profile Send private message
Gapter
Участник форума



Joined: 29 Mar 2004
Posts: 49
Карма: 5
   поощрить/наказать


PostPosted: Sun Jul 11, 2004 10:56 am (спустя 6 дней 17 часов 28 минут)
   Post subject:
Reply with quote

Rumata:
Спасибо за идею! Сделал!
Back to top
View user's profile Send private message
Rumata
Профессионал



Joined: 17 Aug 2003
Posts: 1850
Карма: 185
   поощрить/наказать


PostPosted: Sun Jul 11, 2004 1:07 pm (спустя 2 часа 11 минут)
   Post subject:
Reply with quote

я позволю повториться... алгоритм сложный. можно упростить.

1. у вас тело самого внутренного цикла выполняется 42 раза. то есть сложность алгоритма n=42, можно упростить до n<=42. конечно эта задача не очнь серьезная
2. как следствие првого пункта - функция getdate вызывается 42 раза. хотя это и не критично, но...
3. 4 проверки во внутреннем цикле - это много
4. (ну это уж просто придирка)
Code (php): скопировать код в буфер обмена
static (www.php.net/static) $seconds_in_a_day = 60*60*24;
- так лучше

не часто найдет применение эта функция, но если улучшить есть возможность, надо ее использовать
Back to top
View user's profile Send private message
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 413
   поощрить/наказать


PostPosted: Sun Jul 11, 2004 3:38 pm (спустя 2 часа 30 минут)
   Post subject:
Reply with quote

Функция из новой книги:
Code (php): скопировать код в буфер обмена
// Функция формирует двумерный массив, представляющий собой
// календарь на указанный месяц и год. Массив состоит из строк,
// соответствующих неделям. Каждая строка - массив из семи
// элементов, которые равны числам (или пустой строке, если
// данная клетка календаря пуста).
function makeCal($year, $month) {
  // Получаем номер дня недели для 1 числа месяца. Корректируем
  // его, чтобы воскресенье соответствовало числу 7, а не числу 0.
  $wday = JDDayOfWeek (www.php.net/jddayofweek)(GregorianToJD (www.php.net/gregoriantojd)($month, 1, $year), 0);
  if ($wday == 0) $wday = 7;
  // Начинаем с этого числа в месяце (если меньше нуля
  // или больше длины месяца, тогда в календаре будет пропуск).
  $n = - ($wday - 2);
  $cal = array (www.php.net/array)();
  // Цикл по строкам.
  for ($y=0; $y<6; $y++) {
    // Будущая строка. Вначале пуста.
    $row = array (www.php.net/array)();
    $notEmpty = false;
    // Цикл внутри строки по дням недели.
    for ($x=0; $x<7; $x++, $n++) {
      // Текущее число >0 и < длины месяца?
      if (checkdate (www.php.net/checkdate)($month, $n, $year)) {
        // да. Заполняем клетку.
        $row[] = $n;
        $notEmpty = true;
      } else {
        // Нет. Клетка пуста.
        $row[] = "";
      }
    }
    // Если в данной строке нет ни одного непустого элемента,
    // значит, месяц кончился.
    if (!$notEmpty) break;
    // Добавляем строку в массив.
    $cal[] = $row;
  }
  return $cal;
}

// Формируем календарь на текущий месяц.
$now = getdate (www.php.net/getdate)();
$cal = makeCal($now['year'], $now['mon']-1);
$cal = makeCal(1990, 10);
?>
<!-- Шаблон вывода календаря. -->
<table border=1>
  <tr>
    <td>Пн</td>
    <td>Вт</td>
    <td>Ср</td>
    <td>Чт</td>
    <td>Пт</td>
    <td>Сб</td>
    <td style="color:red">Вс</td>
  </tr>
  <!-- цикл по строкам -->
  <?foreach ($cal as $row) {?>
    <tr>
      <!-- цикл по столбам -->
      <?foreach ($row as $i=>$v) {?>
        <!-- воскресенье - "красный" день -->
        <td style="<?=$i==6? 'color:red' : ''?>">
          <?=$v? $v : "&nbsp;"?>
        </td>
      <?}?>
    </tr>
  <?}?>
</table>
Back to top
View user's profile Send private message Send e-mail
Rumata
Профессионал



Joined: 17 Aug 2003
Posts: 1850
Карма: 185
   поощрить/наказать


PostPosted: Sun Jul 11, 2004 5:03 pm (спустя 1 час 24 минуты)
   Post subject:
Reply with quote

я тут тоже решил попытать свои силы:) в этом решении
Code (php): скопировать код в буфер обмена
<?

/**
* Expanded version of `getdate' function
* The same as `getdate' but adds "days" (days in month) and "today" for current date
*/

function xgetdate($timestamp=false)
{
    $today = time (www.php.net/time)();
    if ($timestamp === false) $timestamp = $today;
    $date = getdate (www.php.net/getdate)($timestamp);
    $date["days"] = (int)date (www.php.net/date)("t", $timestamp);
    if (date (www.php.net/date)("Ym", $timestamp) == date (www.php.net/date)("Ym", $today)) {
        $date["today"] = (int)date (www.php.net/date)("d", $today);
    }
    return $date;
}

/**
* Returns 2D-array of days for `$month' of `$year' arranged by week days
* If `$month' or `$year' are not established an info gets from the system time
*/

function build_calendar($month=false, $year=false)
{
    if (!$year) $year = date (www.php.net/date)("Y");
    if (!$month) $month = date (www.php.net/date)("m");
    $actual_date = xgetdate(mktime (www.php.net/mktime)(23, 59, 59, $month, 1, $year));

    $first_day = $actual_date["wday"];
    if (!$first_day--) $first_day = 6; // more usual: 0 - Monday, 6 - Sunday
    foreach (range (www.php.net/range)(1, $first_day) as $i) $calendar[0][] = "";

    $last_day = $actual_date["days"] + $first_day;
    foreach (range (www.php.net/range)($first_day, $last_day - 1) as $i) {
        $calendar[$i / 7][$i % 7] = $i - $first_day + 1;
    }

    $last_week = count (www.php.net/count)($calendar) - 1;
    $full_week = ($last_week + 1) * 7;
    while ($full_week --> $last_day) $calendar[$last_week][] = "";

    if (@$actual_date["today"]) $calendar["today"] = $actual_date["today"];
    return $calendar;
}

?>
собственно в модуле объявлена новая функция xgetdate, ее задача вернуть абсолютно тоже самое, что и стандартная функция getdate, но при этом может возвращать еще один элемент
"today" для текущего месяца текущего года и
"days" - количество дней в месяце

результат работы build_calendar - 2D-массив, строки - недели, столбцы - дни недели, элементы массива - дни месяца, пустые значения соответствуют дням другого месяца (опционально массив содержит ассоциативный ключ "today" для текущего месяца и года)
Back to top
View user's profile Send private message
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 413
   поощрить/наказать


PostPosted: Sun Jul 18, 2004 1:13 am (спустя 6 дней 8 часов 10 минут)
   Post subject:
Reply with quote

Все способы, использующие на том или ином этапе timestamp-ы, можно считать немного ущербными: они позволяют составлять календарь только в интервале от 1970 до 20xx года (xx не помню). Книжный же способ этого недостатка лишен.
Rumata wrote:
while ($full_week --> $last_day)
Красиво. (-:
Back to top
View user's profile Send private message Send e-mail
Rumata
Профессионал



Joined: 17 Aug 2003
Posts: 1850
Карма: 185
   поощрить/наказать


PostPosted: Sun Jul 18, 2004 5:08 am (спустя 3 часа 54 минуты)
   Post subject:
Reply with quote

Дмитрий Котеров wrote:
Красиво
ага - пока одно стремится к другому

Дмитрий. вопрос такой. я не рассматривал функции работы с каледнарями, видимо можно совместить Ваш и мой вариант?
Back to top
View user's profile Send private message
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 413
   поощрить/наказать


PostPosted: Sun Jul 18, 2004 5:04 pm (спустя 11 часов 55 минут)
   Post subject:
Reply with quote

Вероятнее всего, можно.
Back to top
View user's profile Send private message Send e-mail
@dept
Заглянувший



Joined: 01 Feb 2005
Posts: 1
Карма: 0
   поощрить/наказать


PostPosted: Wed Mar 02, 2005 9:36 am (спустя 7 месяцев 14 дней 16 часов 32 минуты; написано за 4 минуты 16 секунд)
   Post subject: Вопрос по календарю
Reply with quote

Дмитрий, Ваш календарь - лучшее из всего что я видел. Он прост и в какой-то степени универсален.
Но... Есть вопрос - а Ваша функция в каком диапазоне "годов" работает?
Если вызывать make_cal с параметром year=1, еще работает...
А если (ну вот есть такая извращенная необходимость) вызвать ее с параметром год=0, или даже отрицательным (это кстати, будет считаться "до р.х."?) то она уже не работает...
Хотя функции юлианский->григорианский везде в качестве входных данных имеют тип INT, должны же вроде "схавать" и нулевые, и отрицательные значения...
А как исправить функцию, чтоб и с этими значениями работала?
Back to top
View user's profile Send private message
@paul
Guest





Карма: 388
   поощрить/наказать


PostPosted: Sun Mar 20, 2005 2:04 am (спустя 17 дней 16 часов 27 минут; написано за 1 минуту 18 секунд)
   Post subject:
Reply with quote

уважаемые, не пинайте пожалуйста, подскажите как можно знать последний день любого не текущего месяца любого года?
спасибо
Back to top
Woodo
Заглянувший



Joined: 26 Jul 2004
Posts: 13
Карма: 2
   поощрить/наказать

Location: Тбилиси

PostPosted: Sun Mar 20, 2005 4:16 am (спустя 2 часа 12 минут; написано за 3 минуты 48 секунд)
   Post subject:
Reply with quote

@paul

если установлен calendar extension (www.php.net/manual/en/ref.calendar.php) to можете исползовать функцию cal_days_in_month() (www.php.net/manual/en/function.cal-days-in-month.php), или можете написат такую функцыю:
Code (php): скопировать код в буфер обмена
function days_in_month($month, $year) {
  $num = 31;
  while (!checkdate (www.php.net/checkdate)($month, $num, $year)){
    $num--;
  }
  return $num;
}

echo (www.php.net/echo) days_in_month(7, 2001);
Back to top
View user's profile Send private message
@paul
Guest





Карма: 388
   поощрить/наказать


PostPosted: Sun Mar 20, 2005 5:55 am (спустя 1 час 38 минут; написано за 4 минуты 43 секунды)
   Post subject:
Reply with quote

спасибо! а так же самое простое:
Code (php): скопировать код в буфер обмена
$Day = date (www.php.net/date)("t",mktime (www.php.net/mktime)(0, 0, 0, $Month, 1, $Year))
где в качестве месяца и года передаете нужные вам значения...
Back to top
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 413
   поощрить/наказать


PostPosted: Sun Mar 20, 2005 3:20 pm (спустя 9 часов 25 минут; написано за 12 секунд)
   Post subject:
Reply with quote

Так только с 1970-го года!
Back to top
View user's profile Send private message Send e-mail
urisoft
Заглянувший



Joined: 20 May 2005
Posts: 12
Карма: 2
   поощрить/наказать


PostPosted: Fri May 20, 2005 8:35 pm (спустя 2 месяца 5 часов 14 минут; написано за 4 минуты 13 секунд)
   Post subject:
Reply with quote

Способ вызова и результат работы данного кода абсолютно идентичны двум вышепреведенным функциям build_calendar.
Основное отличие это простота реализации и самое быстрое время работы среди всех представленных. По сравнению с первым - в 3 раза быстрее.
Минусы те-же: год только с 1970-го
Code (php): скопировать код в буфер обмена
function build_calendar($month=false,$year=false)
{
        if ($year == false) $year = date (www.php.net/date)("Y");
        if ($month == false) $month = date (www.php.net/date)("m");

        $rows = explode (www.php.net/explode)(",",date (www.php.net/date)('t,w', mktime (www.php.net/mktime)(0, 0, 0, $month, 1, $year)));

        if (!$rows[1]--) $rows[1] = 6;

        $calendar = array (www.php.net/array)();

        for ( $i=0; $i < $rows[1]; $i++ ) $calendar[0][$i] = "";

        $week = 0;
        for ($day=1; $day <= $rows[0]; $day++)
        {
                $calendar[$week][$rows[1]] = $day;
                $rows[1]++;
                if ($rows[1] > 6)
                {
                        $rows[1] = 0;
                        $week ++;
                }
        }

        if ($rows[1] != 0)
        {
                while ($rows[1] <= 6) $calendar[$week][$rows[1]++] = "";
        }

        return $calendar;
}
Если не в тему, можно удалить
Back to top
View user's profile Send private message
Артемий
Участник форума



Joined: 09 Apr 2004
Posts: 48
Карма: 1
   поощрить/наказать

Location: Москва

PostPosted: Mon Jul 04, 2005 8:56 am (спустя 1 месяц 14 дней 12 часов 21 минуту; написано за 6 минут 44 секунды)
   Post subject:
Reply with quote

А вот мой вариант ф-ции построения календаря.
1. Работает быстрее всех выше перечисленных!!!
2. Не использует вложенные циклы, да и вообще не использует циклы.
3. Работает с датами раньше 1970 года
Code (php): скопировать код в буфер обмена
function my_makeCal($year, $month)
{
        //массив хранящий в себе кол-во дней в каждом месяце кроме февраля
        $day_amount = array (www.php.net/array)(1 => '31', 3 => '31', 4 => '30', 5 => '31', 6 => '30',
                        7 => '31', 8 => '31', 9 => '30', 10 => '31', 11 => '30',
                        12 => '31' );
//если сейчас любой месяц кроме февраля
if ($month!==2)
        $day_in_month = $day_amount[$month];
else
{
        if ($year % 4==0) $day_in_month = 29;//високосный год
        else              $day_in_month = 28;
}
        // Получаем номер дня недели для 1 числа месяца.
        // Получаем номер дня недели для последнего дня месяца.
        // Корректируем их, чтобы воскресенье соответствовало числу 7, а не числу 0.
        $wday = JDDayOfWeek (www.php.net/jddayofweek)(GregorianToJD (www.php.net/gregoriantojd)($month, 1, $year), 0);
        $wday_end_month = JDDayOfWeek (www.php.net/jddayofweek)(GregorianToJD (www.php.net/gregoriantojd)($month, $day_in_month, $year), 0);
        if ($wday == 0) $wday = 7;
        if ($wday_end_month == 0) $wday_end_month = 7;
        //Заполняем массив календаря значениями от 1 до последнего числа месяца
        $cal   = range (www.php.net/range)(1, $day_in_month);
        //если первое число не совпадает с понедельником
        if ($wday > 1)
        {
                $cal_b = array_fill (www.php.net/array_fill)(0, $wday-1, '');//заполняет массив пустыми значениями
                $cal   = array_merge (www.php.net/array_merge)($cal_b,$cal);//склеиваем массив дат и пустышку
        }
        //если последнее число не совпадает с воскресеньем
        if($wday_end_month < 7)
        {
                $cal_e = array_fill (www.php.net/array_fill)(0, 7-$wday_end_month, '');//заполняет массив пустыми значениями
                $cal   = array_merge (www.php.net/array_merge)($cal, $cal_e);//склеиваем массив дат и пустышку
        }
return $cal;
}

$cal = my_makeCal(2005, 6);
//делит массив на отрезки по семь дней
$cal = array_chunk (www.php.net/array_chunk)($cal, 7);

?>

<!-- Шаблон вывода календаря. -->
<table border=1>
  <tr>
    <td>Пн</td>
    <td>Вт</td>
    <td>Ср</td>
    <td>Чт</td>
    <td>Пт</td>
    <td>Сб</td>
    <td style="color:red">Вс</td>
  </tr>
  <!-- цикл по строкам -->
  <?foreach ($cal as $row) {?>
    <tr>
      <!-- цикл по столбам -->
      <?foreach ($row as $i=>$v) {?>
        <!-- воскресенье - "красный" день -->
        <td style="<?=$i==6? 'color:red' : ''?>">
          <?=$v? $v : "&nbsp;"?>
        </td>
      <?}?>
    </tr>
  <?}?>
</table>
Back to top
View user's profile Send private message Send e-mail
Rumata
Профессионал



Joined: 17 Aug 2003
Posts: 1850
Карма: 185
   поощрить/наказать


PostPosted: Mon Jul 04, 2005 3:02 pm (спустя 6 часов 6 минут; написано за 51 секунду)
   Post subject:
Reply with quote

urisoft, Артемий ваши примеры идеологически мало отличаются от приведенных ранее решений.

модераторы - разделите тему
Back to top
View user's profile Send private message
Guest






Карма: 388
   поощрить/наказать


PostPosted: Mon Jul 04, 2005 4:39 pm (спустя 1 час 37 минут; написано за 59 секунд)
   Post subject:
Reply with quote

Rumata wrote:
модераторы - разделите тему
Идеологически мало отличаются???

Все применяют циклы притом вложенные, а я работу с массивами!!!!
Back to top
2ko
Участник форума



Joined: 07 Mar 2005
Posts: 28
Карма: 1
   поощрить/наказать

Location: Гомель / Беларусь

PostPosted: Wed Jul 06, 2005 5:37 pm (спустя 2 дня 58 минут; написано за 4 минуты 6 секунд)
   Post subject:
Reply with quote

Артемий А как в Ваш цикл быстрее будет прибавить листинг месяцев(с подсветкой дня и изменением года)?

« (prevmonth) январь » (nextmonth)
   1 2 3 4 5 6 7
 ...
Back to top
View user's profile Send private message
Артемий
Участник форума



Joined: 09 Apr 2004
Posts: 48
Карма: 1
   поощрить/наказать

Location: Москва

PostPosted: Thu Jul 07, 2005 10:01 am (спустя 16 часов 23 минуты; написано за 4 минуты 21 секунду)
   Post subject:
Reply with quote

2ko
Коряво выглядит, но работает!!!
Листает календарь по месяцам и высвечивает текущую дату цветом!!!

скрипт называется calendar.php
Code (php): скопировать код в буфер обмена
<?
function my_makeCal($year, $month)
{
        $day_amount = array (www.php.net/array)(1 => '31', 2 =>array(false => '28', true => '29'), 3 => '31', 4 => '30',
                                                5 => '31', 6 => '30', 7 => '31', 8 => '31', 9 => '30', 10 => '31',
                                                11 => '30', 12 => '31' );
if ($month==2)
        $day_in_month = $day_amount[$month][$year % 4==0];
else
        $day_in_month = $day_amount[$month];
          // Получаем номер дня недели для 1 числа месяца.
          // Получаем номер дня недели для последнего дня месяца.
        // Корректируем их, чтобы воскресенье соответствовало числу 7, а не числу 0.
        $wday = JDDayOfWeek (www.php.net/jddayofweek)(GregorianToJD (www.php.net/gregoriantojd)($month, 1, $year), 0);
        $wday_end_month = JDDayOfWeek (www.php.net/jddayofweek)(GregorianToJD (www.php.net/gregoriantojd)($month, $day_in_month, $year), 0);
        if ($wday == 0) $wday = 7;
        if ($wday_end_month == 0) $wday_end_month = 7;
    //Заполняем массив календаря значениями от 1 до последнего числа месяца
        $cal   = range (www.php.net/range)(1, $day_in_month);
        //если первое число не совпадает с понедельником
            if ($wday>1)
            {
                $cal_b = array_fill (www.php.net/array_fill)(0, $wday-1, '');//заполняет массив пустыми значениями
                $cal   = array_merge (www.php.net/array_merge)($cal_b,$cal);//склеиваем массив дат и пустышку
            }
        //если последнее число не совпадает с воскресеньем
                if($wday_end_month < 7)
                {
                        $cal_e = array_fill (www.php.net/array_fill)(0, 7-$wday_end_month, '');//заполняет массив пустыми значениями
                        $cal   = array_merge (www.php.net/array_merge)($cal, $cal_e);//склеиваем массив дат и пустышку
                }
$cal = array_chunk (www.php.net/array_chunk)($cal, 7);
return $cal;
}

if (!isset (www.php.net/isset)($year) and !isset (www.php.net/isset)($month))
{
        $year  = date (www.php.net/date)("Y");
        $month = date (www.php.net/date)("n");
}

$month_name = Array (www.php.net/array)(1 => 'Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь',
                                                'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь');

$cal = my_makeCal($year, $month);


//выясняем какой будет следующий месяц и какой предидущий и тоже узнаем про год!
if(($month)==1)
{
    $month_minus = 12;
    $year_minus  = $year-1;
    $month_plus  = 2;
    $year_plus   = $year;
}
elseif(($month)==12)
{
    $month_minus = 11;
    $year_minus  = $year;
    $month_plus  = 1;
    $year_plus   = $year+1;
}
else
{
    $month_minus = $month-1;
    $year_minus  = $year;
    $month_plus  = $month+1;
    $year_plus   = $year;
}

?>

<!-- Шаблон вывода календаря. -->
<center>
<a href="calendar.php?year=<?=$year_minus;?>&month=<?=$month_minus;?>">&lt;&lt;</a>&nbsp;<?=$year."&nbsp;".$month_name[$month];?>&nbsp;<a href="calendar.php?year=<?=$year_plus;?>&month=<?=$month_plus;?>">&gt;&gt;</a>
<table border=1>
  <tr>
    <td>Пн</td>
    <td>Вт</td>
    <td>Ср</td>
    <td>Чт</td>
    <td>Пт</td>
    <td>Сб</td>
    <td style="color:red">Вс</td>
  </tr>
  <!-- цикл по строкам -->
  <?foreach ($cal as $row) {?>
    <tr>
      <!-- цикл по столбам -->
      <?foreach ($row as $i=>$v) {?>
        <!-- воскресенье - "красный" день -->
        <td style="<?=$i==6? 'color:red' : ''?>">
//если дата из массива совпадает с текущей то она зеленая!!!
          <?=$v? ((($v==date (www.php.net/date)('d')) and ($year==date (www.php.net/date)('Y')) and ($month==date (www.php.net/date)('n')))?"<b style='color:green'>".$v."</b>" : $v) : "&nbsp;"?>
        </td>
      <?}?>
    </tr>
  <?}?>
</table>
</center>
Back to top
View user's profile Send private message Send e-mail
Guest






Карма: 388
   поощрить/наказать


PostPosted: Sat Aug 20, 2005 9:24 am (спустя 1 месяц 12 дней 23 часа 23 минуты; написано за 7 минут 39 секунд)
   Post subject:
Reply with quote

Господа! Есть другое, более математическое решение проблемы последнего дня месяца:
Code (php): скопировать код в буфер обмена
<?php
function getML($theYear, $theMonth)
{
        $oneDay = 1000 * 60 * 60 * 24; //для ясности
        $thisMonth = date (www.php.net/date)("U", mktime (www.php.net/mktime)(0, 0, 0, $theMonth, 1, $theYear));
        $nextMonth = date (www.php.net/date)("U", mktime (www.php.net/mktime)(0, 0, 0, $theMonth+1, 1, $theYear));
        $len = ($nextMonth - $thisMonth)/$oneDay;
        return round (www.php.net/round)($len*1000);
}
?>
Плюсы: компактно, универсально, работает.
Минусы: Привязано к "Эпохе Юникс" и работает только с 1970 года, сильнее нагружает процессор.
(По правде говоря, врядле кому нибудь понадобиться календарь, который работает до 1970, да и процессор оно грузит неимоверно мало)
Back to top
Роганов Иван
Заглянувший



Joined: 19 Aug 2005
Posts: 9
Карма: -1
   поощрить/наказать

Location: DKO3

PostPosted: Sat Aug 20, 2005 9:27 am (спустя 2 минуты; написано за 1 минуту 7 секунд)
   Post subject:
Reply with quote

Пардон, про getML - это мое, забыл зарегистрироваться.

P.S. Оно еще и корректно февраль обрабатывает
Back to top
View user's profile Send private message
Rumata
Профессионал



Joined: 17 Aug 2003
Posts: 1850
Карма: 185
   поощрить/наказать


PostPosted: Mon Aug 22, 2005 7:33 pm (спустя 2 дня 10 часов 5 минут; написано за 48 секунд)
   Post subject:
Reply with quote

Роганов Иван
читать до посинения www.php.net/date
Code (php): скопировать код в буфер обмена
$days_in_months = date (www.php.net/date)('t', $time);
Back to top
View user's profile Send private message
Роганов Иван
Заглянувший



Joined: 19 Aug 2005
Posts: 9
Карма: -1
   поощрить/наказать

Location: DKO3

PostPosted: Tue Aug 23, 2005 11:32 am (спустя 15 часов 58 минут; написано за 2 минуты 36 секунд)
   Post subject:
Reply with quote

Rumata wrote:
Роганов Иван
читать до посинения www.php.net/date
Code (php): скопировать код в буфер обмена
$days_in_months = date (www.php.net/date)('t', $time);
Мдя, до смерти 8-), просто прикол в том, что я, как грязный паттернщик, использовал такой яваСкрипт, а потом, не долго мучаясь, перевел его на PHP.
Back to top
View user's profile Send private message
aross
Участник форума



Joined: 14 May 2005
Posts: 48
Карма: 3
   поощрить/наказать

Location: Вологда

PostPosted: Fri Aug 26, 2005 10:25 am (спустя 2 дня 22 часа 53 минуты; написано за 13 минут 18 секунд)
   Post subject:
Reply with quote

Артемий wrote:
Code (php): скопировать код в буфер обмена
//если сейчас любой месяц кроме февраля
if ($month!==2)
        $day_in_month = $day_amount[$month];
else
{
        if ($year % 4==0) $day_in_month = 29;//високосный год
        else              $day_in_month = 28;
}
Code (php): скопировать код в буфер обмена
if ($month==2)
        $day_in_month = $day_amount[$month][$year % 4==0];
else
        $day_in_month = $day_amount[$month];
Маленькое уточнение: год високосный, если номер года делится нацело на 4 и НЕ ДЕЛИТСЯ НА 100
Code (php): скопировать код в буфер обмена
//
if ($month!==2)
        $day_in_month = $day_amount[$month];
else
{
        if (( $year % 4 == 0 )&&( $year % 100 != 0 ) || ( $year % 400 = 0 )) //
                $day_in_month = 29;
        else
                $day_in_month = 28;
}
Code (php): скопировать код в буфер обмена
if ($month==2)
        $day_in_month = $day_amount[$month][( $year % 4 == 0 )&&( $year % 100 != 0 ) || ( $year % 400 = 0 )];
else
        $day_in_month = $day_amount[$month];
:)
19.09 Немного поправил код, учитывая года, делящиеся на 400 (совсем про них забыл (-:) Вроде должно работать

Last edited by aross on Mon Sep 19, 2005 11:33 am; edited 2 times in total
Back to top
View user's profile Send private message
Евгений Галашин
Модератор



Joined: 29 Dec 2003
Posts: 1861
Карма: 31
   поощрить/наказать


PostPosted: Thu Sep 08, 2005 12:16 pm (спустя 13 дней 1 час 50 минут)
   Post subject:
Reply with quote


М

Ветка выделена в отдельную тему «О високосных годах»,
расположенную в форуме Прочее (08 Сентября 2005, 12:16).
Back to top
View user's profile Send private message
Guest






Карма: 388
   поощрить/наказать


PostPosted: Fri Oct 21, 2005 8:02 am (спустя 1 месяц 12 дней 19 часов 46 минут; написано за 1 минуту 10 секунд)
   Post subject:
Reply with quote

Quote:
Хотя функции юлианский->григорианский везде в качестве входных данных имеют тип INT, должны же вроде "схавать" и нулевые, и отрицательные значения...
Переменные типа int могут содержать также отрицательные значения и нули!Не путать с unsigned int!
Back to top
Guest






Карма: 388
   поощрить/наказать


PostPosted: Fri Jan 13, 2006 3:55 pm (спустя 2 месяца 23 дня 7 часов 52 минуты; написано за 1 минуту 34 секунды)
   Post subject:
Reply with quote

А возможно-ли дополнить функции календаря для проверки определенных периодов? Ну когда я функции могу передать массив дат, или лучше именно диапазон дат, а на выходе у массива появятся аттрибуты вхождения или нет в заданный массив.
Back to top
Guest






Карма: 388
   поощрить/наказать


PostPosted: Fri Apr 03, 2009 9:54 am (спустя 3 года 2 месяца 20 дней 17 часов 59 минут; написано за 32 секунды)
   Post subject:
Reply with quote

Функция косячит для октября 2009 ...
Back to top
bæv
Модератор «Дзена»



Joined: 27 Aug 2003
Posts: 7275
Карма: 9987
   поощрить/наказать


PostPosted: Mon Apr 20, 2009 11:00 pm (спустя 17 дней 13 часов 5 минут)
   Post subject:
Reply with quote


М

Ветка выделена в отдельную тему «êàëåíäàðü»,
расположенную в форуме Мусоропровод (20 Апреля 2009, 23:00).
Back to top
View user's profile Send private message
Guest






Карма: 388
   поощрить/наказать


PostPosted: Thu Jun 04, 2009 3:01 pm (спустя 1 месяц 13 дней 16 часов 1 минуту; написано за 55 секунд)
   Post subject:
Reply with quote

Артемий, спасибо за календарь! Только по месяцам он не листает =(
Back to top
Display posts from previous:   
Post new topic   Reply to topic All times are GMT + 3 Hours
Page 1 of 1    Email to a Friend.
You cannot post new topics in this forum. You cannot reply to topics in this forum. You cannot edit your posts in this forum. You cannot delete your posts in this forum. You cannot vote in polls in this forum. You cannot attach files in this forum. You can download files in this forum.
XML