All checks were successful
Build Packages / build:rpm (rocky8_nocuda) (push) Successful in 7m47s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Successful in 7m20s
Build Packages / build:rpm (rocky9_nocuda) (push) Successful in 8m13s
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Successful in 7m10s
Build Packages / build:rpm (rocky8_sls9) (push) Successful in 7m53s
Build Packages / build:rpm (rocky8) (push) Successful in 7m57s
Build Packages / Generate python client (push) Successful in 13s
Build Packages / build:rpm (ubuntu2204) (push) Successful in 7m39s
Build Packages / Create release (push) Has been skipped
Build Packages / Build documentation (push) Successful in 36s
Build Packages / build:rpm (rocky9) (push) Successful in 9m0s
Build Packages / build:rpm (ubuntu2404) (push) Successful in 6m55s
Build Packages / Unit tests (push) Successful in 1h10m44s
This is an UNSTABLE release. * Fixes in CI pipeline * jfjoch_broker: Remove PNG preview, no dependency on libpng * jfjoch_writer: Fix UTC timestamp being generated wrong (mix between milli- and microseconds) * jfjoch_viewer: Show data collection time in dataset tooltip * jfjoch_viewer: Allow to choose the calibrant (presets for LaB6 and silver behenate) * jfjoch_viewer: Auto foreground value * Use external libjpeg-turbo and libtiff: simpler build stack, these are built and linked statically in automated Docker builds * Remove OpenBLAS dependency Reviewed-on: #1 Co-authored-by: Filip Leonarski <filip.leonarski@psi.ch> Co-committed-by: Filip Leonarski <filip.leonarski@psi.ch>
93 lines
3.0 KiB
C++
93 lines
3.0 KiB
C++
// SPDX-FileCopyrightText: 2024 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
|
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
|
|
#ifndef JUNGFRAUJOCH_TIME_UTC_H
|
|
#define JUNGFRAUJOCH_TIME_UTC_H
|
|
|
|
#include <string>
|
|
#include <chrono>
|
|
#include <regex>
|
|
#include <iomanip>
|
|
|
|
inline std::string time_UTC(const std::chrono::time_point<std::chrono::system_clock> &input) {
|
|
auto time_ms = std::chrono::duration_cast<std::chrono::milliseconds>(input.time_since_epoch()).count();
|
|
|
|
char buf1[255], buf2[255];
|
|
time_t time = time_ms / (1000);
|
|
strftime(buf1, sizeof(buf1), "%FT%T", gmtime(&time));
|
|
snprintf(buf2, sizeof(buf2), ".%03ld", time_ms%1000);
|
|
return std::string(buf1) + std::string(buf2) + "Z";
|
|
}
|
|
|
|
inline uint64_t parse_UTC_to_ms(const std::string& utc_string) {
|
|
static const std::regex re(
|
|
R"(^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,6}))?Z$)",
|
|
std::regex::ECMAScript);
|
|
|
|
std::smatch match;
|
|
if (!std::regex_match(utc_string, match, re)) {
|
|
throw std::runtime_error("Invalid UTC timestamp format: " + utc_string);
|
|
}
|
|
|
|
std::tm tm = {};
|
|
tm.tm_year = std::stoi(match[1]) - 1900;
|
|
tm.tm_mon = std::stoi(match[2]) - 1;
|
|
tm.tm_mday = std::stoi(match[3]);
|
|
tm.tm_hour = std::stoi(match[4]);
|
|
tm.tm_min = std::stoi(match[5]);
|
|
tm.tm_sec = std::stoi(match[6]);
|
|
|
|
// fractional seconds → milliseconds (pad or truncate)
|
|
int milliseconds = 0;
|
|
if (match[7].matched) {
|
|
std::string frac = match[7].str();
|
|
|
|
// Normalize fractional seconds to milliseconds
|
|
if (frac.size() > 3) {
|
|
// Truncate beyond milliseconds
|
|
frac = frac.substr(0, 3);
|
|
} else if (frac.size() < 3) {
|
|
// Pad with zeros if less than 3 digits
|
|
while (frac.size() < 3) frac.push_back('0');
|
|
}
|
|
|
|
milliseconds = std::stoi(frac);
|
|
}
|
|
|
|
time_t t = timegm(&tm);
|
|
return static_cast<uint64_t>(t) * 1000ULL + milliseconds;
|
|
}
|
|
|
|
|
|
// -- new function that reuses parse_UTC_to_ms() --
|
|
inline std::string utc_to_local_human_readable(const std::string& utc_string) {
|
|
using namespace std::chrono;
|
|
|
|
try {
|
|
uint64_t ms_since_epoch = parse_UTC_to_ms(utc_string);
|
|
auto tp = system_clock::time_point(milliseconds(ms_since_epoch));
|
|
time_t t = system_clock::to_time_t(tp);
|
|
|
|
// Convert to local time
|
|
std::tm tm_local = *std::localtime(&t);
|
|
|
|
static const char* months[] = {
|
|
"January", "February", "March", "April", "May", "June",
|
|
"July", "August", "September", "October", "November", "December"
|
|
};
|
|
|
|
std::ostringstream out;
|
|
out << months[tm_local.tm_mon] << " "
|
|
<< std::setw(2) << std::setfill('0') << tm_local.tm_mday << ", "
|
|
<< (tm_local.tm_year + 1900) << " "
|
|
<< std::setw(2) << std::setfill('0') << tm_local.tm_hour << ":"
|
|
<< std::setw(2) << std::setfill('0') << tm_local.tm_min;
|
|
|
|
return out.str();
|
|
} catch (...) {
|
|
return "";
|
|
}
|
|
}
|
|
|
|
#endif //JUNGFRAUJOCH_TIME_UTC_H
|