Report Local time and not Server Time From UTC
Asked Answered
F

3

12

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?

Fanjet answered 26/8, 2020 at 14:28 Comment(3)
Since what you want is to check the local time of the user via the browser then you really need to implement it on a client side using javascript since c# are for server side code. An article that can give you a much detail about it, Are server-side and client-side programming the same?.Pacemaker
@PinBack Thank you very much for showing that ... I works great (on first glance ;)) And mybe I look a little more into JS because of your post telling me how to call a JS from blazor. I avoided that for too long nowFanjet
There is a tutorial how to do it: Convert DateTime to user's time zone with server-side BlazorSuperjacent
P
4

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");
    }
}
Podiatry answered 27/8, 2020 at 8:1 Comment(0)
R
7

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;
  }
}
Resolvable answered 5/5, 2021 at 5:4 Comment(2)
this answer will resolved the part of converting the server/utc time to local, but can't get local time in blazor codeGabrielson
That is correct, so if you are wanting to know how much more time to midnight then this would not be the correct library for you. You might want to consider using @inject IJSRuntime JSRuntime to get the users current time and then perform the calculation that wayResolvable
P
4

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");
    }
}
Podiatry answered 27/8, 2020 at 8:1 Comment(0)
S
1

You can read out local and UTC time and receive .NET DateTime type from JS much simpler:

  • Local time: new Date().toISOString();
  • UTC time: new Date().toUTCString();

Also note in .NET 5 JS Interop changed a lot. Please check out new IJSRuntime Interface and also JS Isolation docs as well.

By using .NET 5 JS isolation (calling JS functions are very similar but slightly changes, see docs above):

export function localDate() {
  return new Date().toISOString();
}
export function utcDate() {
  return new Date().toUTCString();
}
Spithead answered 15/1, 2021 at 13:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.