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

C#数据库日期格式转换与查询适配问题咨询

解决方案

1. 处理用户输入的d/m/y格式日期

ASP.NET Core 默认 DateTime 绑定逻辑无法直接识别 dd/MM/yyyy 格式,需通过自定义模型绑定器实现正确解析:

自定义日期模型绑定器

public class DmyDateTimeModelBinder : IModelBinder
{
    public Task BindModelAsync(ModelBindingContext bindingContext)
    {
        if (bindingContext == null)
            throw new ArgumentNullException(nameof(bindingContext));

        var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
        if (valueProviderResult == ValueProviderResult.None)
            return Task.CompletedTask;

        bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult);
        var inputValue = valueProviderResult.FirstValue;

        if (string.IsNullOrEmpty(inputValue))
            return Task.CompletedTask;

        // 解析dd/MM/yyyy格式日期
        if (DateTime.TryParseExact(inputValue, "dd/MM/yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out var parsedDate))
        {
            bindingContext.Result = ModelBindingResult.Success(parsedDate.Date); // 仅保留日期部分
        }
        else
        {
            bindingContext.ModelState.TryAddModelError(bindingContext.ModelName, "日期格式无效,请使用dd/MM/yyyy格式(如09/08/2022)");
        }

        return Task.CompletedTask;
    }
}

绑定API接口参数

修改接口参数,指定使用自定义绑定器:

[HttpGet("date/{date}")]
[Produces("application/json")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<ActionResult<Result>> GetPartySearchHistoriesByDate(
    [BindRequired]
    [FromRoute]
    [ModelBinder(BinderType = typeof(DmyDateTimeModelBinder))]
    DateTime date)
{
    try
    {
        var items = await _mediator.Send(new GetPartySearchHistoriesByDateQuery() { Date = date });
        return Result.Ok(new
        {
            MatchCount = items.Count,
            Matches = items
        });
    }
    catch (Exception ex)
    {
        throw new SanctionException("获取记录时发生错误。", ex);
    }
}

2. 修改数据库查询逻辑(匹配当天所有数据)

原SQL仅匹配精确时间,需改为查询当天0点至次日0点的范围,避免时间精度问题且能利用索引:

public async Task<List<PartySearchHistoryDto>> GetListByDateAsync(DateTime date)
{
    IUnitOfWork unitOfWork = await _dbConnection.GetUnitOfWorkAsync();
    unitOfWork.Begin();
    try
    {
        var startOfDay = date.Date;
        var startOfNextDay = startOfDay.AddDays(1);

        var partySearchHistories = await unitOfWork
            .Connection
            .QueryAsync<PartySearchHistoryDto>(
            @"SELECT *
              FROM [dbo].[PartySearchHistories] WITH (NOLOCK)
              WHERE CreatedAt >= @startOfDay 
                AND CreatedAt < @startOfNextDay
                AND IsDeleted = 0",
            new { startOfDay, startOfNextDay },
            transaction: unitOfWork.Transaction);

        return partySearchHistories.ToList();
    }
    catch (Exception)
    {
        return new List<PartySearchHistoryDto>();
    }
}

3. 格式化返回结果(dd/MM/yyyy HH:mm)

在ViewModel中添加格式化后的日期属性,直接返回给前端:

public class PartySearchHistoryVM
{
    // 原有属性保留...
    public DateTime CreatedAt { get; set; }
    
    // 新增格式化日期属性
    public string FormattedCreatedAt => CreatedAt.ToString("dd/MM/yyyy HH:mm", CultureInfo.InvariantCulture);
}

若使用AutoMapper进行DTO到VM的转换,可通过映射配置实现:

CreateMap<PartySearchHistoryDto, PartySearchHistoryVM>()
    .ForMember(dest => dest.FormattedCreatedAt, 
               opt => opt.MapFrom(src => src.CreatedAt.ToString("dd/MM/yyyy HH:mm", CultureInfo.InvariantCulture)));

额外提示

  • 若需支持两位年份输入(如09/08/22),可在模型绑定器中添加dd/MM/yy格式的解析逻辑。
  • 模型绑定器会自动处理解析失败的情况,ASP.NET Core将返回400 Bad Request并包含错误信息。
  • 若数据库CreatedAt为datetimeoffset类型,需将输入日期转换为对应时区后再执行查询。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 06:24:47