Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: zamiana daty w aktywny link
Forum PHP.pl > Forum > PHP
mb83
Witam,
Mam przykładowy tekst:
"Dzisiaj jest {2015-01-01} i nie pada śnieg"
i chcę napisać funkcję, która zamieni {2015-01-01} na <a href=/data/2015-01-01'>1 stycznia 2014 (czwartek)</a>.

czyli efekt będzie:
  1. Dzisiaj jest <a href=/data/2015-01-01'>1 stycznia 2014 (czwartek)</a> i nie pada śnieg


tylko nie wiem jak poprawnie skonstruować tą funkcję, która będzie wyszukiwać string, konwertować do formatu (1 stycznia ...) i zamieniać w link.

mam coś takiego tylko to jest dopiero początek i nie wiem co dalej:
  1. $pattern = '{2014-05-25}';
  2. $replacement = '<a href=\'2014-05-25\'>2014-05-25</a>';
  3. $subject = 'dzisiaj jest 2014-05-25';
  4. echo preg_replace($pattern, $replacement, $subject, -1 );


Można prosić o jakiś przykład? Będę wdzięczny za pomoc
trueblue
Tylko dokładnie taką datę będziesz zamieniał?
Podejrzewam, że nie. Poszukaj wyrażenie regularnego na taki format daty i użyj preg_replace_callback. Dzięki tej funkcji w callback wywołasz dla znalezionej daty inną funkcję, która zmieni ją na format "słowny", z tych stringów zmontujesz cały link.
mb83
generalnie będę zmieniał każdą datę w formacie {YYYY-MM-DD}.
A w jakiej kolejności tych funkcji używać?
Mam funkcję do zamiany dat na polskie nazwy:
  1. function dateV($format,$timestamp=null){
  2. $to_convert = array(
  3. 'l'=>array('dat'=>'N','str'=>array('Poniedziałek','Wtorek','Środa','Czwartek','Piątek','Sobota','Niedziela')),
  4. 'F'=>array('dat'=>'n','str'=>array('styczeń','luty','marzec','kwiecień','maj','czerwiec','lipiec','sierpień','wrzesień','październik','listopad','grudzień')),
  5. 'f'=>array('dat'=>'n','str'=>array('stycznia','lutego','marca','kwietnia','maja','czerwca','lipca','sierpnia','września','października','listopada','grudnia'))
  6. );
  7. if ($pieces = preg_split('#[:/.\-, ]#', $format)){
  8. if ($timestamp === null) { $timestamp = time(); }
  9. foreach ($pieces as $datepart){
  10. if (array_key_exists($datepart,$to_convert)){
  11. $replace[] = $to_convert[$datepart]['str'][(date($to_convert[$datepart]['dat'],$timestamp)-1)];
  12. }else{
  13. $replace[] = date($datepart,$timestamp);
  14. }
  15. }
  16. $result = strtr($format,array_combine($pieces,$replace));
  17. return $result;
  18. }
  19. }


tylko nie wiem w jakiej kolejności co i jak.

- pierwsze jest string, który ma w sobie szablon {YYYY-MM-DD}
- potem go trzeba znaleźć (jak?)
- potem skonwertować (dateV?)
- potem preg_replace_callback (jak użyć?)

dzięki za pomoc!
trueblue
  1. preg_replace_callback('wyrazenie_regularne_na_format {YYYY-MM-DD}', function($match){
  2. $data_tekstowa=funkcja_zmieniajaca_date_na_date_tekstowa($match[0]);
  3. return "<a href=\"/data/".$match[0]."\">".$data_tekstowa."</a>";
  4. },$string);
mb83
kurde, nie za bardzo mi to idzie :-)
  1. $string = "dzisiaj jest {2014-01-01}";
  2. preg_replace_callback('#{^(\d{4})-(\d{2})-(\d{2})?$}#', function($match){
  3. $data_tekstowa=dateV('j F Y', strtotime($match[0]));
  4. return "<a href=\"/data/".$match[0]."\">".$data_tekstowa."</a>";
  5. },$string);
  6. echo $string;
