Your answer is pretty close to what I'd do - but if you have the date, hour and minute in separate strings, I'd use:
var zoneProvider = DateTimeZoneProviders.Tzdb;
var sourceZone = zoneProvider.GetZoneOrNull("Europe/Brussels");
var targetZone = zoneProvider.GetZoneOrNull("Australia/Melbourne");
if (sourceZone == null || targetZone == null)
{
Console.WriteLine("Time zone not found");
return;
}
var dateParseResult = LocalDatePattern.IsoPattern.Parse(date);
int hourValue, minuteValue;
if (!dateParseResult.Success ||
!int.TryParse(hour, out hourValue) ||
!int.TryParse(minute, out minuteValue))
{
Console.WriteLine("Parsing failed");
return;
}
var localDateTime = dateParseResult.Value + new LocalTime(hour, minute);
var zonedDateTime = localDateTime.InZoneStrictly(sourceZone);
Console.WriteLine(zonedDateTime.ToInstant());
Console.WriteLine(zonedDateTime);
Console.WriteLine(zonedDateTime.WithZone(targetZone));
The only significant difference here is the parsing - I wouldn't stick all the bits together; I'd just parse the strings separately. (I also prefer "early outs" for failures :)
You should note the meaning of InZoneStrictly
though - do you definitely want to fail if the input local date/time is ambiguous?