Reputation: 789
I have a script that accepts a start date and a start time as separate parameters. If no start date is provided, I assume they want the date to be today and if no start time, I want to assume it should be "whatever time it is right now".
I don't want to constrain (much) the way that the user inputs the date or time. For example, I want them to be able to enter do -StartDate (Get-Date)
so I need to be able to accept that object (which includes the time), then, because no StartTime was entered, I need to replace whatever time is on the object, with the current time.
I thought about saying that if there is a time in the $StartDate
variable, then use it, but if they do -StartDate 07/10/2018
, then I still need to add the time anyway.
After some searching, this is what I tried and the result:
PS C:\> Get-Date
Tuesday, July 10, 2018 3:15:58 PM
PS C:\> $StartDate = (Get-Date).AddDays(1)
>> $StartTime = [DateTime]::ParseExact((Get-Date -Format HH:mm).ToString(),"HH:mm",[System.Globalization.CultureInfo]::InvariantCulture)
>> [datetime]$StartDate = $StartDate
>> $StartDate = $StartDate.Add([System.Timespan]::Parse($StartTime))
>> $StartDate
Exception calling "Parse" with "1" argument(s): "String was not recognized as a valid TimeSpan."
At line:4 char:1
+ $StartDate = $StartDate.Add([System.Timespan]::Parse($StartTime))
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : FormatException
Wednesday, July 11, 2018 3:16:10 PM
So, I think the question is, "how do I take a particular time and insert it into a datetime object?" Or maybe there is a better way to achieve my goal, that's cool too.
Thanks.
Upvotes: 0
Views: 2987
Reputation: 789
Using a suggestion from Ansgar Wiechers, this modified function works the way I want it to:
function foo {
Param(
[Parameter(Mandatory = $true)]
[DateTime]$StartDate,
[String]$StartTime
)
If (-NOT($StartTime)) {
$currentTime = Get-Date
$StartDate.Date.Add((New-Timespan -Hour $currentTime.Hour -Minute $currentTime.Minute))
}
Else {
$StartDate.Date.Add([Timespan]::Parse($StartTime))
}
}
# Tomorrow, at the current time
foo -StartDate (Get-Date).AddDays(1)
# Tomorrow at 13:30
foo -StartDate (Get-Date).AddDays(1) -StartTime '13:30'
# July 5, 2018 at the current time
foo -StartDate "07-05-2018"
Upvotes: 0
Reputation: 61068
You can Zero-out the time part of a DateTime object using $StartDate = (Get-Date).Date
.
To get just the time part of a DateTime object (returned as a TimeSpan object) you can use (Get-Date).TimeOfDay
To test wether the user gave you a ful date including time or not (and if not add the current time to it) this may do the trick for you:
if ($StartDate.TimeOfDay -eq [TimeSpan]::Zero) {
$StartDate = $StartDate.AddSeconds($StartTime.TotalSeconds)
}
$StartDate
Upvotes: 0
Reputation: 200273
You can always construct a date via the respective parameters of Get-Date
, e.g.
Get-Date -Hour 8 -Minute 30
will give you today's date with the time 8:30.
You can also take just the date portion of a DateTime
value like this:
$today = (Get-Date).Date
add a couple days (or just one)
$tomorrow = $today.AddDays(1)
and then add the desired timespan:
$time = New-Timespan -Hour 8 -Minute 30
$tomorrow.Add($time)
which can also be daisy-chained:
$time = New-Timespan -Hour 8 -Minute 30
(Get-Date).Date.AddDays(1).Add($time)
In your particular scenario you would take the start date as a DateTime
value, strip off the time, then add the timespan e.g. from a string parameter:
Param(
[Parameter(Mandatory=$true)]
[DateTime]$StartDate,
[Parameter(Mandatory=$true)]
[String]$StartTime
)
$StartDate.Date.Add([Timespan]::Parse($StartTime))
and invoke it like this:
foo -StartDate (Get-Date) -StartTime '8:30'
or you'd use different parameters for hour and minute:
Param(
[Parameter(Mandatory=$true)]
[DateTime]$StartDate,
[Parameter(Mandatory=$true)]
[ValidateRange(0,23)]
[Integer]$Hour,
[Parameter(Mandatory=$false)]
[ValidateRange(0,59)]
[Integer]$Minute = 0
)
$StartDate.Date.Add((New-Timespan -Hour $Hour -Minute $Minute))
and invoke the script/function like this:
foo -StartDate (Get-Date) -Hour 8 -Minute 30
Upvotes: 3