How to convert from a INT value HHMMSS to TimeSpan using PowerShell - powershell

I'm creating an application in PowerShell to reschedule the existing jobs in a SQL Server instance. So I have to get the active_start_time value from the sysschules table. The time value is formatted as INT HHMMSS on a 24-hour clock.
As I am using the JobSchedule class (Microsoft.SqlServer.Management.Smo.Agent.JobSchedule) in my PowerShell application, I need to convert from time value in INT to a TimeSpan value in order add to ActiveStartTimeOfDay property.
Example:
Original data: [INT] active_start_time = 10500
Expected data: [TimeSpan] ActiveStartTimeOfDay = 01h 05 min 00s

As FoxDeploy points out, treat the input number as a string!
First, you'll want to use String.PadLeft() to zero-pad the number:
$active_start_time = 10500
$start_timestamp = "$active_start_time".PadLeft(6, '0') # "010500"
Now that we have a "timestamp" of sorts, [timespan] has a ParseExact() method we can use to parse any format:
$start_timespan = [timespan]::ParseExact($start_timestamp, 'hhmmss', $null)

We can do this by taking your input int and treating it like a string. Doing that lets us call ToCharArray() which does this.
$myString = "Hi!"
$myString.ToCharArray()
H
i
!
Once it's in a char array, we can select out the positions of the characters we want by specifying its index, starting with zero, like this:
PS> $myString.ToCharArray()[0] #get's the first
H
Applying that to your scenario, we do the same to select only the numbers we want and tuck them into variables to call on later. With that, we can easily build a new [TimeSpan] object.
$inputInt = 121515
$hours= $inputInt.ToString().ToCharArray()[0..1] -join ''
$mins= $inputInt.ToString().ToCharArray()[2..3] -join ''
$secs = $inputInt.ToString().ToCharArray()[4..5] -join ''
$hours,$mins,$secs -join ":"
Output> 12:15:15
There are a lot of options to make a new [TimeSpan], we can see our choices by typing the static class name and method, and seeing what comes up.
PS> [timespan]::new
OverloadDefinitions
-------------------
timespan new(long ticks)
timespan new(int hours, int minutes, int seconds)
timespan new(int days, int hours, int minutes, int seconds)
timespan new(int days, int hours, int minutes, int seconds, int milliseconds)
That second one looks promising...
$newTimeSpan = [TimeSpan]::new($hours,$mins,$secs)
$newTimeSpan
This should get you heading in the right direction.

Related

Need to convert or format hhmmss to hh-mm-ss using powershell [duplicate]

I'm creating an application in PowerShell to reschedule the existing jobs in a SQL Server instance. So I have to get the active_start_time value from the sysschules table. The time value is formatted as INT HHMMSS on a 24-hour clock.
As I am using the JobSchedule class (Microsoft.SqlServer.Management.Smo.Agent.JobSchedule) in my PowerShell application, I need to convert from time value in INT to a TimeSpan value in order add to ActiveStartTimeOfDay property.
Example:
Original data: [INT] active_start_time = 10500
Expected data: [TimeSpan] ActiveStartTimeOfDay = 01h 05 min 00s
As FoxDeploy points out, treat the input number as a string!
First, you'll want to use String.PadLeft() to zero-pad the number:
$active_start_time = 10500
$start_timestamp = "$active_start_time".PadLeft(6, '0') # "010500"
Now that we have a "timestamp" of sorts, [timespan] has a ParseExact() method we can use to parse any format:
$start_timespan = [timespan]::ParseExact($start_timestamp, 'hhmmss', $null)
We can do this by taking your input int and treating it like a string. Doing that lets us call ToCharArray() which does this.
$myString = "Hi!"
$myString.ToCharArray()
H
i
!
Once it's in a char array, we can select out the positions of the characters we want by specifying its index, starting with zero, like this:
PS> $myString.ToCharArray()[0] #get's the first
H
Applying that to your scenario, we do the same to select only the numbers we want and tuck them into variables to call on later. With that, we can easily build a new [TimeSpan] object.
$inputInt = 121515
$hours= $inputInt.ToString().ToCharArray()[0..1] -join ''
$mins= $inputInt.ToString().ToCharArray()[2..3] -join ''
$secs = $inputInt.ToString().ToCharArray()[4..5] -join ''
$hours,$mins,$secs -join ":"
Output> 12:15:15
There are a lot of options to make a new [TimeSpan], we can see our choices by typing the static class name and method, and seeing what comes up.
PS> [timespan]::new
OverloadDefinitions
-------------------
timespan new(long ticks)
timespan new(int hours, int minutes, int seconds)
timespan new(int days, int hours, int minutes, int seconds)
timespan new(int days, int hours, int minutes, int seconds, int milliseconds)
That second one looks promising...
$newTimeSpan = [TimeSpan]::new($hours,$mins,$secs)
$newTimeSpan
This should get you heading in the right direction.

