首页 > 解决方案 > ASP.NET Core 应用程序上的错误日期时间格式

问题描述

我想在 ASP.NET Core 应用程序上设置相同的日期时间格式 (pl-PL)。我在我的配置中使用 pl-PL 文化:

        services.Configure<RequestLocalizationOptions>(options =>
        {
            var supportedCultures = new[]
            {
                new CultureInfo("pl-PL"),
            };
            options.DefaultRequestCulture = new RequestCulture("pl-PL", "pl-PL");
            options.DefaultRequestCulture.Culture.DateTimeFormat.FullDateTimePattern = "dd.MM.yyyy HH:mm:ss";
            options.DefaultRequestCulture.Culture.DateTimeFormat.ShortDatePattern = "dd.MM.yyyy";
            options.DefaultRequestCulture.UICulture.DateTimeFormat.FullDateTimePattern = "dd.MM.yyyy HH:mm:ss";
            options.DefaultRequestCulture.UICulture.DateTimeFormat.ShortDatePattern = "dd.MM.yyyy";
            

            options.SupportedCultures = supportedCultures;
            options.SupportedUICultures = supportedCultures;

        });

那还不够。我仍然有绑定日期的问题,例如。01.02.2013 绑定为 02.01.2013。因此我编写了自定义活页夹:

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

        // Try to fetch the value of the argument by name
        var modelName = bindingContext.ModelName;
        var valueProviderResult = bindingContext.ValueProvider.GetValue(modelName);
        if (valueProviderResult == ValueProviderResult.None)
            return Task.CompletedTask;

        bindingContext.ModelState.SetModelValue(modelName, valueProviderResult);

        var dateStr = valueProviderResult.FirstValue;
        // Here you define your custom parsing logic, i.e. using "pl-PL" culture

        
        if (!DateTime.TryParse(dateStr, new CultureInfo("pl-PL"), DateTimeStyles.None, out date))
        {
              bindingContext.ModelState.TryAddModelError(bindingContext.ModelName, "Data powinna być w formacie 'dd.MM.yyyy HH:mm:ss'");
              return Task.CompletedTask;
        }
            

        bindingContext.Result = ModelBindingResult.Success(date);
        return Task.CompletedTask;
    }
}

它开始工作,但只是在本地(在具有波兰操作系统的计算机上)。我发现 Culture('pl-PL') 在生产服务器上必须不同(但我不知道为什么)。所以,我决定补充:

if (!DateTime.TryParseExact(dateStr, "dd.MM.yyyy HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime date))
            {
                if (!DateTime.TryParseExact(dateStr, "dd.MM.yyyy HH:mm", CultureInfo.InvariantCulture, DateTimeStyles.None, out date))
                {
                    if (!DateTime.TryParseExact(dateStr, "dd.MM.yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out date))
                    {
                        if (!DateTime.TryParse(dateStr, new CultureInfo("pl-PL"), DateTimeStyles.None, out date))
                        {
                            bindingContext.ModelState.TryAddModelError(bindingContext.ModelName, "Data powinna być w formacie 'dd.MM.yyyy HH:mm:ss'");
                            return Task.CompletedTask;
                        }
                    }
                }
            }

该解决方案有效,但很难看。同样重要的是,我注意到不同浏览器之间的数据格式看起来不同。在 Firefox 上:Od:19.02.2021 执行:05.03.2021(正确) 在 Chrome 上:Od:2021-02-19 执行:2021-03-05(错误)

返回表示层日期的代码:

<div class="col-sm-3">
Od: @vehicleAvailability.DateFrom.ToShortDateString()
Do: @vehicleAvailability.DateTo.ToShortDateString()
</div>

标签: datetimeasp.net-coreformatculture

解决方案


在您的情况下,Chrome 和 Firefox 之间的区别在于它们发送不同的Accept-Language标头,您可以在网络选项卡中查看。如果要显示特定的日期格式,请考虑在DateTime.ToString

<!-- ToShortDateString() equals ToString("d") -->
<div class="col-sm-3">
Od: @vehicleAvailability.DateFrom.ToString("d", new CultureInfo("pl-PL")) 
Do: @vehicleAvailability.DateTo.ToString("d", new CultureInfo("pl-PL"))
</div>

推荐阅读