Search code examples
c#serverlocalizationutcblazor-server-side

Report Local time and not Server Time From UTC


I have created a page where weather data is displayed for the user as reported by the server. The time is saved as UTC, how can one show the local user's or browser's time from a Blazor Server app?


Solution

  • It's not possible to get the user time without javascript.
    If you use Blazor Server Side, the C# Code runs on the server. But you can call javascript functions.
    See https://learn.microsoft.com/en-us/aspnet/core/blazor/call-javascript-from-dotnet?view=aspnetcore-3.1

    Here is a javascript to get the user date and timeoffset (add the script tag inside the header element of your _Host.cshtml):

    <script>
        window.localDate = () => {
            var ldCurrentDate = new Date();
            return ldCurrentDate.getFullYear() +
                "-" + String(ldCurrentDate.getMonth() + 1).padStart(2, '0') +
                "-" + String(ldCurrentDate.getDate()).padStart(2, '0') +
                "T" +
                String(ldCurrentDate.getHours()).padStart(2, '0') +
                ":" + String(ldCurrentDate.getMinutes()).padStart(2, '0') +
                ":" + String(ldCurrentDate.getSeconds()).padStart(2, '0');
        };
        window.utcDate = () => {
            var ldCurrentDate = new Date();
            return ldCurrentDate.getUTCFullYear() +
                "-" + String(ldCurrentDate.getUTCMonth() + 1).padStart(2, '0') +
                "-" + String(ldCurrentDate.getUTCDate()).padStart(2, '0') +
                "T" +
                String(ldCurrentDate.getUTCHours()).padStart(2, '0') +
                ":" + String(ldCurrentDate.getUTCMinutes()).padStart(2, '0') +
                ":" + String(ldCurrentDate.getUTCSeconds()).padStart(2, '0');
        };
        window.timeZoneOffset = () => {
            return new Date().getTimezoneOffset() / 60;
        };
    </script>
    

    Call from C#:

    @page "/dates"
    @inject IJSRuntime JSRuntime;
    
    <button type="button" @onclick="GetDates">
        Get Dates
    </button>
    
    <p>
        <span>
            User Date: @string.Format("{0:G}", this.UserDate)
        </span>
    </p>
    <p>
        <span>
            Utc Date: @string.Format("{0:G}", this.UTCDate)
        </span>
    </p>
    <p>
        <span>
            TimeZoneOffset: @string.Format("{0}", this.TimeZoneOffset)
        </span>
    </p>
    <p>
        <span>
            ServerDate: @string.Format("{0:G}", this.ServerDate)
        </span>
    </p>
    
    
    @code {
    
        private DateTime UserDate { get; set; }
        private DateTime UTCDate { get; set; }
        private DateTime ServerDate { get; set; }
        private int TimeZoneOffset { get; set; }
    
    
        private async Task GetDates()
        {
            this.ServerDate = DateTime.Now;
            this.UserDate = await JSRuntime.InvokeAsync<DateTime>("localDate");
            this.UTCDate = await JSRuntime.InvokeAsync<DateTime>("utcDate");
            this.TimeZoneOffset = await JSRuntime.InvokeAsync<int>("timeZoneOffset");
        }
    }