在 Blazor 中本地化日期时间(和数字)
Localizing DateTime (and numbers) in Blazor
我正在开发基于最新 Core 3.1 的 Blazor 项目。
UI 文化正确显示日期和数字,如图中所示。
但是当我使用 EditForm 时,数字和日期的格式不正确。
因此 EditForm 的这段代码
<InputDate id="date" class="form-control" @bind-Value="@TaskObject.Date" />
所以在 EditForm 中它看起来像这样,这是不正确的文化格式:
但在 UI 中看起来像这样,这没关系:
作为 Blazor 的新手,我尝试在线阅读不同的内容以获取有关此问题的一些知识。
所以我已经厌倦了以下内容:
- I want to change date format of form control class type is date?
- How to format the date using local culture using the blazor <InputDate /> tag
运气不好。
然后我尝试阅读 this and found this,它不适用于 Core 3.1。
我的问题是,究竟应该怎样做才能让 EditForm 像 UI 一样显示日期和数字,为什么 EditForm 会出现这种情况?
这不是 Blazor 问题,而是 type="date"
的 HTML <input>
元素的行为。
type="date"
所需的 format
是 Blazor 组件使用的 "yyyy-MM-dd"
。任何其他格式均无效。
如果我们做一点测试,我们可以验证这不是 Blazor 问题。
@page "/dates"
@using System.Globalization
<h3>Date</h3>
<p>@_dateString</p>
<input type="date" value="@_dateString" />
@code {
private string _dateString;
protected override void OnInitialized()
{
// using en-US culture
// this is what InputDate component does
_dateString = DateTime.Now.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);
}
}
_dateString
输出 2019-12-30
但 <input>
中显示的日期是 30/12/2019
有关 type=date
的详细信息可在 here 中找到。在“值”部分中,有一条说明如下:
The displayed date format will differ from the actual value — the displayed date is formatted based on the locale of the user's browser, but the parsed value is always formatted yyyy-mm-dd.
因此格式固定为用户浏览器的区域设置。
Why this happen for EditForm
内置的InputDate
/InputNumber
被设计为Culture-Invariant组件。参见 source code of InputDate and InputNumber。
What should exactly be done to make EditForm show date and number like the of UI,
我认为我们可以创建自定义 InputDate<TValue>
实现。然而,我错了。根据 MDN:
The displayed date is formatted based on the locale of the user's browser, but the parsed value is always formatted yyyy-mm-dd..
即使我们获得了支持当前 CultureInfo
的自定义 InputDate<TValue>
实现,我们仍然需要一些 js/css 来显示正确的格式。 IMO,没有标准的方法来实现这个。另见 this thread on SO.
我建议使用这个组件
https://blazorrepl.com/repl/wbambCPv20P0pX1h21
编辑:
如果 link 不起作用,这里是代码:
<style>
#myInput[type="date"] {
margin-top: 3px;
border: 0;
position: absolute;
width: 24px;
height: 24px;
}
#myInput[type="date"]::-webkit-inner-spin-button {
display: none;
}
#myInput[type="date"]::-webkit-calendar-picker-indicator {
margin: 0;
position: absolute;
}
#myInput[type=date]::-webkit-datetime-edit,
#myInput[type=date]::-webkit-datetime-edit-fields-wrapper {
-webkit-appearance: none;
display: none;
margin: 0;
padding: 0;
}
</style>
<input value="@this.Value.ToString(this.Format)" @onchange="this.DateChangedAsync" class="@Class" style="display:inline-block;margin-right: -38px;" />
<input id="myInput" type="date" value="@Value" @onchange="this.DateChangedAsync" style="display:inline-block; " />
@code {
[Parameter]
public string Format { get; set; }
[Parameter]
public DateTime Value { get; set; }
[Parameter]
public EventCallback<DateTime> ValueChanged { get; set; }
[Parameter]
public string Class { get; set; }
protected override void OnParametersSet()
{
if (string.IsNullOrWhiteSpace(Format))
{
this.Format = "dd/MM/yyyy";
}
}
private async Task DateChangedAsync(ChangeEventArgs args)
{
string text = args.Value.ToString();
if (string.IsNullOrWhiteSpace(text))
{
return;
}
this.Value = DateTime.Parse(text);
await this.ValueChanged.InvokeAsync(this.Value);
}
}
我正在开发基于最新 Core 3.1 的 Blazor 项目。
UI 文化正确显示日期和数字,如图中所示。
但是当我使用 EditForm 时,数字和日期的格式不正确。
因此 EditForm 的这段代码
<InputDate id="date" class="form-control" @bind-Value="@TaskObject.Date" />
所以在 EditForm 中它看起来像这样,这是不正确的文化格式:
但在 UI 中看起来像这样,这没关系:
作为 Blazor 的新手,我尝试在线阅读不同的内容以获取有关此问题的一些知识。
所以我已经厌倦了以下内容:
- I want to change date format of form control class type is date?
- How to format the date using local culture using the blazor <InputDate /> tag
运气不好。
然后我尝试阅读 this and found this,它不适用于 Core 3.1。
我的问题是,究竟应该怎样做才能让 EditForm 像 UI 一样显示日期和数字,为什么 EditForm 会出现这种情况?
这不是 Blazor 问题,而是 type="date"
的 HTML <input>
元素的行为。
type="date"
所需的 format
是 Blazor 组件使用的 "yyyy-MM-dd"
。任何其他格式均无效。
如果我们做一点测试,我们可以验证这不是 Blazor 问题。
@page "/dates"
@using System.Globalization
<h3>Date</h3>
<p>@_dateString</p>
<input type="date" value="@_dateString" />
@code {
private string _dateString;
protected override void OnInitialized()
{
// using en-US culture
// this is what InputDate component does
_dateString = DateTime.Now.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);
}
}
_dateString
输出 2019-12-30
但 <input>
中显示的日期是 30/12/2019
有关 type=date
的详细信息可在 here 中找到。在“值”部分中,有一条说明如下:
The displayed date format will differ from the actual value — the displayed date is formatted based on the locale of the user's browser, but the parsed value is always formatted yyyy-mm-dd.
因此格式固定为用户浏览器的区域设置。
Why this happen for EditForm
内置的InputDate
/InputNumber
被设计为Culture-Invariant组件。参见 source code of InputDate and InputNumber。
What should exactly be done to make EditForm show date and number like the of UI,
我认为我们可以创建自定义 InputDate<TValue>
实现。然而,我错了。根据 MDN:
The displayed date is formatted based on the locale of the user's browser, but the parsed value is always formatted yyyy-mm-dd..
即使我们获得了支持当前 CultureInfo
的自定义 InputDate<TValue>
实现,我们仍然需要一些 js/css 来显示正确的格式。 IMO,没有标准的方法来实现这个。另见 this thread on SO.
我建议使用这个组件 https://blazorrepl.com/repl/wbambCPv20P0pX1h21
编辑: 如果 link 不起作用,这里是代码:
<style>
#myInput[type="date"] {
margin-top: 3px;
border: 0;
position: absolute;
width: 24px;
height: 24px;
}
#myInput[type="date"]::-webkit-inner-spin-button {
display: none;
}
#myInput[type="date"]::-webkit-calendar-picker-indicator {
margin: 0;
position: absolute;
}
#myInput[type=date]::-webkit-datetime-edit,
#myInput[type=date]::-webkit-datetime-edit-fields-wrapper {
-webkit-appearance: none;
display: none;
margin: 0;
padding: 0;
}
</style>
<input value="@this.Value.ToString(this.Format)" @onchange="this.DateChangedAsync" class="@Class" style="display:inline-block;margin-right: -38px;" />
<input id="myInput" type="date" value="@Value" @onchange="this.DateChangedAsync" style="display:inline-block; " />
@code {
[Parameter]
public string Format { get; set; }
[Parameter]
public DateTime Value { get; set; }
[Parameter]
public EventCallback<DateTime> ValueChanged { get; set; }
[Parameter]
public string Class { get; set; }
protected override void OnParametersSet()
{
if (string.IsNullOrWhiteSpace(Format))
{
this.Format = "dd/MM/yyyy";
}
}
private async Task DateChangedAsync(ChangeEventArgs args)
{
string text = args.Value.ToString();
if (string.IsNullOrWhiteSpace(text))
{
return;
}
this.Value = DateTime.Parse(text);
await this.ValueChanged.InvokeAsync(this.Value);
}
}