You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel中使用DB::raw调用DATE_FORMAT能否实现多语言日期格式化?

解决Laravel中DATE_FORMAT多语言月份缩写的问题

这个问题我做多语言项目时也碰到过——MySQL的DATE_FORMAT函数本身依赖数据库系统的语言配置,默认只会返回英文月份缩写,没法直接实现多语言适配。不过我们有几个靠谱的解决方案,按推荐度排序给你:

方案1:用Laravel Carbon本地化处理(最推荐)

别在数据库查询里做格式化,而是取出原始的created_at时间字段,利用Laravel内置的Carbon扩展完成本地化格式化。Carbon已经集成了多语言的月份、星期等翻译,只要配置好应用的本地化就能自动适配。

修改后的查询代码如下:

$test = Test::query()
    ->select("test.id as id", "users.first_name as first_name", "users.last_name as last_name")
    ->addSelect("test.company_name as company_name", "test.email as email", "test.created_at")
    ->join("users", "users.id", "=", "test.user_id")
    ->where("test.test_id", "=", $test->id)
    ->get()
    ->map(function($item) {
        // 用translatedFormat输出对应语言的日期格式,%b对应本地化的月份缩写
        $item->created = $item->created_at->translatedFormat('d-M-Y');
        // 可选:移除不需要的原始created_at字段
        unset($item->created_at);
        return $item;
    });

配置本地化

  • 你可以在config/app.php里设置默认的locale(比如'locale' => 'tr'对应土耳其语);
  • 如果需要动态切换语言,在查询前调用App::setLocale('你的语言代码')即可,Carbon会自动使用对应语言的翻译。

这个方案完全利用Laravel的生态,灵活且易于维护,多语言切换毫无压力。

方案2:临时修改MySQL会话的语言设置(不推荐)

如果一定要在数据库层面完成格式化,可以临时修改当前MySQL会话的lc_time_names参数,指定目标语言区域,这样DATE_FORMAT就会返回对应语言的月份缩写。

示例代码:

// 设置当前MySQL会话的时间语言(以土耳其语为例)
DB::statement("SET lc_time_names = 'tr_TR'");

$test = Test::query()
    ->select("test.id as id", "users.first_name as first_name", "users.last_name as last_name")
    ->addSelect("test.company_name as company_name", "test.email as email")
    ->addSelect(DB::raw("DATE_FORMAT(test.created_at, '%d-%b-%Y') as created"))
    ->join("users", "users.id", "=", "test.user_id")
    ->where("test.test_id", "=", $test->id)
    ->get();

注意事项

  • 这个设置只对当前数据库会话有效,每次查询前都需要执行;
  • 如果你的应用使用数据库连接池,可能会出现会话共享导致的语言混乱问题,所以不推荐在多用户多语言场景下使用。

方案3:自定义月份映射数组(适合简单场景)

如果只需要支持少数几种固定语言,可以自己定义英文月份缩写和目标语言的映射关系,查询完成后替换结果中的月份。

示例代码:

// 示例:土耳其语的月份缩写映射
$monthTranslations = [
    'Jan' => 'Oca',
    'Feb' => 'Şub',
    'Mar' => 'Mar',
    'Apr' => 'Nis',
    'May' => 'May',
    'Jun' => 'Haz',
    'Jul' => 'Tem',
    'Aug' => 'Ağu',
    'Sep' => 'Eyl',
    'Oct' => 'Eki',
    'Nov' => 'Kas',
    'Dec' => 'Ara',
];

$test = Test::query()
    // 原有查询代码不变
    ->select("test.id as id", "users.first_name as first_name", "users.last_name as last_name")
    ->addSelect("test.company_name as company_name", "test.email as email")
    ->addSelect(DB::raw("DATE_FORMAT(test.created_at, '%d-%b-%Y') as created"))
    ->join("users", "users.id", "=", "test.user_id")
    ->where("test.test_id", "=", $test->id)
    ->get()
    ->map(function($item) use ($monthTranslations) {
        // 替换月份缩写
        foreach ($monthTranslations as $enAbbr => $localAbbr) {
            $item->created = str_replace($enAbbr, $localAbbr, $item->created);
        }
        return $item;
    });

这个方案的缺点是需要手动维护映射数组,新增语言时要更新代码,适合语言需求固定且较少的小型项目。


内容的提问来源于stack exchange,提问作者Hasan Çetin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.01 00:47:41