Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Powershell - convert local time to different timezone

Tags:

powershell

I am trying to convert my system time (EST) to a different timezone (GMT Standard Time) using PowerShell. I have to run this PowerShell command through my RPA automation software so I am looking to use a single command (instead of PS script) to accomplish this task if possible. Here's the command I am trying to use:

$test = Get-Date
[System.TimeZoneInfo}::ConvertTime($test, 'GMT Standard Time')

First line is just to show the logic I am thinking but I will pass it as a variable and so that I truly have to execute only one line of code. However, I get the following error:

PS C:\Users\samsi> [System.TimeZoneInfo]::ConvertTime($test, 'GMT Standard Time')
Cannot find an overload for "ConvertTime" and the argument count: "2".
At line:1 char:1
+ [System.TimeZoneInfo]::ConvertTime($test, 'GMT Standard Time')
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodException
    + FullyQualifiedErrorId : MethodCountCouldNotFindBest

Clearly, I don't know much about PowerShell, can someone please help me with this command.

like image 494
samsingla Avatar asked Oct 19 '17 16:10

samsingla


2 Answers

Try this and see if it gets you what you're after.

[System.TimeZoneInfo]::ConvertTimeBySystemTimeZoneId($(Get-Date), [System.TimeZoneInfo]::Local.Id, 'GMT Standard Time')

or if you prefer storing the current date in a variable first (the way you have it in your code)

$test = Get-Date
[System.TimeZoneInfo]::ConvertTimeBySystemTimeZoneId($test, [System.TimeZoneInfo]::Local.Id, 'GMT Standard Time')
like image 155
notjustme Avatar answered Nov 09 '22 23:11

notjustme


Let's look at how to diagnose this.

The error message:

Cannot find an overload for "ConvertTime" and the argument count: "2".

is a common one on PowerShell when calling methods on objects. Sometimes it's misleading. It always means that given the arguments you supplied, none of the method's overloads matched.

Aside: each method has one or more ways you can call it, with parameters of different types, or different number or order of parameters.

In PowerShell, you can see all the overloads by "invoking" the method without parentheses or arguments. So:

[System.TimeZoneInfo]::ConvertTime

Result:

OverloadDefinitions
-------------------
static System.DateTimeOffset ConvertTime(System.DateTimeOffset dateTimeOffset, System.TimeZoneInfo destinationTimeZone)
static datetime ConvertTime(datetime dateTime, System.TimeZoneInfo destinationTimeZone)
static datetime ConvertTime(datetime dateTime, System.TimeZoneInfo sourceTimeZone, System.TimeZoneInfo
destinationTimeZone)

The error message in PowerShell always references the number of arguments, but it sometimes also means that you didn't use the correct type.

So in your example, you did supply 2 arguments, which makes the error confusing.

But the second argument you supplied is a [string]. Looking at the available overloads, you can see that none of the second arguments take a string, they are all looking for an object of type [System.TimeZoneInfo].

Sometimes, you can use a different type, if there's an implicit cast available. For example if a method takes a parameter of type [System.Net.IPAddress] then you can give a string like '127.0.0.1'. That's because [System.Net.IPAddress] knows how to convert an IP string into the object. You can see this by doing something like '127.0.0.1' -as [System.Net.IPAddress] or [System.Net.IPAddress]'127.0.0.1'.

Going back to your use case: it seems you either cannot cast a string to the TimeZoneInfo type, or your string is not valid for that purpose (that is, the cast failed).

So you should first figure out how to create or retrieve a TimeZoneInfo object that represents what you want.

It looks to me like [System.TimeZoneInfo]::GetSystemTimeZones() returns an array of all the time zones on your system.

Filtering that list to find the one you want seems like a good idea. Looking at the list, I can see the string you want to use is in the StandardName property so I'll use this to get the right one:

$gmt = [System.TimeZoneInfo]::GetSystemTimeZones().Where({$_.StandardName -eq 'GMT Standard Time'})[0] # it's an array, so get the first one

Then you can call your original method with that object:

[System.TimeZoneInfo]::ConvertTime($test, $gmt)
like image 26
briantist Avatar answered Nov 09 '22 23:11

briantist