Maytham Fahmi
Maytham Fahmi

Reputation: 33407

Localizing DateTime (and numbers) in Blazor

I am working on Blazor project based on latest Core 3.1.

The UI Culture show correctly dates and numbers as seen the in the image.

But the moment I used the EditForm the number and date is not formatted as it should be.

So this code part of EditForm

<InputDate id="date" class="form-control" @bind-Value="@TaskObject.Date" />

So in EditForm it looks like this, which is not correct culture format:

enter image description here

But in the UI looks like this, which is OK:

enter image description here

As I new in Blazor, I have tried to read different stuff online to get some knowledge regarding this issue.

So I have tired following:

without luck.

Then I tried to read this and found this which is not working with Core 3.1.

My question, what should exactly be done to make EditForm show date and number like the of UI, and Why this happen for EditForm?

Upvotes: 7

Views: 14431

Answers (3)

Borislav Nikolov
Borislav Nikolov

Reputation: 1

I suggest using this component https://blazorrepl.com/repl/wbambCPv20P0pX1h21

EDIT: Here is the code if the link does not work:

<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);
        }
}

Upvotes: 0

itminus
itminus

Reputation: 25350

Why this happen for EditForm

The built-in InputDate/InputNumber is designed as Culture-Invariant components. See source code of InputDate and InputNumber.

What should exactly be done to make EditForm show date and number like the of UI,

I thought we can create a custom InputDate<TValue> implementation. However, I was wrong. According to 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..

Even we get a custom InputDate<TValue>implementation that honors the current CultureInfo, we still need some js/css to display the correct format. IMO, there's no standard way to implement this. See also this thread on SO.

Upvotes: 5

Colin Bacon
Colin Bacon

Reputation: 15609

This is not a Blazor issue but rather the behaviour of the HTML <input> element of type="date".

The required format for type="date" is "yyyy-MM-dd" which the Blazor component uses. Any other format is not valid.

If we do a little test, we can verify it is not a Blazor issue.

@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 outputs 2019-12-30 but the date shown in the <input> is 30/12/2019

Detailed information on type=date can be found here. In the Value section there is a note which says the following:

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.

So the formatting is fixed to the locale of the users browser.

Upvotes: 3

Related Questions