Powershell cast string to time only

I have created a Powershell/XAML app, that on button press makes a RESTAPI call, parses the JSON response into fields in the app front end. All fine so far.
These fields will be populated with a string representing a time, so "1800" or "2000" etc.
The user can then change this from 1800 to 1900 for example.
This is all fine, and in the background the app will use 1900 to update a setting to be used in a POST back.
However there are other settings that are offset by 90 mins of the time above. I don't want the user to have update each one, which is why I am trying to programmatically.
But try as I might, I cannot take a string of 1800, add 90 mins to it and make the value 1930 (not 1890).
You could parse the input as a DateTime object (ignoring the date part) and then use the AddMinutes method.
$input = '1800'
$hour = $input.Substring(0,2)
$minute = $input.Substring(2,2)
$dateInputStr = "0001-01-01,${hour}:${minute}:00"
[datetime]$dateInput = ([datetime]$dateInputStr)
$dateInput = $dateInput.AddMinutes(90)
$dateInput.ToString("HHmm")
Using [timespan] instances is another option:
$time = '1800'
([timespan] ($time -replace '(?<=^..)', ':') + '01:30').ToString('hhmm') #->'1930'
$time -replace '(?<=^..)', ':' uses the regex-based -replace operator to insert : after the first two characters - see this regex101.com page for an explanation of the regex and the ability to experiment with it.
Due to expressing the results only in terms of hours and minutes, the calculation wraps around at midnight, so that adding '05:30', for instance, would yield '0030'
The RHS operand needn't be cast to [timespan] directly, because the data type of the LHS - with its explicit [timespan] cast - implicitly converts the RHS to [timespan] too, with '01:30' representing 1 hour and 30 minutes, i.e. 90 minutes.
If you want to define the duration to add in terms of 90 minutes, use the following instead (there are analogous static methods for other units, such as ::FromSeconds():
[timespan]::FromMinutes(90)
Alternatively, you can cast a number to [timespan], which is interpreted as ticks, which are 100-nanosecond units; there are 1e9 (10 to the power of 9) nanoseconds in a second, and therefore 1e7 100-nanosecond units in a second. Thus, multiplying with 1e7 gives you seconds, and multiplying that with 60 minutes.
# 90 minutes expressed as ticks
[timespan] 90 * (60 * 1e7)
When I read this question I wanted to solve it with minimal string manipulation, leaning on time related objects and methods instead. datetime was the first object I thought of, but it expects a date (year, month, day). Things actually simplify if we use timespan. Its static method, ParseExact, can parse the string directly.
$offsetTimeSpan = [timespan]::FromMinutes(90)
$timeField = '830'
$timeStr = $timeField.PadLeft(4, '0')
$timeSpan = [timespan]::ParseExact($timeStr, 'hhmm', [CultureInfo]::InvariantCulture)
$offsetTime = $timeSpan.Add($offsetTimeSpan)
$offsetTime.ToString('hhmm')
$timeField is used to represent the time you get from the RESTAPI. PadLeft is only needed if it's possible for a leading 0 to be missing. ParseExact does the heavy lifting of converting the string to a time type. Because timespan doesn't have an AddMinutes member, we use the Add method passing in a timespan of 90 minutes, $offsetTimeSpan.
You don't mention anything about overflowing past midnight. You can test for overflow using $offsetTime.Days, if any special processing is required.

Get total mins for today

I am looking for total mins for today,
Tried this way but not working.
$from_date = Get-Date
$Start_date = $from_date.ToShortDateString()
($from_date - $Start_date).Minute
I'd do it this way:
PS C:\> (Get-Date).TimeOfDay.TotalMinutes
651.356536988333
Don't use ToShortDateString() if you want to do further arithmetic cprocessing on the object, it'll turn it into a string.
Substract the Date property from the object and grab the TotalMinutes property value from the resulting timespan:
$from_date = Get-Date
$MinutesSinceMidnight = ($from_date - $from_date.Date).TotalMinutes
The result will be in decimal form. Use Math.Floor() if you need an integer value:
[System.Math]::Floor($MinutesSinceMidnight)

Converting time in SPSS from hhmm:ss to hh:mm:ss (TIME8)

After a data export I get a string variable with "2017/02/22 1320:35 +000 4".
Through:
compute #TS = char.index(Timestamp_1, " ").
string date (A10).
compute date = char.substr(Timestamp_1,1,#TS).
alter type date (A10 = SDATE10).
I manage to get the date in a separate variable.
The same:
string time (A8).
compute time = char.substr(Timestamp_2,#TS+1,7).
alter type time (A8 = TIME8).
doesn't work for the time because it is in the 'hhmm:ss' format. How do I change the string variable '1320:35' into a time variable '13:20:35'?
You can insert a ":" manually into the time string by using the concat function before you alter the type.
COMPUTE time = CONCAT(CHAR.SUBSTR(time,1,2),":",(CHAR.SUBSTR(time,3))).
Another approach would be to extract hours, minutes and seconds from Timestamp variable individually and to use these elements inside the TIME.HMS function:
COMPUTE #hh = NUMBER(CHAR.SUBSTR(Timestamp_1,TS+1,2),F2).
COMPUTE #mm = NUMBER(CHAR.SUBSTR(Timestamp_1,TS+3,2),F2).
COMPUTE #ss = NUMBER(CHAR.SUBSTR(Timestamp_1,TS+6,2),F2).
COMPUTE time = TIME.HMS(#hh,#mm,#ss).
EXECUTE.
FORMATS time (TIME8).
Statistics has a datetime format and, new in V24, an ISO 8601 timestamp format, YMDHMS. If the string is converted to a regular date/time value, then the XDATE.DATE and XDATE.TIME functions can be used to extract the pieces. The Date and Time wizard may accommodate the format you have (not sure about that +000 4 part at the end).

How do you parse a millisecond number into HH:MM:SS

Can you tell me how to parse a millisecond number such as 10173510 into hours, minutes and seconds?
Formated like this maybe?
HH:MM:SS
Thanks.
Update:
I was able to get it close but I need to format the numbers correctly because I need leading zeros (0) to make the results look something like this: 01:52:03 because the code shows 1:52:3 instead.
Sub SeekBarTimeToKeepActive_ValueChanged (Value As Int, UserChanged As Boolean)
Dim intHoursToKeepActive As Int
Dim intMinutesToKeepActive As Int
Dim intSecondsToKeepActive As Int
intHoursToKeepActive = DateTime.GetHour(Value) -19
intMinutesToKeepActive = DateTime.GetMinute(Value)
intSecondsToKeepActive = DateTime.GetSecond(Value)
LabelTimeToKeepActive.Text = "Length of time to keep active: " & _
intHoursToKeepActive & ":" & intMinutesToKeepActive & ":" & intSecondsToKeepActive
End Sub
Try using Number Format:
Example:
Hour = 2
NumberFormat(hour,2,0)