Microsoft Virtualization Discussions



Alright guys, I have an interesting thing happening and I am not sure if it is a CMDLET bug or ONTAP bug.


When I login to my 9.1 system via SSH and check the date and time, everything comes back normal. When I view the system with systems manager everything looks normal there too. However....when I run (Get-NcTime) on the same system I get the proper UTC time, but the Local time is showing 4 hours ahead. My system is in the US/Eastern timezone, so we are currtnely UTC-4. 


Now, when I move my systems timezone to UTC+4 to (Kabul) for instance and run the (Get-NcTime) CMDLET, once again the UTC time is returned properly, but the Local time is returned as what was expected when I have my timezone as US\Eastern. It is like the offset was reveresed from what it should be. I am not sure how PowerCLI is getting the info and presenting it from the controller, but something is definately not right. 


Anyone have any ideas?


My client I am running this from and the storage array are all in the same timezone. 


Here is my output from this:




Timezone TimezoneUtc TimezoneVersion
-------- ----------- ---------------
US/Eastern -0400 2016j



NcController : piesdcl01
LocalTime : 1493935666
UtcTime : 1493921266
LocalTimeDT : 5/4/2017 10:07:46 PM
UtcTimeDT : 5/4/2017 6:07:46 PM



Now setting timezone ahead 4 hours:




Timezone TimezoneUtc TimezoneVersion
-------- ----------- ---------------
Asia/Kabul +0430 2016j



NcController : piesdcl01
LocalTime : 1493905093
UtcTime : 1493921293
LocalTimeDT : 5/4/2017 1:38:13 PM
UtcTimeDT : 5/4/2017 6:08:13 PM





I just went through this myself. You are better off calculating the local time using the UtcTime output from Get-NcTime, the TimezoneUtc offset from Get-NcTimezone and the [System.DateTimeOffset] .Net class.


Note that the 'DateTime' property will be the cluster local time, while the 'LocalDateTime' will be your host's local time using this method. 'UtcTime' will be correct. In this example, the cluster is in US/Central (-05:00) and my host is in US/Mountain (-06:00), hence the hour difference between the LocalDateTime and DateTime properties. The DateTimeOffset class will always use the timezone on your local host for its calculations when using the .FromUnixTimeSeconds() method. Also, the FromUnixTimeSeconds() method is only available with .Net 4.5 and above. But, there are other ways to calculate the Unix timestamps if necessary.


PS C:\> $tzUtcOffset = (Get-NcTimezone).TimezoneUtc
#The $tzUtcOffset.Insert() code at the end of this line is just converting the ONTAP offset format '-0500' to a proper timespan format '-05:00'
PS C:\> [System.DateTimeOffset]::FromUnixTimeSeconds((Get-NcTime).UtcTime).ToOffset($tzUtcOffset.Insert(($tzUtcOffset.Length - 2), ':'))

DateTime : 5/4/2017 2:06:45 PM UtcDateTime : 5/4/2017 7:06:45 PM LocalDateTime : 5/4/2017 1:06:45 PM Date : 5/4/2017 12:00:00 AM Day : 4 DayOfWeek : Thursday DayOfYear : 124 Hour : 14 Millisecond : 0 Minute : 6 Month : 5 Offset : -05:00:00 Second : 45 Ticks : 636295036050000000 UtcTicks : 636295216050000000 TimeOfDay : 14:06:45 Year : 2017


In fact, I have started converting all my timestamps to a DateTimeOffset object so I can easily use either DateTime or UtcDateTime, depending on what makes sense for that particular property.


If you need to calculate past timestamps you should look into the NodaTime library and use the (Get-NcTimezone).Timezone property. The reason for this is that NodaTime is aware of daylight savings time and other ambiguities with timezones (they are a mess). For instance, using just the offset with a timestamp in the Mountain timezone from December would currently be 1 hour off since in December it was -07:00 but is -06:00 now (does that make sense)?


This example below is essentially the same output as above since I'm using the current time for this, but this will calculate the proper DateTime for a previous timestamp that fell under a different UTC offset for a given timezone.


To use NodaTime (which is a fantastic library if you need to use it):


PS C:\> Add-Type -Path '<path>\NodaTime.dll'
PS C:\> $tz = [NodaTime.DateTimeZoneProviders]::Tzdb[(Get-NcTimezone).Timezone]
PS C:\> [NodaTime.Instant]::FromSecondsSinceUnixEpoch((Get-NcTime).UtcTime).InZone($tz).ToDateTimeOffset()

DateTime : 5/4/2017 2:10:58 PM UtcDateTime : 5/4/2017 7:10:58 PM LocalDateTime : 5/4/2017 1:10:58 PM Date : 5/4/2017 12:00:00 AM Day : 4 DayOfWeek : Thursday DayOfYear : 124 Hour : 14 Millisecond : 0 Minute : 10 Month : 5 Offset : -05:00:00 Second : 58 Ticks : 636295038580000000 UtcTicks : 636295218580000000 TimeOfDay : 14:10:58 Year : 2017 

I believe there were some BURTs in the past regarding this from an ONTAP perspective and Get-NcTime tries to work around it. At least, that is what I remember from when I dug into this recently. I owe the toolkit team an email on the topic to try to get this resolved.


Don't get me started on trying to calculate ASUP timestamps back to UTC. 🙂 (spoiler alert: you can't with any certainty since the timezone information is not part of the ASUP payload)




This appears to be a bug in the PowerShell Toolkit.  ZAPI returns the correct values for localtime and utctime, but the toolkit is doing something with localtime to throw it off (by 8 hours for me).


I created a bug for this (1098245), however it may be related to 1047513.


As a workaround, you could do something like this...


# ref
# Converting a Unix (epoc) timestamp to a PowerShell object
function Get-UnixDate ($UnixDate) {

$result = Invoke-NcSystemApi "<clock-get-clock />"


Which will output a PowerShell DateTime object you can use just like the "LocalTimeDT" property of the Get-NcTime output.


Hope that helps.



If this post resolved your issue, please help others by selecting ACCEPT AS SOLUTION or adding a KUDO.