Powershell How to round a TimeSpan? - windows

I have a TimeSpan that I want to round before adding it to my file.
Sometimes its ok like this: 12:03:55 but sometimes it is like this: 04:12:32.96472749
It should not look like this just give me the seconds so I thought of rounding it up or down it doesnt even matter.
I tried this: ([Math]::Round($result)) => Where $result is the timespan but it is saying that the method is overloaded even though I saw it on StackOverflow like this...
also this does not work either: ([Math]::Round($result,2))
Maybe someone can help me because I think there is a special way to round TimeSpans and not normal decimals.
Edit:
I just checked out String Formatting like this:
$formattedTime = "{0:hh\:mm\:ss}" -f ([TimeSpan] $result)
It looks good but I need to add Days in front if the date goes over 24Hours .. so something like 'dd' maybe?
Ty Faded~

You cannot format a TimeSpan object as if it were a DateTime object.
For that, you need to put together your own format string and use the individual properties you need:
Without days:
$ts = [timespan]::new(0,12,3,55,964.72749)
('{0} {1:D2}:{2:D2}:{3:D2}' -f $ts.Days, $ts.Hours, $ts.Minutes, $ts.Seconds).TrimStart("0 ")
# returns 12:03:55
With days (same format string)
$ts = [timespan]::new(11,12,3,55,964.72749)
('{0} {1:D2}:{2:D2}:{3:D2}' -f $ts.Days, $ts.Hours, $ts.Minutes, $ts.Seconds).TrimStart("0 ")
# returns 11 12:03:55
The time properties of a TimeSpan object are ReadOnly, so you cannot set the Milliseconds to 0 unfortunately.
If you do want to get a 'rounded' TimeSpan object where the Milliseconds are stripped off, you can do this:
$ts = [timespan]::new(0,12,3,55,964.72749)
# create a new TimeSpan object from the properties, leaving out the MilliSeconds
$ts = [timespan]::new($ts.Days, $ts.Hours, $ts.Minutes, $ts.Seconds)

Related

how to convert mm:ss.000 to s.ms using Posixct and strptime

