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

使用CSVHelper解析通话日志CSV时无法获取Date字段的技术问询

解析CSV通话日志时Date字段无法获取的解决方案

问题

有一个.txt格式的CSV通话日志,定义的字段为Name、Address、Direction、Status、Duration、Date,使用CSVHelper解析时无法正确获取Date字段,需要开发Windows窗体程序存储包含完整日期时间的通话日志。

日志示例

Name,Address,Direction,Status,Duration,Date
Berat Bey Dörtsan,"05315554622",Outgoing,Unanswered,00:00,00:00,8/4/2022 (9:25:48 AM)
Berat Bey Dörtsan,"05315554622",Outgoing,Answered,00:47,00:47,8/4/2022 (9:27:55 AM)

预期解析格式

  • Name = Berat Bey Dörtsan
  • Address = 05315554466
  • Direction = Outgoing
  • Status = Unanswered
  • Duration = 00:54 - 01:56
  • Date = 8/4/2022 (9:25:48 AM)

用户原有代码

using CsvHelper;
using CsvHelper.Configuration.Attributes;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace TextVeriCekme
{
    public partial class Form1 : Form
    {
        String csvPath = "";
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog
            {
                Title = "CSV Dosyası Aç",
                Filter = "csv files (*.csv)|*.csv",
                CheckFileExists = true,
                CheckPathExists = true
            };

            if (ofd.ShowDialog() == DialogResult.OK)
            {
                MessageBox.Show(ofd.FileName);
                csvPath = ofd.FileName;
            }
        }

        public class Foo
        {
            public string Name { get; set; }

            public string Address { get; set; }

            public string Direction { get; set; }

            public string Status { get; set; }

            public string Duration { get; set; }

            [Name("Date")]
            [Format("dd-MM-yyyy")]
            public DateTime Date { get; set; }
        }

        int sayac = 0;

        private void button2_Click(object sender, EventArgs e)
        {
            IEnumerable<Foo> records = null;
            List<Foo> list = null;
            using (var reader = new StreamReader(csvPath))
                using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
            {
                records = csv.GetRecords<Foo>();
                list = records.ToList();
                MessageBox.Show("Toplam Kayıt : " + records.Count().ToString());
                foreach (Foo record in list)
                {
                    if (sayac == 1)
                    {
                        MessageBox.Show(record.Name);
                        MessageBox.Show(record.Address);
                        MessageBox.Show(record.Direction);
                        MessageBox.Show(record.Status);
                        MessageBox.Show(record.Duration);
                        MessageBox.Show(record.Date.ToString());
                    }
                    sayac++;
                }
            }
        }
    }
}

问题原因及解决步骤

1. 字段不匹配:表头与数据列数量不一致

日志表头仅定义6个字段,但实际数据行有7列——Duration对应了两个值(如00:00,00:00),导致Date字段的位置被偏移,CSVHelper无法正确映射。

2. Date字段格式配置错误

日志中的日期格式为M/d/yyyy (h:mm:ss tt)(示例:8/4/2022 (9:25:48 AM)),但代码中使用[Format("dd-MM-yyyy")],格式不匹配导致解析失败。

修改后的代码实现

using CsvHelper;
using CsvHelper.Configuration;
using CsvHelper.Configuration.Attributes;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Windows.Forms;

namespace TextVeriCekme
{
    public partial class Form1 : Form
    {
        string csvPath = "";
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog
            {
                Title = "CSV Dosyası Aç",
                Filter = "csv files (*.csv)|*.csv",
                CheckFileExists = true,
                CheckPathExists = true
            };

            if (ofd.ShowDialog() == DialogResult.OK)
            {
                MessageBox.Show(ofd.FileName);
                csvPath = ofd.FileName;
            }
        }

        // 修正实体类,匹配实际数据列
        public class CallLog
        {
            public string Name { get; set; }
            public string Address { get; set; }
            public string Direction { get; set; }
            public string Status { get; set; }
            
            // 接收第一个Duration值
            [Name("Duration")]
            public string DurationStart { get; set; }
            
            // 接收第二个Duration值,通过索引指定位置
            [Index(5)]
            public string DurationEnd { get; set; }

            // 匹配日志中的日期格式
            [Index(6)]
            [Format("M/d/yyyy (h:mm:ss tt)")]
            public DateTime Date { get; set; }

            // 合并Duration为预期格式
            public string FormattedDuration => $"{DurationStart} - {DurationEnd}";
        }

        int sayac = 0;

        private void button2_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(csvPath))
            {
                MessageBox.Show("请先选择CSV文件");
                return;
            }

            // 配置CSVHelper文化信息,适配日期解析
            var config = new CsvConfiguration(CultureInfo.InvariantCulture)
            {
                // 确保表头映射正确
                HasHeaderRecord = true,
            };

            using (var reader = new StreamReader(csvPath))
            using (var csv = new CsvReader(reader, config))
            {
                var records = csv.GetRecords<CallLog>().ToList();
                MessageBox.Show("Toplam Kayıt : " + records.Count.ToString());
                
                foreach (var record in records)
                {
                    if (sayac == 1)
                    {
                        MessageBox.Show(record.Name);
                        MessageBox.Show(record.Address);
                        MessageBox.Show(record.Direction);
                        MessageBox.Show(record.Status);
                        MessageBox.Show(record.FormattedDuration); // 使用合并后的Duration
                        MessageBox.Show(record.Date.ToString("M/d/yyyy (h:mm:ss tt)"));
                    }
                    sayac++;
                }
            }
        }
    }
}

关键修改说明

  • 实体类重命名为CallLog更具语义,新增DurationStart和DurationEnd分别接收数据中的两个时长值,通过[Index]特性指定第二个时长的列位置。
  • 新增FormattedDuration属性,将两个时长值合并为预期的00:00 - 00:00格式。
  • Date字段修改为[Format("M/d/yyyy (h:mm:ss tt)")],匹配日志中的日期格式,同时通过[Index(6)]明确指定列位置,避免表头映射歧义。
  • 添加CSV配置实例,确保文化信息正确,同时增加文件路径为空的判断。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 20:40:25