Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Blazor Server Side: How can I read out the local time of the user/browser not of the server (using only c#)

Tags:

I have created a page where weather data is displayed for the user (I get the data via api call). I have the UTC-timestamp of the data from the api call.

My problem is that if I transform the UTC time via ToLocalTime() the local time of my Server is presented not the local time of the users browser.

Is there a way to show the user "their" time: UTCTime.ToUserTimeZone() with C# and Blazor only?

I have zero knowledge of JS etc. or is that the only way. I googled and found alot of answeres where I have to implement JavaScript to "get" the user localisation.

Thanks for your help and time

like image 381
nogood Avatar asked Aug 26 '20 14:08

nogood


2 Answers

I ran into a similar problem and created a library called Blazor Time to address it.

To install BlazorTime run Install-Package BlazorTime

Then add <script src="_content/BlazorTime/blazorTime.js"></script> to your host or index file

After that you can display values in the users local time with the <ToLocal> tag

<p>
  @*UTC to browser time*@
  <ToLocal DateTime="testUtcTime" Format="ddd mmm dd yyyy HH:MM:ss"></ToLocal>
</p>

<p>
  @*server time to browser time*@
  <ToLocal DateTime="testServerTime" Format="default"></ToLocal>
</p>

<p>
  @*display as iso example 2021-05-10*@
  <ToLocal DateTime="testUtcTime" Format="yyyy-mm-dd"></ToLocal>
</p>

<p>
  @*display as time example 2pm*@
  <ToLocal DateTime="testUtcTime" Format="htt"></ToLocal>
</p>

<button @onclick="Update">Update Time</button>

@code {
  private DateTime testUtcTime = DateTime.UtcNow;
  private DateTime testServerTime = DateTime.Now;

  private void Update()
  {
    testUtcTime = DateTime.UtcNow;
    testServerTime = DateTime.Now;
  }
}
like image 62
Dustin Gamester Avatar answered Oct 11 '22 20:10

Dustin Gamester


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://docs.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");
    }
}
like image 24
PinBack Avatar answered Oct 11 '22 21:10

PinBack