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

Laravel中Maatwebsite Excel导入日期变为1970-01-01问题求助

问题:Laravel导入Excel日期全部变为1970-01-01

在Laravel项目中使用Maatwebsite Excel实现Excel数据导入功能,数据已成功写入数据库,但Excel中原本的01/01/2022和31/12/2022日期,导入后全部变成了01/01/1970。

相关代码

AlokasicutiImport类

<?php

namespace App\Imports;
use Carbon\Carbon;
use App\Models\Alokasicuti;
use Illuminate\Support\Facades\Log;
use Maatwebsite\Excel\Concerns\ToModel;

class AlokasicutiImport implements ToModel
{
    public function startRow(): int
    {
        return 2;
    }

    /**
    * @param array $row
    *
    * @return \Illuminate\Database\Eloquent\Model|null
    */
    public function model(array $row)
    {
        if(isset($row[0]) && isset($row[2]))
        {
            if(!Alokasicuti::where('id_karyawan',$row[0])->where('id_jeniscuti',$row[2])->exists())
            {
                $data = [
                    'id_karyawan'      => $row[0] ?? null,
                    'id_settingalokasi'=> $row[1] ?? null,
                    'id_jeniscuti'     => $row[2] ?? null,
                    'durasi'           => $row[3] ?? null,
                    'mode_alokasi'     => $row[4] ?? null,
                    'tgl_masuk'        => Carbon::parse($row[5])->format("Y-m-d") ?? null,
                    'tgl_sekarang'     => Carbon::parse($row[6])->format("Y-m-d") ?? null,
                    'aktif_dari'       => Carbon::parse($row[7])->format("Y-m-d") ?? null,
                    'sampai'           => Carbon::parse($row[8])->format("Y-m-d") ?? null,
                ];
                
                Alokasicuti::create($data);
            
            }else{
                Log::info('id pegawai dan tanggal absensi sudah ada');
            }
        } else{
             Log::info('Row 1 kosong');
        }
    }
}

导入控制器方法

public function importexcel(Request $request)
{
    Excel::import(new AlokasicutiImport, request()->file('file'));
    return redirect()->back();
}

问题原因

  1. 日期格式解析不匹配:Carbon::parse()默认优先识别MM/DD/YYYY格式,而你的Excel日期是DD/MM/YYYY(日/月/年),导致解析错误。例如31/12/2022中31作为月份不存在,解析失败后返回Unix时间戳0对应的日期1970-01-01。
  2. 空值处理逻辑错误:代码中Carbon::parse($row[7])->format("Y-m-d") ?? null的写法无效,因为即使解析失败,Carbon::parse()也会返回一个Carbon实例(对应1970-01-01),不会触发?? null。
  3. Excel日期存储形式问题:如果Excel中的日期是以数值形式存储(Excel内部将日期转为从1900-01-01开始的天数),直接用Carbon解析数值会导致完全错误的结果。

解决方案

方案1:指定日期格式解析

针对DD/MM/YYYY格式,使用Carbon::createFromFormat()明确指定解析规则,同时先判断单元格是否为空:

$data = [
    // ... 其他字段
    'tgl_masuk'        => !empty($row[5]) ? Carbon::createFromFormat('d/m/Y', $row[5])->format('Y-m-d') : null,
    'tgl_sekarang'     => !empty($row[6]) ? Carbon::createFromFormat('d/m/Y', $row[6])->format('Y-m-d') : null,
    'aktif_dari'       => !empty($row[7]) ? Carbon::createFromFormat('d/m/Y', $row[7])->format('Y-m-d') : null,
    'sampai'           => !empty($row[8]) ? Carbon::createFromFormat('d/m/Y', $row[8])->format('Y-m-d') : null,
];

方案2:处理Excel数值型日期

如果Excel中的日期是数值格式,使用PhpSpreadsheet内置的转换方法:

use PhpOffice\PhpSpreadsheet\Shared\Date;

// ...

$data = [
    // ... 其他字段
    'aktif_dari'       => !empty($row[7]) ? Date::excelToDateTimeObject($row[7])->format('Y-m-d') : null,
    'sampai'           => !empty($row[8]) ? Date::excelToDateTimeObject($row[8])->format('Y-m-d') : null,
];

方案3:兼容多种日期格式

如果不确定Excel日期格式,可以先尝试解析,失败时再用指定格式:

function parseExcelDate($date) {
    if(empty($date)) return null;
    try {
        $carbonDate = Carbon::parse($date);
        if($carbonDate->year < 2000) { // 解析结果异常,尝试用DD/MM/YYYY
            $carbonDate = Carbon::createFromFormat('d/m/Y', $date);
        }
        return $carbonDate->format('Y-m-d');
    } catch (\Exception $e) {
        return null;
    }
}

// 在$data中使用:
'aktif_dari' => parseExcelDate($row[7]),
'sampai' => parseExcelDate($row[8]),

内容的提问来源于stack exchange,提问作者akhiratunnisa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 17:20:42