2

I am currently running few shell command in my android app and parsing the shell output on my app.

Currently my shell output is also returning a time duration between previous output. The duration is something like this -- time=+1d1h55m15s584ms

Now I am stuck in here. If there anyways to calculate this duration into milliseconds or turn it into exact timestamp?

Meno Hochschild
  • 42,708
  • 7
  • 104
  • 126
Rabbi Hossain
  • 25
  • 2
  • 3
  • 3
    The regular expression `time=\+(\d+)d(\d+)h(\d+)m(\d+)s(\d+)ms` will pick out those numbers as regexp groups. See http://fiddle.re/ft77dn. Then, run the calculation of days/hours/minutes/seconds/milliseconds into milliseconds. – CommonsWare Jan 21 '17 at 23:38
  • 2
    Still would like to know what shell command was used. Maybe the output can be changed there – OneCricketeer Jan 21 '17 at 23:49

2 Answers2

5

Do you have control over that string generation? If so use standard format instead.

ISO 8601

The ISO 8601 standard defines many textual formats for representing date-time values. This includes a format for durations such as yours: PnYnMnDTnHnMnS where the P marks the beginning and the T separates the years-month-days from the hours-minutes-seconds.

For example, an hour and a half is PT1H30M.

Using java.time

The java.time classes built into Java 8 and later, and back-ported to Java 6 & 7 & Android, use the ISO 8601 formats by default for both parsing and generating strings.

The java.time classes represent years-months-days as a Period object, and hours-minutes-seconds as a Duration object.

String input = "P1DT1H55M15.584S";
Duration d = Duration.parse ( input );

d.toString(): PT25H55M15.584S

d.toMillis(): 93315584

d.toNanos(): 93315584000000

String manipulation

If you cannot control the format of your input string, I would consider manipulating those inputs into standard format. Add the P, insert the T, and change the ms portion into a decimal fraction.


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

Where to obtain the java.time classes?

Community
  • 1
  • 1
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • Thanks, this solves the issue. Though I had to parse string with some if else statements. Cause sometimes the time string doesn't contains any day or hour instead it shows like time=+32m1s – Rabbi Hossain Jan 22 '17 at 07:56
2

The main problem with most answers suggesting string input preprocessing is that the input string can often not be changed.

So it is usually more flexible to adjust the parsing routine and not the input.

Either you have to code your own parsing routine, or you can use my library Time4A which offers direct support for parsing durations on pattern base (instead of ThreetenABP as suggested in answer of @Basil Bourque) and then using this code (version v3.28 or later):

String input = "+1d1h55m15s584ms";
String pattern = "+[#D'd'][#h'h'][#m'm'][#s's'][fff'ms']";

long totalMillis =
    Duration.formatter(pattern)
    .parse(input)
    .toClockPeriodWithDaysAs24Hours()
    .with(ClockUnit.MILLIS.only())
    .getPartialAmount(ClockUnit.MILLIS);
System.out.println(totalMillis); // 93315584

Explanation in detail

About the pattern syntax:

  • The square brackets indicate optional components which are not mandatory in input.
  • All parts escaped by apostrophs are handled as literals.
  • The pattern symbol "+" is a placeholder for either a positive or a negative sign.
  • The symbols D, h, m, s, f stand for: days, hours, minutes, seconds and fractional seconds.
  • If such a symbol is preceded by "#" then this special pattern char marks an additional leading digit, this way indicating the maximum number of allowed digits.

After the input has been parsed, the parsed duration needs normalization in two steps: First converting the whole duration to clock-unit-based duration (handling days as 24 hours long) and then normalizing to milliseconds only. After the second step, we know that the partial amount in milliseconds is also the total one (the wished result).

Meno Hochschild
  • 42,708
  • 7
  • 104
  • 126
  • what if the input doesn't contain date or hour and only show minute and second field? Do, I have to change the pattern accordingly ? or will work with the same pattern? – Rabbi Hossain Jan 22 '17 at 07:58
  • @RabbiHossain I have already seen this problem before and therefore edited the pattern inside my suggested solution. And the new normalizing method will come in next [Time4A-release](https://github.com/MenoData/Time4J/commit/454839f9de102ee74a447e465db707e776e2ea83). Potentially missing parts can be enclosed in square brackets (optional parts). – Meno Hochschild Jan 22 '17 at 08:03
  • @RabbiHossain Just to make it clear. If you use optional syntax indicated by square brackets in pattern then you will be able to use the same pattern for every input type. – Meno Hochschild Jan 22 '17 at 08:40
  • I didn't understood optional syntax part. Any example? It would be good If your library contains a documentation. – Rabbi Hossain Jan 22 '17 at 10:07
  • @RabbiHossain No documentation? I have even given a link to the pattern description - see my post (it is the second link). But you are free and welcome to contribute or suggest any improvements. – Meno Hochschild Jan 22 '17 at 13:58