How to convert any timestamp of a given timezones into UTC?

86 Views Asked by At

I need a function that converts any given timestamp in a given TimeZone into UTC. I started by using the UTC-Offset of the source-timezone, but then it turns out, that this is not always correct because it does not respect the indiviual offset including/excluding the daylight saving time (DST) offset. The problem here is the fact, that DST starts/ends at different dates for many timezones. How can I fix that so that it works on any timestamp and for any timezone?

Here the initial Powershell code I made without respecting the daylight saving time:

$sourceTime = [datetime]::new(2024,3,12,10,0,0)
$sourceZone = 'Pacific Standard Time'
$utcOffset  = (Get-TimeZone -Id $sourceZone).BaseUtcOffset
write-host 'UTC-time:' ($sourceTime - $utcOffset)
2

There are 2 best solutions below

0
Jon Skeet On

Use the TimeZoneInfo.ConvertTimeToUtc method.

But you should be aware that a value expressed as a local date/time might be invalid or ambiguous due to DST changes. (A value of 2024-03-10T02:30 for Pacific Time would be invalid, for example, because the clocks went forward from 2am to 3am.) You can detect this with the IsAmbiguousTime and IsInvalidTime methods.

0
Carsten On

The TimeZoneInfo.ConvertTimeToUtc method is the solution. Here is a working sample that shows the DST offset in action:

$sourceTime1 = [datetime]::new(2024, 1, 12, 10, 0, 0)
$sourceTime2 = [datetime]::new(2024, 3, 12, 10, 0, 0)
$sourceZone = 'Pacific Standard Time'

$tz = Get-TimeZone -Id $sourceZone
try {$utcTime1 = [TimeZoneInfo]::ConvertTimeToUtc($sourceTime1, $tz) } catch {$utcTime1 = 'invalid'}
try {$utcTime2 = [TimeZoneInfo]::ConvertTimeToUtc($sourceTime2, $tz) } catch {$utcTime2 = 'invalid'}
write-host 'UTC-time1:' $utcTime1
write-host 'UTC-time2:' $utcTime2

That gives this correct output:

UTC-time1: 12/01/2024 18:00:00
UTC-time2: 12/03/2024 17:00:00