35

Take this example:

{{ $article->created_at->format('M') }}

It returns Nov. I need to localise this to my language, so the output should be Kas

Thought about doing the following:

{{ trans("language.{$article->created_at->format('M')}") }}

app/lang/tr/language.php -> 'nov' => 'kas'

This looks like reinventing the wheel and programmatically pretty terrible. I'm sure there are some localisation standards. Something like:

{{ $article->created_at->format('M')->localiseTo('tr_TR') }}

What's the best way to achieve this?

Aristona
  • 8,611
  • 9
  • 54
  • 80

8 Answers8

27

Using a library as Laravel-Date you will just need to set the language of the app in the Laravel app config file and use its functions to format the date as you want.

Set the language in /app/config/app.php

'locale' => 'es',

I've found this library pretty useful and clean. To use it, you can write something like the example in the library readme file. I leave the results in spanish.

echo Date::now()->format('l j F Y H:i:s'); // domingo 28 abril 2013 21:58:16

echo Date::parse('-1 day')->diffForHumans(); // 1 día atrás

This is the link to the repository:

https://github.com/jenssegers/laravel-date

To install this library you can follow the instructions detailed in the following link:

https://github.com/jenssegers/laravel-date#installation

Marco Florian
  • 929
  • 1
  • 10
  • 18
  • Been a while since I asked this question. This was the solution I went with. I also had to extend Date class myself to provide some more functional features. – Aristona Jan 06 '15 at 06:52
  • 1
    Maybe worth noting that you can use it for multiple locales like `Date::setLocale('nl');`. – Adam Nov 28 '17 at 17:41
  • 1
    Please review the answer of Arthur Tavares since this solution is a little bit deprecated. You can achieve the same without a package (https://stackoverflow.com/a/70277624/4112883). – Dirk Jan Jun 21 '22 at 13:44
16

As of carbon version 2.30.0, you can use the translatedFormat function

$date = Carbon::parse('2021-12-08 11:35')->locale('pt-BR');
echo $date->translatedFormat('d F Y'); //  08 dezembro 2021
Arthur Tavares
  • 171
  • 1
  • 6
13

When you retrieve a date off a model in Laravel, you get back a Carbon object: https://github.com/briannesbitt/Carbon

If you refer to the Carbon documentation, it tells you how you can get a locale formatted Date:

Unfortunately the base class DateTime does not have any localization support. To begin localization support a formatLocalized($format) method has been added. The implementation makes a call to strftime using the current instance timestamp. If you first set the current locale with setlocale() then the string returned will be formatted in the correct locale.

setlocale(LC_TIME, 'German');                     
echo $dt->formatLocalized('%A %d %B %Y');          // Donnerstag 25 Dezember 1975
setlocale(LC_TIME, '');                           
echo $dt->formatLocalized('%A %d %B %Y');          // Thursday 25 December 1975

So basically, just use formatLocalized('M') instead of format('M')

Brian Glaz
  • 15,468
  • 4
  • 37
  • 55
  • "Call to undefined method" – Aristona Nov 18 '13 at 21:28
  • Are you using Laravel version 4? – Brian Glaz Nov 18 '13 at 21:29
  • Yes. Carbon model binded to $created_at doesn't have a method called "formatLocalized" – Aristona Nov 18 '13 at 21:41
  • It's possible it was added in a newer version? Try a `composer update` from your root directory. If i look in the Carbon class file, I see a `formatLocalized` method defined on line 778. The file is located in `/vendor/nesbot/carbon/src/Carbon/Carbon.php` – Brian Glaz Nov 18 '13 at 21:45
  • I just issued composer update but nothing changed. My carbon path is: `vendor/nesbot/carbon/Carbon/Carbon.php` and it doesn't contain a method like that. – Aristona Nov 18 '13 at 23:33
  • Here's the method copied from my Carbon.php: `/** * Format the instance with the current locale. You can set the current * locale using setlocale() http://php.net/setlocale. * * @param string $format * * @return string */ public function formatLocalized($format) { // Check for Windows to find and replace the %e // modifier correctly if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') { $format = preg_replace('#(?<!%)((?:%%)*)%e#', '\1%#d', $format); } return strftime($format, $this->timestamp); }` – Brian Glaz Nov 19 '13 at 13:44
  • Can I see your composer.json? – Aristona Nov 19 '13 at 13:57
  • Don't think I changed it from the default, it's just requiring `laravel/framework: 4.0.*` – Brian Glaz Nov 19 '13 at 14:13
5

It is also a good idea to set locale globally for each request (eg. in filters.php) when using Carbon date instances.

App::before(function($request) {
    setlocale(LC_TIME, 'sk_SK.utf8');
});

and then proceed as usual

$dt->formatLocalized('%b'); // $dt is carbon instance

See format options here and list of locales here.

Community
  • 1
  • 1
zub0r
  • 1,299
  • 1
  • 14
  • 20
  • 1
    I like this answer. However you need to be aware that the locale you want to use is actually installed on the server https://stackoverflow.com/questions/1941956/is-it-feasible-to-rely-on-setlocale-and-rely-on-locales-being-installed – Adam Dec 06 '17 at 11:24
1

In addition to the accepted answer, I was looking for a way to use this within Blade using the Carbon instance of created_at for example. The class in the accepted answer didn't seem to accept a Carbon instance as date, but rather parsed a date from a string.

I wrote a little helper function to shorten the code in the blade templates:

function localeDate($date, $format)
{
    return Jenssegers\Date\Date::createFromFormat('d-m-Y H:i:s',  $date->format('d-m-Y H:i:s'))->format($format);
}

Within Blade you can now use:

{{ localeDate($model->created_at, 'F') }}

Which would return the fully written name of the month in the locale set in config/app.php

If there's a better way (or I missed something in the code), please let me know. Otherwise this might be helpfull for others.

Joshua - Pendo
  • 4,331
  • 6
  • 37
  • 51
0

Goto your App->Config->app.php put

'timezone' => 'Asia/Kolkata',

use simple {{$post->created_at->diffForHumans()}}

Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
0

Localized (i18n) date with Laravel 8

In Laravel 8, I added a method in my Block Model:

use Illuminate\Support\Carbon;

class Block extends Model
{
    public function updatedDate() {
        return Carbon::parse($this->updated_at)->translatedFormat('d F Y');
    }
}

In my Blade template, I want to get the latest row's update date:

{{ $blocks->last()->updatedDate() }} // prints out 25 January 2022

// PS. Carbon uses your app.locale config variable so setting locale() is optional
// return Carbon::parse($this->updated_at)->locale('en')->translatedFormat('d F Y')
Taikahessu
  • 11
  • 2
0

For Laravel 10 I suggest the following helper class (intl package required):

namespace App\Helpers;

use IntlDateFormatter;

class Date 
{
    /**
     * Returns the locale defined at config/app.php
     * @return string Locale defined at config/app.php
     */
    public static function getAppLocale(): string 
    {
        return config('app.locale');
    }

    /**
     * Returns a date formated according the given locale.
     * 
     * @param int $timestamp The date timestamp.
     * @param string $locale The locale string (Ex: "pt_BR"). 
     * If no locale is provided, it uses the app locale.
     */
    public static function toLocaleFormat(int $timestamp, string $locale=null): string 
    {
        if (empty($locale)) {
            $locale = self::getAppLocale();
        }

        $formatter = new IntlDateFormatter($locale, IntlDateFormatter::SHORT, IntlDateFormatter::NONE);
        if ($formatter === null) {
            throw new \Exception(intl_get_error_message());
        }

        return $formatter->format($timestamp);
    }
}

To format a date just use:

echo Date::formatLocale($timestamp);

To format a Carbon model attribute:

echo Date::formatLocale($model->column_name->timestamp);

Additionaly, you can create a model method to make easy date formating:

namespace App\Models;

use App\Helpers\Date;

class BaseModel extends Model
{    
    public function localDate(string $attribute): ?string
    {
        if ($this->{$attribute} === null) {
            return null;
        }

        return Date::toLocaleFormat($this->{$attribute}->timestamp);
    }
}

Extends BaseModel in your model classes and you can get locale formatted dates just calling:

{{ $model->localDate('column_name') }}
Arivan Bastos
  • 1,876
  • 1
  • 20
  • 28
  • The accepted answer is 9 years old. What's wrong with just using Carbon as in this [more modern answer](https://stackoverflow.com/a/70277624/1255289)? – miken32 Aug 08 '23 at 18:37
  • @miken32 nothing wrong, but I dont think it is a good idea use locale string and date pattern hard coded. My suggestion detects the date format acordding locale provided in app config and it can be changed on the fly by user. I think it would be great do this using carbon, but I dont know how. – Arivan Bastos Aug 09 '23 at 18:21