在C中将毫秒转换为小时:分钟:秒:毫秒

新手上路,请多包涵

我正在寻找一种使用 C++ 以这种格式打印出毫秒的方法:

 cout << hours << " Hours : " << minutes << " Minutes : " << seconds << " Seconds : " << milliseconds << " Milliseconds" << endl;

我知道有很多关于这个的重复问题。但是他们都没有真正处理如何以毫秒为单位获得余数。有一些使用 Java 执行此操作,但我想要 C++ 中的解决方案。

编辑:

我想澄清这个问题。我正在寻找一个时间值,该时间值是程序运行所需的时间,并以用户易读的格式打印出该时间。获得标准的 hr:min:sec 是直截了当的。但包括任何剩余的毫秒都让我绊倒了。

原文由 Berkyjay 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.1k
2 个回答

也许你正在寻找这样的东西:

 #include <iostream>
using namespace std;

int main() {
//Value chosen to be 1 hour, 1 minute, 1 second, and 1 millisecond
long milli = 3661001;
//3600000 milliseconds in an hour
long hr = milli / 3600000;
milli = milli - 3600000 * hr;
//60000 milliseconds in a minute
long min = milli / 60000;
milli = milli - 60000 * min;

//1000 milliseconds in a second
long sec = milli / 1000;
milli = milli - 1000 * sec;

cout << hr << " hours and " << min << " minutes and " << sec << " seconds and " << milli << " milliseconds." << endl;
}

原文由 Jsqsh 发布,翻译遵循 CC BY-SA 4.0 许可协议

std::string format_duration( std::chrono::milliseconds ms ) {
    using namespace std::chrono;
    auto secs = duration_cast<seconds>(ms);
    ms -= duration_cast<milliseconds>(secs);
    auto mins = duration_cast<minutes>(secs);
    secs -= duration_cast<seconds>(mins);
    auto hour = duration_cast<hours>(mins);
    mins -= duration_cast<minutes>(hour);

    std::stringstream ss;
    ss << hour.count() << " Hours : " << mins.count() << " Minutes : " << secs.count() << " Seconds : " << ms.count() << " Milliseconds";
    return ss.str();
}

活生生的例子

将此扩展到天/年/等应该很容易(但是,在 c++20 之前,天/年/等没有预定义的 std::chrono 持续时间类型)。

但我可以做得更好。

 template<class Duration>
struct split_duration {
  Duration d;
  std::chrono::milliseconds leftover;

  split_duration( std::chrono::milliseconds ms ):
    d( std::chrono::duration_cast<Duration>(ms) ),
    leftover( ms - std::chrono::duration_cast<std::chrono::milliseconds>(d) )
  {}
};

template<class...Durations>
std::tuple<Durations...> durations( std::chrono::milliseconds ms ) {
  std::tuple<std::optional<split_duration<Durations>>...> tmp;
  ( (void)(
       (void)std::get<std::optional<split_duration<Durations>>>(tmp).emplace( ms ),
       ms = std::get<std::optional<split_duration<Durations>>>(tmp)->leftover
     ), ...
  );
  return std::make_tuple( std::get<std::optional<split_duration<Durations>>>( tmp )->d... );
}

template<class T>
struct tag_t {};
template<class T>
constexpr tag_t<T> tag = {};

inline std::string duration_name( tag_t<std::chrono::milliseconds> ) { return "ms"; }
inline std::string duration_name( tag_t<std::chrono::seconds> ) { return "Seconds"; }
inline std::string duration_name( tag_t<std::chrono::minutes> ) { return "Minutes"; }
inline std::string duration_name( tag_t<std::chrono::hours> ) { return "Hours"; }
// inline std::string duration_name( tag_t<std::chrono::days> ) { return "Days"; }
// inline std::string duration_name( tag_t<std::chrono::years> ) { return "Years"; }

template<class...Durations>
std::string format_duration( std::chrono::milliseconds ms ) {
    auto split = durations<Durations...>(ms);

    std::stringstream ss;

    (
        (void)( ss << duration_name(tag<Durations>) << ": " << std::get<Durations>(split).count() << " " ), ...
    );

    return ss.str();
}

Days/Years 需要 c++20 ,其他都是 c++17

您只需调用 format_durations<Durations...>( some_ms ) 并输出基于 Durations... 的格式化字符串。你必须从最重要到最不重要的地方去做。

durations<Durations...> 为您提供时间的元组细分,该时间必须是从多到少;如果您愿意,您可以在格式化之前重新排序。

重复的持续时间类型会导致编译时错误,因为 std::get 死于可怕的模棱两可的死亡。

活生生的例子

原文由 Yakk - Adam Nevraumont 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题