1 #pragma once 2 3 #include <chrono> 4 #include <string> 5 6 namespace redfish 7 { 8 9 namespace time_utils 10 { 11 12 namespace details 13 { 14 15 inline void leftZeroPadding(std::string& str, const std::size_t padding) 16 { 17 if (str.size() < padding) 18 { 19 str.insert(0, padding - str.size(), '0'); 20 } 21 } 22 } // namespace details 23 24 /** 25 * @brief Convert time value into duration format that is based on ISO 8601. 26 * Example output: "P12DT1M5.5S" 27 * Ref: Redfish Specification, Section 9.4.4. Duration values 28 */ 29 std::string toDurationString(std::chrono::milliseconds ms) 30 { 31 if (ms < std::chrono::milliseconds::zero()) 32 { 33 return ""; 34 } 35 36 std::string fmt; 37 fmt.reserve(sizeof("PxxxxxxxxxxxxDTxxHxxMxx.xxxxxxS")); 38 39 using Days = std::chrono::duration<long, std::ratio<24 * 60 * 60>>; 40 Days days = std::chrono::floor<Days>(ms); 41 ms -= days; 42 43 std::chrono::hours hours = std::chrono::floor<std::chrono::hours>(ms); 44 ms -= hours; 45 46 std::chrono::minutes minutes = std::chrono::floor<std::chrono::minutes>(ms); 47 ms -= minutes; 48 49 std::chrono::seconds seconds = std::chrono::floor<std::chrono::seconds>(ms); 50 ms -= seconds; 51 52 fmt = "P"; 53 if (days.count() > 0) 54 { 55 fmt += std::to_string(days.count()) + "D"; 56 } 57 fmt += "T"; 58 if (hours.count() > 0) 59 { 60 fmt += std::to_string(hours.count()) + "H"; 61 } 62 if (minutes.count() > 0) 63 { 64 fmt += std::to_string(minutes.count()) + "M"; 65 } 66 if (seconds.count() != 0 || ms.count() != 0) 67 { 68 fmt += std::to_string(seconds.count()) + "."; 69 std::string msStr = std::to_string(ms.count()); 70 details::leftZeroPadding(msStr, 3); 71 fmt += msStr + "S"; 72 } 73 74 return fmt; 75 } 76 77 } // namespace time_utils 78 } // namespace redfish 79