Reputation: 61
var timezoneOffsetInMinutes = new Date().getTimezoneOffset();
console.log(timezoneOffsetInMinutes);
Api receives the offset
public DateTimeOffset GetDateTimeOffsetAtTimezone(int timezoneOffsetInMinutes)
{
var utc = DateTime.UtcNow;
utc.AddMinutes(timezoneOffsetInMinutes); //Apply the offset
var result = new DateTimeOffset(utc, TimeSpan.FromMinutes(timezoneOffsetInMinutes)); //Set the offset
return result;
}
For some reason i get this error message
"The UTC Offset for Utc DateTime instances must be 0. (Parameter 'offset')"
I don't want to use NodaTime because I already have the timezoneOffset and i just need to apply it. Unless I am wrong about this and I should use NodaTime.
If you know the correct way of doing this that would be really helpful.
Upvotes: 1
Views: 2436
Reputation: 241603
To answer your question directly as asked:
public DateTimeOffset GetDateTimeOffsetAtTimezone(int timezoneOffsetInMinutes)
{
// Start out with the current UTC time as a DateTimeOffset
DateTimeOffset utc = DateTimeOffset.UtcNow;
// Get the offset as a TimeSpan
TimeSpan offset = TimeSpan.FromMinutes(timezoneOffsetInMinutes);
// Apply the offset to the UTC time to calculate the resulting DateTimeOffset
DateTimeOffset result = utc.ToOffset(offset);
return result;
}
That said - be sure you are only doing this when you are relaying the current time zone offset - the one that's valid now on the client, and now on the server (a reasonable transmission delay is acceptable). To understand why, refer to to "Time Zone != Offset" in the timezone tag wiki.
If you also need to work with times other than now, then you'll need to instead gather the time zone ID from the client, not the offset.
var timeZoneId = Intl.DateTimeFormat().resolvedOptions().timeZone;
console.log(timeZoneId);
That will return an IANA time zone identifier, such as America/Los_Angeles
.
On the server side, you have choices:
On a non-Windows system (Linux, OSX, etc.):
public DateTimeOffset ConvertDateTimeOffsetToTimeZone(DateTimeOffset dto, string ianaTimeZoneId)
{
// Get the time zone by its identifier
TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById(ianaTimeZoneId);
// Convert the input value to the time zone
DateTimeOffset result = TimeZoneInfo.ConvertTime(dto, tz);
return result;
}
On any OS (including Windows) using my TimeZoneConverter library:
using TimeZoneConverter;
public DateTimeOffset ConvertDateTimeOffsetToTimeZone(DateTimeOffset dto, string ianaTimeZoneId)
{
// Get the time zone by its identifier
TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById(ianaTimeZoneId);
// Convert the input value to the time zone
DateTimeOffset result = TimeZoneInfo.ConvertTime(dto, tz);
return result;
}
On any OS (including Windows) using the Noda Time library:
using NodaTime;
public DateTimeOffset ConvertDateTimeOffsetToTimeZone(DateTimeOffset dto, string ianaTimeZoneId)
{
// Get the time zone by its identifier
DateTimeZone tz = DateTimeZoneProviders.Tzdb[ianaTimeZoneId];
// Convert the input value to the time zone
DateTimeOffset result = OffsetDateTime.FromDateTimeOffset(dto)
.InZone(tz)
.ToDateTimeOffset();
return result;
}
Of course, if you were using Noda Time throughout your project then you might prefer to keep things in terms of Noda Time's types rather than converting back and forth.
Upvotes: 3