rdavin

Powershell and DateTimeKind

Discussion created by rdavin Employee on Aug 5, 2013
Latest reply on Aug 7, 2013 by rdavin

I'm a newbie with Powershell but have already stumbled across issues with DateTime objects and the Kind property.  For so many applications, a simple DateTime is good enough but for process historians I believe extra caution is needed for making sure the DateTimeKind is correct.  I believe there is a bug with Get-PIArchive where an archive's StartTime and EndTime is incorrectly set with Kind=Unspecified when it should be Kind=Local.  

 

I've played around with some simple Powershell scripting just for DateTimes wanting to see if I could choose some past date and set it to be midnight at local time.  There's a lot of ways you think you can do this, but I only see 2 that yield the correct answer.  And I don't believe Get-Date allows you to ever explicitly set Kind=Utc, though 1 of my aforementioned methods does.

 

No OSIsoft commands are invoked in the code below.  

 

 

 
# Returns Now as a DateTime object with Kind=Local
$mydate = [DateTime]::Now

# Returns Today as a DateTime object with Kind=Local and set to midnight
$mydate = [DateTime]::Today

#****************************************************************************
#
# Now let's try to set another date to be both (1) Local and (2) at midnight
# Let's choose 'PI Day' 2013, i.e. Thursday March 14, 2013
#
#****************************************************************************

# Returns a DateTime object with Kind=Unspecified
# You probably don't want this because it is not Local.
$mydate = Get-Date -Date "3/14/2013"

# Returns a DateTime object with Kind=Local
# but it NOT midnight because -Hour, -Minute, -Second, and -Millisecond do NOT default to 0.
# You probably don't want this either.
$mydate = Get-Date -Year 2013 -Month 3 -Day 14
# You can inspect the DateTime properties to see that you are not at midnight:
write-host Time is $mydate.Hour":"$mydate.Minute":"$mydate.Second and $mydate.Millisecond milliseconds

# Returns a DateTime object with Kind=Local
# Time is at midnight because we were verbose.
# This is one way to get a DateTime object that is both (a) Local and (b) at Midnight.
$mydate = Get-Date -Year 2013 -Month 3 -Day 14 -Hour 0 -Minute 0 -Second 0 -Millisecond 0

#*************************************************************
#
# I don't believe Get-Date allows me to build a DateTime
# object explicitly with Kind=Utc.  Let me now switch to
# using .NET DateTime constructors.
#
#*************************************************************

# Returns a DateTime object with Kind=Unspecified
# Convenient and short, but ultimately wrong.
# You probably don't want this since it is not Local time.
$mydate = [DateTime] "3/14/2013"

# Returns a DateTime object with Kind=Unspecified
# Note no brackets around DateTime and commas in list.
# You probably don't want this either.
$mydate = new-object DateTime 2013, 3, 14

# Returns a DateTime object with Kind=Local and Time at midnight!
# Note no brackets around DateTime and commas in list but last parameter requires brackets and parenthesis!
# This is the other way to get a DateTime object that is both (a) Local and (b) at Midnight.
$mydate = New-Object DateTime 2013, 3, 14, 0, 0, 0, ([DateTimeKind]::Local)

# One advantage over the last assignment is that you can construct a DateTime
# explicitly with Kind=Utc by changing the last parameter, which you can't do with Get-Date:
$mydate = New-Object DateTime 2013, 3, 14, 0, 0, 0, ([DateTimeKind]::Utc)

 

Outcomes