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?
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");
}
}
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;
}
}
@inject IJSRuntime JSRuntime
to get the users current time and then perform the calculation that way –
Resolvable 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");
}
}
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();
}
© 2022 - 2024 — McMap. All rights reserved.