Помощник
|
Время. Отчет времени от определенной даты |
Sunrise_mw
|
Сообщение
#1
|
||
|
|
||
|
|||
ZiTosS |
4.12.2009, 23:22;
Ответить: ZiTosS
Сообщение
#2
|
|
Sunrise, ничего сложного нет.
1) Нам надо получить текущую метку времени. Метка времени имеет тип int и число хранящееся в ней, это количество секунд прошедших с 1 января 1970 года; 2) Так же у нас есть дата в формате (YYYY-mm-dd), которую надо разбить, и так же получить по данным метку; 3) Нужно вычислить сначала годы, затем месяцы, затем дни и так далее. [php]<?php function getDateInterval($stringDate) { $pointNow = time(); // получили метку текущего времени $times = array('year' => 60*60*24*365, 'month' =>60*60*24*31, 'day' => 60*60*24); if( ereg("^([0-9]{4})\-([0-9]{2})\-([0-9]{2})$", $stringDate, $matchDate) ) // проверяем корректность даты и вырезаем годы месяцы дни { $year = intval($matchDate[0]); // вытаскиваем год, дополнительно переводя к целым(на всякий) $month = intval($matchDate[1]); // вытаскиваем месяц, дополнительно переводя к целым(на всякий) $day = intval($matchDate[2]); // вытаскиваем день, дополнительно переводя к целым(на всякий) } else return false; // если дата некорректна $pointDate = mktime(0, 0, 0, $month, $day, $year); // получили метку переданной даты $pointInterval = $pointDate > $pointNow ? $pointDate - $pointNow : $pointNow - $pointDate; // получили метку разности двух дат $returnDate = array(); // создаём пока пустой массив возвращаемой даты $returnDate['year'] = floor($pointInterval / $times['year']); // высчитываем годы $pointInterval = $pointInterval % $times['year']; // находим остаток $returnDate['month'] = floor($pointInterval / $times['month']); // высчитываем месяцы $pointInterval = $pointInterval % $times['month']; // находим остаток $returnDate['day'] = floor($pointInterval / $times['day']); // высчитываем дни $pointInterval = $pointInterval % $times['day']; // находим остаток return $returnDate; } // пример использования $date = getDateInterval("2008-12-12"); echo "С даты прошло<br>"; echo "Лет: {$date['year']}"; echo "Месяцев: {$date['month']}"; echo "Дней: {$date['day']}"; ?>[/php] |
|
|
Eugene_hb |
5.12.2009, 5:55;
Ответить: Eugene_hb
Сообщение
#3
|
|
Предложенный ZiTosS вариант хорошо подойдет там, где не нужна высокая точность (например, сколько времени прошло с момента регистрации на форуме).
Но т.к. этот алгоритм считает, что в месяце 31 день, а год всегда состоит из 365 дней, то в некоторых случаях можно и не досчитаться нескольких дней. Например, с 16.02.2009 до 17.03.2009 г. согласно общепринятого календаря прошло чуть больше месяца. А по мнению этого скрипта месяца еще не пройдет. И смотря по специфике задачи, недостаток этих нескольких дней может быть весьма критичен. |
|
|
Sunrise_mw
|
Сообщение
#4
|
|
Тогда из-за разности в днях, нужно каждый месяц отдельно описывать?
|
|
|
Eugene_hb |
5.12.2009, 14:25;
Ответить: Eugene_hb
Сообщение
#5
|
|
Ну зачем же каждый месяц, да еще и отдельно!
Сейчас набросал, посмотрел - вроде работает. На входе нужно чтобы: 1. $year1, $month1, $day1 - составляющие года, месяца и дня для первой даты. 2. $year2, $month2, $day2 - аналогично только для второй даты. 3. Вторая дата должна быть больше первой. На выходе получаем $deltaYear, $deltaMonth, $deltaDay - искомая разница в годах, месяцах и днях соответственно. [php]// Определяем разницу лет $deltaYear = ($month2 >= $month1) ? $year2-$year1 : $year2-$year1-1; // Определяем разницу месяцев if ($month2 >= $month1) $deltaMonth = ($day2 >= $day1) ? $month2-$month1 : $month2-$month1-1; else $deltaMonth = ($day2 >= $day1) ? $month2-$month1+12 : $month2-$month1+11; // Определяем разницу дней if ($day2 >= $day1) $deltaDay = $day2 - $day1; else $deltaDay = ($month2 == $month1) ? $day2-$day1 : $day2-$day1+days_in_month($month1, $year1);[/php] Используемая здесь функция days_in_month возвращает количество дней в месяце $month года $year. Выглядеть может, например, так: [php]function days_in_month($month, $year) { if ($month==2) return ((($year % 4 == 0) and ( (!($year % 100 == 0)) or ($year % 400 == 0))) ? 29 : 28 ); else if ( ($month==4) or ($month==6) or ($month==9) or ($month==11) ) return 30; else return 31; }[/php] |
|
|
ZiTosS |
6.12.2009, 1:29;
Ответить: ZiTosS
Сообщение
#6
|
|
EugeneM, молодца. А мне что-то стало лень вспоминать високосные и месяцы с разными днями. Мой вариант конечно не точный, тут уж на вкус и цвет
|
|
|
Sunrise_mw
|
Сообщение
#7
|
|
Спасибо, классно работает! Но. Не умеет работать с с числами, если в первой дате переменные $year1, $month1, $day1 имеют числа большие чем числа в переменных $year2, $month2, $day2. То есть если $month1 = 12 , а $month2 = 6 то скрипт не работает.
|
|
|
Eugene_hb |
6.12.2009, 2:50;
Ответить: Eugene_hb
Сообщение
#8
|
|
Почему не работает? При, например
[php]$year1 = 2000; $month1 = 12; $day1 = 1; $year2 = 2001; $month2 = 6; $day2 = 1;[/php] (т.е. с 1.12.2000 до 1.06.2001) выдает, как и положено 0 лет, 6 месяцев и 0 дней. Если поставить [php]$year1 = 2000; $month1 = 12; $day1 = 1; $year2 = 2000; $month2 = 6; $day2 = 1;[/php] то, действительно выдаст полную ерунду. Но! В этом случае 1-я дата соответствует 1.12.2000, а вторая - 1.06.2000. А одним из условий я упомянул, что вторая дата должна находиться позже первой. Если нужно чтобы разница определялась вне зависимости от того, какая дата идет по календарю раньше, а какая позже, то перед тем как вычленить из даты составляющие года, месяца и дня, сравните эти даты между собой и при необходимости поменяйте местами. |
|
|
Sunrise_mw
|
Сообщение
#9
|
|
Но вот щас $year1 = $year2, то есть обе 2009, то результ выдает -1. Если $year1 = 2008, а $year2 = 2009 , то результат 0. Если $year1 = 2009, а $year2 = 2008 , то результат -2.
|
|
|
Eugene_hb |
7.12.2009, 0:48;
Ответить: Eugene_hb
Сообщение
#10
|
|
И еще раз сейчас запустил. Никакого -1 не выводит.
Вот полный скрипт, который я запускал: [php]<?php // Будем находить разницу с 1.06.2009 до 1.12.2009 $year1 = 2009; $month1 = 6; $day1 = 1; // Соответствует 1.06.2009 $year2 = 2009; $month2 = 12; $day2 = 1; // Соответствует 1.12.2009 // Определяем разницу лет $deltaYear = ($month2 >= $month1) ? $year2-$year1 : $year2-$year1-1; // Определяем разницу месяцев if ($month2 >= $month1) $deltaMonth = ($day2 >= $day1) ? $month2-$month1 : $month2-$month1-1; else $deltaMonth = ($day2 >= $day1) ? $month2-$month1+12 : $month2-$month1+11; // Определяем разницу дней if ($day2 >= $day1) $deltaDay = $day2 - $day1; else $deltaDay = ($month2 == $month1) ? $day2-$day1 : $day2-$day1+days_in_month($month1, $year1); echo "Лет: $deltaYear, месяцев: $deltaMonth, дней: $deltaDay" ?>[/php] И вот что вывело: Лет: 0, месяцев: 6, дней: 0 Если вначале изменить [php]$year1 = 2009; $month1 = 12; $day1 = 1; // Соответствует 1.12.2009 $year2 = 2009; $month2 = 6; $day2 = 1; // Соответствует 1.06.2009[/php] То да, выведет -1. Но это всего лишь потому вторая дата (1.06.2009) находится раньше первой (1.12.2009) - а это противоречит условиям. |
|
|
|
Похожие темы
Тема | Ответов | Автор | Просмотров | Последний ответ | |
---|---|---|---|---|---|
Вы тратите собственное время зря? | 35 | metvekot | 2459 | 19.3.2024, 20:14 автор: MisterBit |
|
Странный трафик на сайте длительное время | 26 | TABAK | 7542 | 16.3.2024, 17:31 автор: Boymaster |
|
Сколько времени нужно для раскачки нового сайта? | 29 | metvekot | 7870 | 8.3.2024, 15:41 автор: malamut |
|
Продам скрипт rtb exchange suite - система перепродажи трафика dsp/ssp в реальном времени. | 4 | buypushplatform | 4145 | 12.10.2021, 15:29 автор: ULUD |
|
Чем монетизировать посетителей без определенной тематики и широким гео? | 16 | Mansurka | 3083 | 11.7.2021, 15:25 автор: kuprum |
Текстовая версия | Сейчас: 29.3.2024, 16:39 |