Jak renderować obiekt DateTime w szablonie Twig

215

Jednym z moich pól w jednym z moich podmiotów jest zmienna „datetime”.

Jak przekonwertować to pole na ciąg znaków w celu renderowania w przeglądarce?

Oto fragment kodu:

{% for game in games %}
    ...
        <td> {{game.gameTeamIdOne.teamName}} </td>
        <td> {{game.gameTeamIdTwo.teamName}} </td>
        <td> {{game.gameDate}}</td>
    </tr>
{% endfor %}

Oto zmienna w mojej klasie encji:

/**
 * @var date $gameDate
 *
 * @ORM\Column(name="GAME_DATE", type="datetime", nullable=true)
 */
private $gameDate;

A oto komunikat o błędzie, który otrzymuję:

Zgłoszono wyjątek podczas renderowania szablonu („Catchable Fatal Error: Obiekt klasy DateTime nie mógł zostać przekonwertowany na ciąg znaków w ... \ app \ cache \ dev \ twig \ 9b \ ad \ 58fd3bb1517632badf1fdc7fa4a8.php wiersz 33” ) w „BeerBundle: Games: gameTable.html.twig” w linii 10.

Chris Ridmann
źródło

Odpowiedzi:

305

Chociaż możesz użyć

{{ game.gameDate|date('Y-m-d') }}

należy pamiętać, że ta wersja nie uwzględnia ustawień regionalnych użytkownika, co nie powinno stanowić problemu w przypadku witryny, z której korzystają tylko użytkownicy jednej narodowości. Międzynarodowi użytkownicy powinni wyświetlać datę gry zupełnie inaczej, na przykład rozszerzając \DateTimeklasę i dodając __toString()do niej metodę, która sprawdza ustawienia regionalne i działa odpowiednio.

Edytuj :

Jak wskazał @Nic w komentarzu, jeśli użyjesz rozszerzenia Intl Twig , będziesz mieć localizeddatedostępny filtr, który pokazuje datę w ustawieniach regionalnych użytkownika. W ten sposób możesz porzucić mój poprzedni pomysł rozszerzenia \DateTime.

GergelyPolonkai
źródło
45
{{ game.gameDate|date('Y-m-d H:i:s') }}dla daty i godziny. Przez kilka minut miałem problemy ze znalezieniem postaci.
murko
6
Funkcja daty Twiga używa tego samego formatu co funkcja php (z dokumentów Twig). Dla każdego, kto szuka innych formatów, php.net/manual/en/function.date.php .
JonnyS
9
Uważaj na wartości zerowe; w podobnym przypadku użycia widzę dzisiejszą datę, gdy przesyłam wartość zerową do datefunkcji Twiga . Na podstawie Twojego przykładu musisz go owinąć{% if game.gameDate is not empty %} ... {%endif}
etap
4
Jeśli chodzi o lokalizację, nie powinieneś rozszerzać DateTimeklasy! Zamiast tego po prostu użyj localizeddatefiltru dla Twig .
Nic Wortel
1
{% if game.gameDate %} {{ game.gameDate|date('Y-m-d H:i:s') }} {% endif %}byłoby sugerowane
Dheeraj,
90

Możesz użyć datefiltru:

{{ game.gameDate|date("m/d/Y") }}
Ondrej Slinták
źródło
3
Zupełnie się z Tobą zgadzam. Jest to coś, co powinno tam być domyślnie.
tftd,
2
@ThomasDecaux wcale nie jest tak dziwny, ponieważ __toString()metoda musiałaby wiedzieć, na jaki format przekonwertować DateTimeobiekt, i prawdopodobnie istnieją setki możliwych formatów. Oczywiście w PHP można użyć format()metody na DateTimeobiekcie, który przyjmuje argument formatu, a datefiltr jest po prostu odpowiednikiem Twig tej metody.
Nic Wortel
68

Zależy to od formatu, w jakim ma być wyświetlana data.

Statyczny format daty

Jeśli chcesz wyświetlić format statyczny, który jest taki sam dla wszystkich ustawień narodowych (na przykład ISO 8601 dla kanału Atom), powinieneś użyć datefiltru Twiga :

{{ game.gameDate|date('Y-m-d\\TH:i:sP') }}

Co zawsze zwróci datę / godzinę w następującym formacie:

2014-05-02T08: 55: 41Z

Ciągi formatów akceptowane przez datefiltr są takie same, jak dla funkcji PHPdate() . (jedyną różnicą jest to, że o ile mi wiadomo, nie można używać predefiniowanych stałych, które mogą być używane w date()funkcji PHP )

Zlokalizowane daty (i godziny)

