Files
Jungfraujoch/common/time_utc.h
T
leonarski_f 75e401f0e5
Build Packages / Unit tests (push) Successful in 1h31m59s
Build Packages / build:rpm (rocky8_nocuda) (push) Successful in 8m43s
Build Packages / build:rpm (rocky9_nocuda) (push) Successful in 10m5s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Successful in 9m27s
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Successful in 8m56s
Build Packages / build:rpm (rocky8_sls9) (push) Successful in 9m24s
Build Packages / build:rpm (rocky9_sls9) (push) Successful in 10m27s
Build Packages / build:rpm (rocky8) (push) Successful in 9m20s
Build Packages / build:rpm (rocky9) (push) Successful in 10m50s
Build Packages / build:rpm (ubuntu2204) (push) Successful in 9m54s
Build Packages / build:rpm (ubuntu2404) (push) Successful in 8m38s
Build Packages / DIALS test (push) Successful in 12m13s
Build Packages / XDS test (durin plugin) (push) Successful in 7m8s
Build Packages / XDS test (JFJoch plugin) (push) Successful in 7m8s
Build Packages / XDS test (neggia plugin) (push) Successful in 7m50s
Build Packages / Generate python client (push) Successful in 16s
Build Packages / Build documentation (push) Successful in 50s
Build Packages / Create release (push) Skipped
v1.0.0-rc.153 (#63)
This is an UNSTABLE release. It includes many experimental features, as well as many AI generated fixes. We recommend using rc.152 for production use.

* jfjoch_broker: Add EXPERIMENTAL pixelrefine mode for image processing
* jfjoch_broker: Allow to load user mask from 8-bit and 16-bit TIFF files
* jfjoch_broker: Add ROI calculation in non-FPGA workflow
* jfjoch_broker: Fixes to TCP image pusher
* jfjoch_broker: Remove NUMA bindings
* jfjoch_broker: Improvements to indexing
* jfjoch_broker: For PSI EIGER, trimming energies are taken from the detector configuration (now compulsory) instead of hardcoded values
* jfjoch_writer: Save ROI definitions and the per-pixel ROI bitmap in the master file; azimuthal ROIs support phi (angular) sectors
* jfjoch_viewer: Major redesign with dockable panels and saved layouts, plus on-canvas creation/move/resize of box, circle and azimuthal ROIs
* jfjoch_viewer: Run jfjoch_process reprocessing jobs from inside the GUI and overlay per-run results

Reviewed-on: #63
2026-06-23 20:29:49 +02:00

106 lines
3.1 KiB
C++

// SPDX-FileCopyrightText: 2024 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
// SPDX-License-Identifier: GPL-3.0-only
#pragma once
#include <string>
#include <chrono>
#include <regex>
#include <iomanip>
#include <sstream>
#include <stdexcept>
#include <ctime>
#include <cstdio>
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);
std::tm tm_utc{};
#ifdef _WIN32
if (gmtime_s(&tm_utc, &time) != 0)
#else
if (gmtime_r(&time, &tm_utc) == nullptr)
#endif
throw std::runtime_error("gmtime failed");
strftime(buf1, sizeof(buf1), "%FT%T", &tm_utc);
snprintf(buf2, sizeof(buf2), ".%03d", static_cast<int>(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]);
int milliseconds = 0;
if (match[7].matched) {
std::string frac = match[7].str();
if (frac.size() > 3) {
frac = frac.substr(0, 3);
} else if (frac.size() < 3) {
while (frac.size() < 3) frac.push_back('0');
}
milliseconds = std::stoi(frac);
}
#ifdef _WIN32
time_t t = _mkgmtime(&tm);
#else
time_t t = timegm(&tm);
#endif
return static_cast<uint64_t>(t) * 1000ULL + milliseconds;
}
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);
std::tm tm_local{};
#ifdef _WIN32
if (localtime_s(&tm_local, &t) != 0)
#else
if (localtime_r(&t, &tm_local) == nullptr)
#endif
return "";
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 "";
}
}