| 36 | } |
| 37 | |
| 38 | std::string NsToLocalTime(uint64_t ns_since_1970, int format) { |
| 39 | const auto system_time = |
| 40 | static_cast<std::time_t>(ns_since_1970 / 1'000'000'000); |
| 41 | const struct tm* bt = localtime(&system_time); |
| 42 | std::ostringstream text; |
| 43 | text << std::put_time(bt, "%X"); |
| 44 | |
| 45 | std::ostringstream extra; |
| 46 | switch (format) { |
| 47 | case 1: { // Show ms |
| 48 | const auto ms_sec = (ns_since_1970 / 1'000'000) % 1'000; |
| 49 | extra << '.' << std::setfill('0') << std::setw(3) << ms_sec; |
| 50 | break; |
| 51 | } |
| 52 | |
| 53 | case 2: { // Show us |
| 54 | const auto us_sec = (ns_since_1970 / 1'000) % 1'000'000; |
| 55 | extra << '.' << std::setfill('0') << std::setw(6) << us_sec; |
| 56 | break; |
| 57 | } |
| 58 | |
| 59 | case 3: { // Show ns |
| 60 | const auto ns_sec = (ns_since_1970) % 1'000'000'000; |
| 61 | extra << '.' << std::setfill('0') << std::setw(9) << ns_sec; |
| 62 | break; |
| 63 | } |
| 64 | |
| 65 | case 0: // Show seconds |
| 66 | default: |
| 67 | return text.str(); |
| 68 | } |
| 69 | |
| 70 | const std::string input = text.str(); |
| 71 | std::ostringstream output; |
| 72 | bool is_am_pm = false; |
| 73 | bool is_blank = false; |
| 74 | for (const char char_in : input) { |
| 75 | if (std::isalpha(char_in) && !is_am_pm) { // Assume AM PM and insert ms |
| 76 | output << extra.str(); |
| 77 | if (is_blank) { |
| 78 | output << " "; |
| 79 | is_blank = false; |
| 80 | } |
| 81 | is_am_pm = true; |
| 82 | output << char_in; |
| 83 | } else if (iswspace(char_in)) { |
| 84 | is_blank = true; |
| 85 | } else { |
| 86 | if (is_blank) { |
| 87 | output << " "; |
| 88 | is_blank = false; |
| 89 | } |
| 90 | output << char_in; |
| 91 | } |
| 92 | } |
| 93 | if (!is_am_pm) { |
| 94 | output << extra.str(); |
| 95 | } |