6
$\begingroup$

I have a list of time durations, which are strings of the form: "hh:mm:ss". Here's a sample for you to play with:

durations = {"00:09:54", "00:31:24", "00:40:07", "00:11:58", "00:13:51", "01:02:32"}

I want to convert all of these into numbers in seconds, so that I can actually do useful things with this data!

How would I go about doing this? There must be some way to get Mathematica to extract the relevant things from each string.

Thanks.

Edit: I'm surprised that there doesn't seem to be a question related to this already - but it may be that I was using the wrong search terms.

$\endgroup$
6
$\begingroup$

A method based on AbsoluteTime:

AbsoluteTime /@ durations - AbsoluteTime["00:00:00"]
(* {594, 1884, 2407, 718, 831, 3752} *)
$\endgroup$
5
$\begingroup$

One method:

3600 FromDMS[ToExpression[StringSplit[#, ":"]]] & /@ durations
   {594, 1884, 2407, 718, 831, 3752}
$\endgroup$
5
$\begingroup$

You didn't specify that performance is important but I decided to examine that aspect.

First I generate a list of 10,000 durations:

durations = 
  ToString@Row[#, ":"] & /@ 
   Map[IntegerString[#, 10, 2] &, 
    RandomInteger[{0, 24}, {10000, 3}], {2}];

I then time each of the existing solutions (using timeAvg, posted many times before):

AbsoluteTime /@ durations - AbsoluteTime["00:00:00"] // timeAvg

7.722

3600 FromDMS[ToExpression[StringSplit[#, ":"]]] & /@ durations // timeAvg

0.078

We see that at least with my test set and on my machine the second method is more than two orders of magnitude faster than the first, but I think we can do better:

FromDigits[#, 60] & /@ Map[FromDigits, StringSplit[durations, ":"], {2}] // timeAvg

0.02868

By using the undocumented function StringToDouble we can eek out a bit more:

timeAvg[
  FromDigits[#, 60] & /@ Map[Internal`StringToDouble, StringSplit[durations, ":"], {2}]
]

0.02248

This last method returns Reals instead of Integers, if that matters, but the time taken to Round is negligible:

seconds = 
  FromDigits[#, 60] & /@ Map[Internal`StringToDouble, StringSplit[durations, ":"], {2}];

Round[seconds] // timeAvg

0.00011488

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.