One of my first posts, so I'll do my best. I've tried searching this, which is how I got this far..but I could use some help converting some time data in the form mm:ss.000 (that's milliseconds at the end) to seconds with a fraction at the end. For example, 2:15.45 should come out to 135.45.
This works:
t <- "02:15.45" (as.numeric(as.POSIXct(strptime(t, format = "%M:%OS"))) - as.numeric(as.POSIXct(strptime("0", format = "%S"))))
But this one, where I'm trying to use a column of my dataframe (originally in character form) does not work:
starttimesFPsnapjumps <- FPsnapjumps$start (as.numeric(as.POSIXct(strptime(starttimesFPsnapjumps, format = "%M:%OS"))) - as.numeric(as.POSIXct(strptime("0", format = "%S"))))
Perhaps it's because my numbers in the column have an extra 0 - they are mm:ss.000. Any thoughts? Thanks in advance.

Strange format from JodaTime when calculating time difference with Java

I am trying to find the duration between two times with the below code:
DateTimeFormatter formatter = DateTimeFormat.forPattern("HH:mm");
System.out.println(airTime1);
System.out.println(startTime1);
Minutes difference = ((Minutes.minutesBetween(startTime1,airTime1)));
String differenceS = String.valueOf(difference);
System.out.println(differenceS);
LocalTime remaining1 = formatter.parseLocalTime(differenceS);
System.out.println(remaining1);
airTime1 & startTime1 are both localTime variables. difference should contain the duration between the two times. differenceS is a String representation of difference, as minutes cannot be converted to String.
When I enter times into the variables such as 12:00 & 13:00, the variables are recorded as: 12:00:00.000 & 13:00:00.000, but differenceS received a value of PT-60M, which obviously throws an error. Does anyone know why the minutes difference line could be calculating this value?
Thanks in advance!
The Minutes class of jodatime overwrites the toString() method in a way that returns a String in ISO8601 duration format as mentioned in the JavaDoc. This is exactly what your PT-60M represents. A duration of -60 minutes.
If you just want the raw minutes printed your code could look like this:
DateTimeFormatter formatter = DateTimeFormat.forPattern("HH:mm");
System.out.println(airTime1);
System.out.println(startTime1);
Minutes difference = Minutes.minutesBetween(startTime1,airTime1);
System.out.println(Math.abs(difference.getMinutes()));

Calculating days in Ruby

I have an issue where, I'm trying to work out if a certain alert on a webpage is calculating sums correctly. I'm using Capybara and Cucumber.
I have an alert that calculates records that expire within 30 days. When selecting this alert, the records are listed in a table and the date is presented in the following format, "1 feb 2016"
What I want to do is somehow take today's date, compare it to the date returned in the table and ensure that it's >= 30 days from the date in the alert.
I'm able to set today's date as the same format using Time.strftime etc.
When I try things like:
And(/^I can see record "([\d]*)" MOT is calculated due within 30 days$/) do |selection1|
today = Time.now.strftime('%l %b %Y')
thirty_days = (today + 30)
first_30day_mot = first('#clickable-rows > tbody > tr:nth-child(' + selection1 + ') > td:nth-child(3)')
if today + first_30day_mot <= thirty_days
puts 'alert correct'
else
(error handler here)
end
end
As you can see, this is quite a mess.
I keep getting the error TypeError: no implicit conversion of Fixnum into String
If anyone can think of a neater way to do this, please put me out of my misery.
Thanks
There are at least a couple of things wrong with your attempt.
You're converting dates to strings and then trying to compare lengths of time with strings. You should be converting strings to dates and then comparing them
#first returns the element in the page not the contents of the element
It's not 100% clear from your code what you're trying to do, but from the test naming I think you just want to make sure the date in the 3rd td cell (which is in the 1 feb 2016 format) of a given row is less than 30 days from now. If so the following should do what you want
mot_element = first("#clickable-rows > tbody > tr:nth-child(#{selection1}) > td:nth-child(3)")
date_of_mot = Date.parse(mot_element.text)
if (date_of_mot - Date.today) < 30
puts 'alert correct'
else
#error handler
end
Beyond that, I'm not sure why you're using #first with that selector since it seems like it should only ever match one element on the page, so you might want to swap that to #find instead, which would get you the benefits of Capybaras waiting behavior. If you do actually need #first, you might consider passing the minimum: 1 option to make sure it waits a bit for the matching element to appear on the page (if this is the first step after clicking a button to go to a new page for instance)
Convert selection1 to the string explicitly (or, better, use string interpolation):
first_30day_mot = first("#clickable-rows > tbody > tr:nth-child(#{selection1}) > td:nth-child(3)")
Also, I suspect that one line below it should be converted to integer to add it to today:
first_30day_mot.to_i <= 30
UPD OK, I finally got time to take a more thorough look at. You do not need all these voodoo magic with days calculus:
# today = Time.now.strftime('%l %b %Y') # today will be a string " 3 Feb 2016"
# thirty_days = (today + 30) this was causing an error
# correct:
# today = DateTime.now # correct, but not needed
# plus_30_days = today + 30.days # correct, but not needed
first_30day_mot = first("#clickable-rows > tbody > tr:nth-child(#{selection1}) > td:nth-child(3)")
if 30 > first_30day_mot.to_i
...
Hope it helps.
I'd strongly recommend not using Cucumber to do this sort of test. You'll find its:
Quite hard to set up
Has a high runtime cost
Doesn't give enough benefit to justify the setup/runtime costs
Instead consider writing a unit test of the thing that provides the date. Generally a good unit test can easily run 10 to 100 times faster than a scenario.
Whilst with a single scenario you won't experience that much pain, once you have alot of scenarios like this the pain will accumulate. Part of the art of using Cucumber is to get plenty of bang for each scenario you write.

Variable naming in for loops

I'm writing a function that supposed to work with lists of lists, and if I use this example:
def mode(year):
monthAmount = len(year)
for month in year:
(month)Index = len(month)
What I want this to do is, say year is [January, February, March], the results should be something like this: JanuaryIndex = *, FebruaryIndex = *, MarchIndex = *, and so on; with a number of different months. Is there an easy way to do this? Thanks.
I am not entirely sure what you are looking for here.
To get an index into a sequence you are looping over together with the actual value, use the enumerate() function:
for index, month in enumerate(year):
print index, month
You really do not want to dynamically set global variables. Use a dictionary instead:
monthindices = {}
for month in year:
monthindices[month] = len(month)
You can create global variables dynamically, by accessing the globals() mapping, but doing this is generally a bad idea. You'd do it like this if you are stubborn:
gl = globals()
for month in year:
gl['{}Index'.format(month)] = len(month)

ruby DateTime#strptime cannot handle '%6N'?

time_format = '%H.%M.%S.%6N'
timestamp = DateTime.now.strftime(time_format) # this works, it shows something like "10.09.53.595977"
DateTime.strptime(timestamp, time_format) # error, in `strptime': invalid date (ArgumentError)
So is it possible to make the #strptime work if I really want to parse the microsecond (6 digits) as well?
Looking at the ruby source code at ext/date/date_strptime.c it seems the N case is taken into account, try this:
DateTime.strptime(timestamp, '%H.%M.%S.%N')
And to check the seconds fraction was parsed try this:
d = DateTime.strptime(timestamp, '%H.%M.%S.%N')
p d.sec_fraction
And compare it with what you have in *time_format*.

Resources