How to format std::chrono durations?

前端 未结 4 1801
名媛妹妹
名媛妹妹 2021-01-11 12:49

Is there a convenient way to format std::chrono::duration to a specified format?

std::chrono::high_resolution_clock::time_point now, then;
then          


        
4条回答
  •  感动是毒
    2021-01-11 13:23

    This takes an arbitrary chrono duration and breaks it down into other duration quantities:

    template
    std::tuple break_down_durations( DurationIn d ) {
      std::tuple retval;
      using discard=int[];
      (void)discard{0,(void((
        (std::get(retval) = std::chrono::duration_cast(d)),
        (d -= std::chrono::duration_cast(std::get(retval)))
      )),0)...};
      return retval;
    }
    

    Test code:

    int main() {
      auto then = std::chrono::high_resolution_clock::now();
      std::this_thread::sleep_for( std::chrono::seconds(3) );
      auto now = std::chrono::high_resolution_clock::now();
      auto duration = now - then;
    
      auto clean_duration = break_down_durations( duration );
      std::cout << std::get<0>(clean_duration).count() << "::" << std::get<1>(clean_duration).count() << "::" << std::get<2>(clean_duration).count() << "\n";
    }
    

    The formatting code can be cleaned up and put into a function.

    Live example.

    It would be amusing to write an auto-formatters for such a tuple of (increasing precision) durations.

    You'd write the outermost duration, then ::. After that, you'd convert one unit of the previous duration to the next, take its log based 10, and do a setw, and output the next duration. Repeat until you run out of durations.

    I'd probably round-trip this through arrays of std::size_t for both .count() and for the ratios.

    Like this:

    template
    std::string format_durations( std::tuple d ) {
      std::size_t values[]={(std::size_t)std::get(d).count()...};
      auto ratios = get_ratios();
    
      std::stringstream ss << std::setfill('0');
      ss << values[0];
    
      for (std::size_t const& v:values) {
        std::size_t i = &v-values;
        if (i==0) continue;
        ss << "::" << std::setw( log_10_round_up(ratios[i-1]) ) << values[i];
      }
      return ss.str();
    }
    

    with log_10_round_up and get_ratios to be written.

    That lets you take a duration, and format it as hh:mm:ss or whatever else you want.

提交回复
热议问题