Ponieważ jednak chcesz wyrenderować go w przeglądarce, prawdopodobnie będziesz chciał pokazać go w formacie czytelnym dla człowieka, zlokalizowanym dla języka i lokalizacji użytkownika. Zamiast samodzielnej lokalizacji możesz użyć do tego rozszerzenia Intl (które korzysta z IntlDateFormatter PHP ). Zapewnia filtr, localizeddatektóry wyświetli datę i godzinę przy użyciu zlokalizowanego formatu.

localizeddate( date_format, time_format [, locale ] )

Argumenty za localizeddate:

  • date_format: Jeden z ciągów formatu (patrz poniżej)
  • time_format: Jeden z ciągów formatu (patrz poniżej)
  • locale: (opcjonalnie) Użyj tego, aby zastąpić skonfigurowane ustawienia narodowe. Pozostaw ten argument, aby użyć domyślnych ustawień regionalnych, które można skonfigurować w konfiguracji Symfony.

(jest więcej, zobacz dokumentację, aby uzyskać pełną listę możliwych argumentów)

For date_formati time_formatmożesz użyć jednego z następujących ciągów:

  • 'none' jeśli nie chcesz dołączyć tego elementu
  • 'short' dla najbardziej skróconego stylu (13.12.2016 lub 15:30 w języku angielskim)
  • 'medium' dla średniego stylu (12 stycznia 1952 r. w języku angielskim)
  • 'long' na długi styl (12 stycznia 1952 lub 15:30:32 w języku angielskim)
  • 'full' dla całkowicie określonego stylu (wtorek, 12 kwietnia 1952 r. lub 15:30:42 PST w języku angielskim)

Przykład

Na przykład, jeśli chcesz wyświetlić datę w formacie równoważnym do February 6, 2014 at 10:52 AM, użyj następującego wiersza w szablonie Twig:

{{ game.gameDate|localizeddate('long', 'short') }}

Jeśli jednak użyjesz innego ustawienia narodowego, wynik zostanie zlokalizowany dla tych ustawień regionalnych:

  • 6 februari 2014 10:52dla nllokalizacji;
  • 6 février 2014 10:52dla frlokalizacji;
  • 6. Februar 2014 10:52dla delokalizacji; itp.

Jak widać, localizeddatenie tylko tłumaczy nazwy miesięcy, ale także korzysta z lokalnych notacji. Notacja angielska umieszcza datę po miesiącu, a notacja holenderska, francuska i niemiecka przed miesiącem. Nazwy miesięcy w języku angielskim i niemieckim zaczynają się od dużej litery, natomiast nazwy miesięcy w języku niderlandzkim i francuskim są małe. Do niemieckich dat dołączona jest kropka.

Instalacja / ustawienie ustawień regionalnych

Instrukcje instalacji dla rozszerzenia Intl można znaleźć w tej osobnej odpowiedzi .

Nic Wortel
źródło
1
Zlokalizowane daty (i godziny) - dziękuję bardzo za to @Nic - super!
webDEVILopers
Cześć, korzystając z zlokalizowanej daty, czy wiesz, jak wyprowadzać tylko M i Y (nie dzień)? thks
mario
3

Nie zapomnij

@ORM \ HasLifecycleCallbacks ()

Podmiot:

/**
     * Set gameDate
     *
     * @ORM\PrePersist
     */
    public function setGameDate()
    {
        $this->dateCreated = new \DateTime();

        return $this;
    }

Widok:

{{ item.gameDate|date('Y-m-d H:i:s') }}

>> Wyniki 2013-09-18 16:14:20

Ivan
źródło
2

Istnieje narzędzie symfony2 do wyświetlania daty w bieżącym języku:

{{ user.createdAt|localeDate }} to have a medium date and no time, in the current locale

{{ user.createdAt|localeDate('long','medium') }} to have a long date and medium time, in the current locale

https://github.com/michelsalib/BCCExtraToolsBundle

ihsan
źródło
2
{{game.gameDate | date('c')}}  // 2014-02-05T16:45:22+00:00

Dla pełnego ciągu daty i godziny wraz z przesunięciem strefy czasowej.

Venkat Kotra
źródło
1

Wiem, że to dość stare pytanie, ale znalazłem to pytanie dzisiaj, ale odpowiedzi nie były tym, czego potrzebowałem.

Oto, czego potrzebowałem.

Jeśli, podobnie jak ja , chcesz wyświetlić aktualną datę w gałązce, możesz użyć następujących opcji:

{{ "now"|date("m/d/Y") }}

Zobacz dokumentację na ten temat:

data na gałązce

Refilon
źródło
0

Aby uniknąć błędu wartości zerowej, możesz użyć tego kodu:

{{ game.gameDate ? game.gameDate|date('Y-m-d H:i:s') : '' }}
Arnold Richmon
źródło