trueblue
  1. $string = "dzisiaj jest {2014-01-01}";
  2. $string=preg_replace_callback('#\{((\d{4})-(\d{2})-(\d{2})?)\}#', function($match){
  3. $data_tekstowa=dateV('j F Y', strtotime($match[1]));
  4. return "<a href=\"/data/".$match[1]."\">".$data_tekstowa."</a>";
  5. },$string);
  6. echo $string;
mb83
podobnie jak trueblue wykombinowałem - pozbyłem się klamr ({}) i formatuję datę za pomocą dateV, dzięki trueblue za pomoc!
  1. $string = "dzisiaj jest 2015-01-01 a jutro będzie 2015-01-02.";
  2. echo preg_replace_callback('([0-9]{4}-[0-9]{2}-[0-9]{2})', function($match){
  3. $data_tekstowa=dateV('j F Y', strtotime($match[0]));
  4. $dzien_tekstowy=dateV('l', strtotime($match[0]));
  5. return "<a href=\"/data/".$match[0]."\">".$data_tekstowa." (".$dzien_tekstowy.")</a>";
  6. },$string);


jeszcze jedno: a da się to ulepszyć tak aby linkował tylko datę z przyszłości a datę z przeszłości wyświetlał jako tekst bez linku?

mam na myśli coś takiego:
  1. $dat = date("Y-m-d");
  2. $skrot = preg_replace_callback('([0-9]{4}-[0-9]{2}-[0-9]{2})', function($match){
  3. $data_tekstowa=dateV('j f Y', strtotime($match[0]));
  4. $dzien_tekstowy=dateV('l', strtotime($match[0]));
  5. $mat=date('Y-m-d', strtotime($match[0]));
  6. if(($dat)<($mat)) return "<a href=\"/data/".$match[0]."\" title=\"".$data_tekstowa." (".$dzien_tekstowy.")\">".$data_tekstowa." (".$dzien_tekstowy.") -- ".$mat."</a>";
  7. if(($dat)>($mat)) return "".$data_tekstowa." (".$dzien_tekstowy.") -- ".$mat."";
  8. },$skrot);


ale to nie za bardzo działa bo linkuje wszystkie daty, gdzie jest błąd?
trueblue
Porównuj obydwie daty jako unix timestamp, albo http://php.net/manual/en/datetime.diff.php.
mb83
timestamp nic nie daje, taki sam efekt jak bez niego:
  1. $skrot = preg_replace_callback('([0-9]{4}-[0-9]{2}-[0-9]{2})', function($match){
  2. $data_tekstowa=dateV('j f Y', strtotime($match[0]));
  3. $dzien_tekstowy=dateV('l', strtotime($match[0]));
  4. $dat = strtotime('Y-m-d');
  5. $mat=strtotime($match[0]);
  6. if(($mat)<($dat)) return "<a href=\"/data/".$match[0]."\" title=\"".$data_tekstowa." (".$dzien_tekstowy.")\">".$data_tekstowa." (".$dzien_tekstowy.") -- ".$mat."</a>";
  7. if(($mat)>($dat)) return "".$data_tekstowa." (".$dzien_tekstowy.") -- ".$mat."";
  8. },$skrot);


możesz dać przykład jak to napisać z datediff? albo co jest nie tak, że przy powyższym kodzie linkuje zarówno datę mniejszą jak i większą?
trueblue
  1. $dat = strtotime('Y-m-d');


A tu jaką datę zamieniasz na unix timestamp?
mb83
no tak trueblue, zapomniałem o date ;-)
wersja finalna, działa jak należy - linkuje datę równą bądź większą, mniejszą zmienia na sam tekst:
  1. $skrot = preg_replace_callback('([0-9]{4}-[0-9]{2}-[0-9]{2})', function($match){
  2. $data_tekstowa=dateV('j f Y', strtotime($match[0]));
  3. $dzien_tekstowy=dateV('l', strtotime($match[0]));
  4. $dat = strtotime(date('Y-m-d'));
  5. $mat=strtotime($match[0]);
  6. if(($mat)>($dat) || ($mat)==($dat)) return "<a href=\"/data/".$match[0]."\" title=\"".$data_tekstowa." (".$dzien_tekstowy.")\">".$data_tekstowa." (".$dzien_tekstowy.") -- ".$mat."</a>";
  7. if(($mat)<($dat)) return "".$data_tekstowa." (".$dzien_tekstowy.") -- ".$mat."";
  8. },$skrot);
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.