X   Сообщение сайта
(Сообщение закроется через 3 секунды)



 

Здравствуйте, гость (

| Вход | Регистрация )

2 страниц V   1 2 >
Открыть тему
Тема закрыта
> Время. Отчет времени от определенной даты
Sunrise_mw
Sunrise_mw
Topic Starter сообщение 4.12.2009, 19:26; Ответить: Sunrise_mw
Сообщение #1


После долгой паузы в PHP пришлось заново за него взяться. Возникла проблема, как отсчитать время от определенной даты? на php.net просмотрел страничку посвщенной функции date(); но увы, за отсчет ничего не нашел.

Есть допустим дата 2009 05 08 (yyyy-mm-dd) нужно посчитать сколько дней, месяцев, лет прошло.

Подскажите плиз
0
Вернуться в начало страницы
 
Ответить с цитированием данного сообщения
ZiTosS
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]


Поблагодарили: (1)
Вернуться в начало страницы
 
Ответить с цитированием данного сообщения
Eugene_hb
Eugene_hb
сообщение 5.12.2009, 5:55; Ответить: Eugene_hb
Сообщение #3


Предложенный ZiTosS вариант хорошо подойдет там, где не нужна высокая точность (например, сколько времени прошло с момента регистрации на форуме).
Но т.к. этот алгоритм считает, что в месяце 31 день, а год всегда состоит из 365 дней, то в некоторых случаях можно и не досчитаться нескольких дней. Например, с 16.02.2009 до 17.03.2009 г. согласно общепринятого календаря прошло чуть больше месяца. А по мнению этого скрипта месяца еще не пройдет.
И смотря по специфике задачи, недостаток этих нескольких дней может быть весьма критичен.


Поблагодарили: (2)
Вернуться в начало страницы
 
Ответить с цитированием данного сообщения
Sunrise_mw
Sunrise_mw
Topic Starter сообщение 5.12.2009, 12:27; Ответить: Sunrise_mw
Сообщение #4


Тогда из-за разности в днях, нужно каждый месяц отдельно описывать?
Вернуться в начало страницы
 
Ответить с цитированием данного сообщения
Eugene_hb
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]


Поблагодарили: (2)
Вернуться в начало страницы
 
Ответить с цитированием данного сообщения
ZiTosS
ZiTosS
сообщение 6.12.2009, 1:29; Ответить: ZiTosS
Сообщение #6


EugeneM, молодца. А мне что-то стало лень вспоминать високосные и месяцы с разными днями. Мой вариант конечно не точный, тут уж на вкус и цвет :blink:
Вернуться в начало страницы
 
Ответить с цитированием данного сообщения
Sunrise_mw
Sunrise_mw
Topic Starter сообщение 6.12.2009, 2:19; Ответить: Sunrise_mw
Сообщение #7


Спасибо, классно работает! Но. Не умеет работать с с числами, если в первой дате переменные $year1, $month1, $day1 имеют числа большие чем числа в переменных $year2, $month2, $day2. То есть если $month1 = 12 , а $month2 = 6 то скрипт не работает.
Вернуться в начало страницы
 
Ответить с цитированием данного сообщения
Eugene_hb
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
Sunrise_mw
Topic Starter сообщение 7.12.2009, 0:35; Ответить: Sunrise_mw
Сообщение #9


Но вот щас $year1 = $year2, то есть обе 2009, то результ выдает -1. Если $year1 = 2008, а $year2 = 2009 , то результат 0. Если $year1 = 2009, а $year2 = 2008 , то результат -2.
Вернуться в начало страницы
 
Ответить с цитированием данного сообщения
Eugene_hb
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) - а это противоречит условиям.


Поблагодарили: (1)
Вернуться в начало страницы
 
Ответить с цитированием данного сообщения
2 страниц V   1 2 >
Открыть тему
Тема закрыта
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0


Свернуть

> Похожие темы

  Тема Ответов Автор Просмотров Последний ответ
Горячая тема (нет новых ответов) Вы тратите собственное время зря?
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


 



RSS Текстовая версия Сейчас: 29.3.2024, 16:39
Дизайн