Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Miesiące
Forum PHP.pl > Forum > PHP
NuLL
Hi all :-)

Mam dwie daty w formacie timestampa. Jak pobrać wszystkie miesiące zawarte pomiędzy nimi. aarambo.gif Łatwo by było, gdyby miesiące miały tą samą ilość dni - ale nie mają. Jakieś pomysły, sugestie...?

EDIt - juz prawie wykombinowalem tak wiec temat jest do skasowania.

BTW. Czemu nie mozna skasowac wlasnorecznie napisanego tematu ?
tiraeth
Jak wykombinowałeś to pokaż skrypt smile.gif Może się niektórym przydać na tym forum.

OT: Jak usuniesz posta to temat zostaje usunięty smile.gif Proste nie ? snitch.gif
dr_bonzo
2. Jesli nie ma zadnych dodatkowych postow to mozna usunac swoj -- i zarazem temat

1.
Kod
$pierwsza data ---> $druga_data
while ( $loop_date < $druga_data )
{
$loop_date = strtotime() zwieksz o jeden miesiac i dodaj do tablicy
}

jesli ostatni element tablicy jest wiekszy niz $druga_data (moze byc jescze tylko rowny) to go usun

ew. wloz na poczatek $pierwsza data jesli ma tam byc


$pierwsza_data = 2005-04-20
$duga_data = 2005-07-10
$x[ 0 ] = 2005-05-20
$x[ 1 ] = 2005-06-20
$x[ 3 ] = 2005-07-20; // za duza, wiec ja usuwasz
no i dodajesz 2005-04-20 jesli potrzebujesz (unshift() chyba)
Bora
pobierasz ale skąd? z bazy pliku ?
jak z bazy proponuje
  1. SELECT *
  2. FROM TABLE WHERE date > '.$from.' AND date < '.$to.' ORDER BY date

jeżeli pliki to zamieniłbym na time() i podobnie jak powyżej.
NuLL
@Bora: nie - mam dwa timestampy miedzy ktorymi muse wynalesc wszystkie miesiace i zwrocic jest np. w postaci tablicy.

@dr_bonzo - ale miesiące maja różnią liczbę dni. I możesz jakiś pominąc - twój pomysł się wykasztani jeśli różnica timestampow jest duza smile.gif

Algorytm wkleje za niedługą chwilę.
nospor
  1. <?php
  2. $date1='2004-03-10';$date2='2004-06-16';
  3. $date1=strtotime($date1);$date2=strtotime($date2);
  4. while (date('n',$date1)<=date('n',$date2))
  5. {
  6. echo date('F',$date1);
  7. $date1=strtotime('+1 month',$date1);
  8. }
  9.  
  10. ?>
bendi
Kod nospora bierze pod uwage tylko miesiace pomijajac lata, a oto moje rozwiazanie:
  1. <?
  2. $iTime1 = mktime( 0,0,0,12,3,2004 );
  3. $iTime2 = mktime( 0,0,0,3,1,2005 );
  4.  
  5. //sprowadzamy obie daty do pierwszego dnia miesiaca
  6. $iTime1 = mktime( 0,0,0,date('n',$iTime1),1,date('Y',$iTime1 ) );
  7. $iTime2 = mktime( 0,0,0,date('n',$iTime2),1,date('Y',$iTime2 ) );
  8.  
  9. //wybieramy mniejsza z nich i inicjujemy zmienna tymczasowa przechowujaca czas
  10. $iTempDate = min( $iTime1, $iTime2 );
  11.  
  12. //zachowujemy pierwotna ilosc miesiecy oraz ta potrzebna w petli
  13. $iMonthStart = $iMonthCurrent = date( 'n', $iTempDate );
  14.  
  15. //przechodzimy przez daty dopoki wieksza z dat jest wieksza od aktualnej
  16. while( max( $iTime1, $iTime2 ) > $iTempDate ) {
  17. //no i tworzymy aktualna date zwiekszajac licznik miesiaca (wazne - rok musi pozostac staly !!)
  18. $iTempDate = mktime( 0,0,0,++$iMonthCurrent,1,date( 'Y', min( $iTime1, $iTime2 ) ) );
  19. }
  20. echo $iMonthCurrent-$iMonthStart, ' ', date( 'd-m-Y', $iTempDate );
  21. ?>
nospor
bendi ma rację. Nie pomyślałem o latach. Ale to żaden problem. Nowy skrypt z małą poptawką:
  1. <?php
  2.  
  3. $date1='2004-03-10';$date2='2005-06-16';
  4. $date1=strtotime($date1);$date2=strtotime($date2);
  5. while (date('Y',$date1)<date('Y',$date2) || (date('Y',$date1)==date('Y',$date2) && date('n',$date1)<=date('n',$date2)))
  6. {
  7. echo date('F',$date1);
  8. $date1=strtotime('+1 month',$date1);
  9. }
  10.  
  11.  
  12. ?>
