org.linkedin.util-core/src/main/java/org/linkedin/util/clock/Timespan.java
public static Timespan parseTimespan(String timespan)
  {
    if(timespan == null)
      return null;

    int len = timespan.length();
    if(len == 0)
      return ZERO_MILLISECONDS;

    int count = 0;
    int timeUnitOrderIdx = 0;
    int timeUnitOrderLen = TIME_UNIT_ORDER.length;
    Timespan[] timespans = new Timespan[timeUnitOrderLen];

    int startDigitsIdx = 0;
    boolean expectingDigits = true;

    for(int i = 0; i < len; i++)
    {
      char c = timespan.charAt(i);
      if(c >= '0' && c <= '9')
      {
        expectingDigits = false;
        continue;
      }

      if(expectingDigits)
        throw new IllegalArgumentException("found " + c + " was expecting a digit");

      for(; timeUnitOrderIdx < timeUnitOrderLen; timeUnitOrderIdx++)
      {
        TimeUnit timeUnit = TIME_UNIT_ORDER[timeUnitOrderIdx];
        String displayChar = timeUnit.getDisplayChar();
        if(displayChar.length() == 0)
          throw new IllegalArgumentException("found nothing was expecting: " + c);
        if(c == displayChar.charAt(0))
        {
          try
          {
            long duration = Long.parseLong(timespan.substring(startDigitsIdx, i));
            timespans[timeUnitOrderIdx++] = new Timespan(duration, timeUnit);
            startDigitsIdx = i + 1;
            expectingDigits = true;
            count++;
            break;
          }
          catch(NumberFormatException e)
          {
            throw new IllegalArgumentException(e);
          }
        }
      }
    }

    if(startDigitsIdx < len)
    {
      try
      {
        long duration = Long.parseLong(timespan.substring(startDigitsIdx, len));
        timespans[timeUnitOrderLen - 1] = new Timespan(duration, TimeUnit.MILLISECOND);
        count++;
      }
      catch(NumberFormatException e)
      {
        throw new IllegalArgumentException(e);
      }
    }

    Timespan[] ts = new Timespan[count];
    for(int i = 0, idx = 0; i < timespans.length; i++)
    {
      Timespan t = timespans[i];
      if(t != null)
        ts[idx++] = t;
    }
    return create(ts);
  }
public static Timespan parseTimespan(String timespan)
  {
    if(timespan == null)
      return null;

    int len = timespan.length();
    if(len == 0)
      return ZERO_MILLISECONDS;

    int count = 0;
    int timeUnitOrderIdx = 0;
    int timeUnitOrderLen = TIME_UNIT_ORDER.length;
    Timespan[] timespans = new Timespan[timeUnitOrderLen];

    int startDigitsIdx = 0;
    boolean expectingDigits = true;

    for(int i = 0; i < len; i++)
    {
      char c = timespan.charAt(i);
      if(c >= '0' && c <= '9')
      {
        expectingDigits = false;
        continue;
      }

      if(expectingDigits)
        throw new IllegalArgumentException("found " + c + " was expecting a digit");

      for(; timeUnitOrderIdx < timeUnitOrderLen; timeUnitOrderIdx++)
      {
        TimeUnit timeUnit = TIME_UNIT_ORDER[timeUnitOrderIdx];
        String displayChar = timeUnit.getDisplayChar();
        if(displayChar.length() == 0)
          throw new IllegalArgumentException("found nothing was expecting: " + c);
        if(c == displayChar.charAt(0))
        {
          try
          {
            long duration = Long.parseLong(timespan.substring(startDigitsIdx, i));
            timespans[timeUnitOrderIdx++] = new Timespan(duration, timeUnit);
            startDigitsIdx = i + 1;
            expectingDigits = true;
            count++;
            break;
          }
          catch(NumberFormatException e)
          {
            throw new IllegalArgumentException(e);
          }
        }
      }
    }

    if(startDigitsIdx < len)
    {
      try
      {
        long duration = Long.parseLong(timespan.substring(startDigitsIdx, len));
        timespans[timeUnitOrderLen - 1] = new Timespan(duration, TimeUnit.MILLISECOND);
        count++;
      }
      catch(NumberFormatException e)
      {
        throw new IllegalArgumentException(e);
      }
    }

    Timespan[] ts = new Timespan[count];
    for(int i = 0, idx = 0; i < timespans.length; i++)
    {
      Timespan t = timespans[i];
      if(t != null)
        ts[idx++] = t;
    }
    return create(ts);
  }
Parses the provided string as a timespan. It should follow the pattern returned by
{@link #getCanonicalString()}. Example: 10m30s

@param timespan
@return the timespan to parse
@throws IllegalArgumentException if the string is not valid