I need to produce a UTC time that is relevant to a specific location anywhere in the world such that when the client translates the time locally it will produce the expected time.
Let me be more concrete.
The user is in Paris, +1 UTC offset.
I need to ensure the time displayed by the UX is 0300.
But what I send in the JSON payload to be the UTC offset that will produce that.
So, in this case, it needs to be 0200 in the UTC time.
This is what I've got started, but I'm pretty green to date time operations like this, so I'm not quite sure I'm even building the foundation right.
public static DateTime ToUtcOffsetFromBaseTime(this NextRunTime nextRunTime, Base? staffBase)
{
ArgumentNullException.ThrowIfNull(staffBase, nameof(staffBase));
var instant = DateTime.UtcNow.ToInstant();
var baseOffset = staffBase.OffsetAsOf(instant);
if (baseOffset.HasValue)
{
// get the NOW local offset time
var baseOffsetInstant = instant.WithOffset(baseOffset.Value);
// set the local time to the next run time
baseOffsetInstant.PlusHours(baseOffsetInstant.Hour - nextRunTime.Hour);
baseOffsetInstant.PlusMinutes(baseOffsetInstant.Minute - nextRunTime.Minute);
// offset it to the relative UTC time and return
return baseOffsetInstant.ToDateTimeOffset().UtcDateTime;
}
throw new Exception($"The base offset for {staffBase.BaseCode} could not be found for the date/time {instant}.");
}
The NextRunTime has the hour and minute that it needs to represent locally. So you might have an Hour of 3 and a Minute of 0 such that it needs to represent 0300 local time when the client converts it to local time. Or, you might have something like 9 for the Hour and 45 for the Minute.
public class NextRunTime
{
public required int Hour { get; set; }
public required int Minute { get; set; }
public required string Type { get; set; }
}
But, I'm not sure where to go from here honestly, and I'm not sure what I've even started with is right.
I finally got it worked out. In the end my original solution wasn't too far off.
The basic flow can be described like this:
Baseoffset from the databaseI added the
asOffor unit testing.The reason this flow is so important is because the relative UTC time for each local location is going to be different.
If anybody knows a cleaner way of doing the same thing, let me know.
Here is a unit test that validates it.