dr_bonzo
Wystarczy porownac timestampy -- a nie bawic sie osobno z miesiacami i latami
  1. <?php
  2. $d1 = '2005-11-20';
  3. $d2 = '2006-03-15'; // pokaze nov, dec, jan, feb,
  4. //$d2 = '2006-03-20'; // pokaze tez march
  5.  
  6. $date_1 = strtotime( $d1 );
  7. $date_2 = strtotime( $d2 );
  8.  
  9.  
  10. $temp_date = $date_1;
  11. $arrMonths = array();
  12. $arrMonths[] = $temp_date;
  13. print( $d1 . ' | ' . $d2 . &#092;"<br />nn\" );
  14.  
  15. while ( $temp_date < $date_2 )
  16. {
  17. $temp_date = strtotime( '+1 month', $temp_date );
  18. //print( date( 'F', $temp_date ) . \"<br />n\" );
  19. $arrMonths[] = date( 'F', $temp_date );
  20. }
  21.  
  22. print_r( $arrMonths );
  23. print( &#092;"----------------------------<br />n\" );
  24.  
  25. if ( $temp_date > $date_2 ) // usuwa ost miesiac bo liczba dnia miesiaca moze byc juz za duza
  26. {
  27. print( 'Usunieto miesiac ' . array_pop( $arrMonths ) . &#092;"<br />n\" );
  28. }
  29.  
  30. print_r( $arrMonths );
  31.  
  32. ?>


@NuLL: gdzie ma sie wykaszanic?
nospor
@dr_bonzo aby nie usuwać ostatniego miesiąca, wystarczy tylko dodawać do tablicy przed zwiększeniem o miesiać.

Moj poprawiony kod (po uwzględnieniu uwagi dr_bonzo):
  1. <?php
  2.  
  3. $date1='2004-03-10';$date2='2005-06-16';
  4. $date1=strtotime($date1);$date2=strtotime($date2);
  5. while ($date1<=$date2)
  6. {
  7. echo date('F',$date1);
  8. $date1=strtotime('+1 month',$date1);
  9. }
  10.  
  11. ?>
bendi
Prownanie timestamp'ow moze byc nie wystarczajace zeby uzyskac pewne wyniki otoz uzywajac definicji dat z kodu dr_bonzo
Kod
$d1 = '2005-11-10';
$d2 = '2006-03-15'; // pokaze nov, dec, jan, feb,

Dadza inny wynik niz
Kod
$d1 = '2005-11-20';
$d2 = '2006-03-15'; // pokaze nov, dec, jan, feb,

A przeciez roznica miesiecy sie nie zmienila. Wlasnie dlatego moj kod sprowadza wszystko do pierwszego dnia miesiaca i pozniej dopiero porownoje.
nospor
@bendi masz rację
Wracam do porzedniego kodu:
  1. <?php
  2.  
  3. $date1='2005-11-10';$date2='2006-03-15';
  4. $date1=strtotime($date1);$date2=strtotime($date2);
  5. while (date('Y',$date1)<date('Y',$date2) || (date('Y',$date1)==date('Y',$date2) && date('n',$date1)<=date('n',$date2)))
  6. {
  7. echo date('F',$date1);
  8. $date1=strtotime('+1 month',$date1);
  9. }
  10.  
  11. ?>


teraz twoje obie próby dadzą ten sam wynik
dr_bonzo
Moj kod byl ok, bo zalozenia mialem innne: liczylem CALE miesiace miedzy datami.
(specjalnie dalem te daty $d2 = '2006-03-15' i $d2 = '2006-03-20' zeby to pokazac)
A jesli uwzgledniamy niepelne miesiace to kod powienien wygladac tak:
{no i tu mial byc kod, ale nie wyszlo smile.gif, moze umieszcze pozniej}

Pozniej nastalo, strzezcie sie:P
  1. <pre><?php
  2. /**
  3.  * Wyznacza wszystkie miesiace (jakie wystepuja -- nie pelne miesiace) miedzy dwoma datami
  4.  */
  5. $d1 = '2005-11-30';
  6. $d2 = '2006-02-13';
  7.  
  8. $date_1 = strtotime( $d1 );
  9. $date_2 = strtotime( $d2 );
  10.  
  11. // przejscie do pierwszego dnia tego miesiaca, dzieki temu obliczenia sa prostsze
  12. $date_1 = mktime( 1, 0, 0, date( 'n', $date_1 ), 1, date( 'Y', $date_1 ) );
  13. $date_2 = mktime( 1, 0, 0, date( 'n', $date_2 ), 1, date( 'Y', $date_2 ) );
  14.  
  15.  
  16. $arrMonths = array();
  17. $temp_date = $date_1;
  18.  
  19. while ( $temp_date <= $date_2 )
  20. {
  21. $arrMonths[] = date( 'F', $temp_date );
  22. $temp_date = strtotime( '+1 month', $temp_date );
  23. }
  24.  
  25. print( $d1 . ' --&gt; ' . date( 'Y-m-d', $date_1 ) . '<br />' );
  26. print( $d2 . ' --&gt; ' . date( 'Y-m-d', $date_2 ) . '<br />' );
  27. print_r( $arrMonths );
  28.  
  29. ?></pre>
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.