Skip to content

Commit

Permalink
Add start timezone
Browse files Browse the repository at this point in the history
  • Loading branch information
simonkimi committed Aug 28, 2024
1 parent 20c135d commit 756dbc6
Show file tree
Hide file tree
Showing 17 changed files with 285 additions and 1 deletion.
27 changes: 27 additions & 0 deletions include/mdf/ifilehistory.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,33 @@ class IFileHistory : public IBlock {
*/
virtual void Time(uint64_t ns_since_1970) = 0;

/** \brief Sets the local start time.
*
* Sets the absolute start time for the measurement file based on local time.
* @param timestamp_ns Nanoseconds since 1970.
*/
virtual void SetStartTimeLocal(uint64_t timestamp_ns) = 0;

/** \brief Sets the UTC start time.
*
* Sets the absolute start time for the measurement file based on Coordinated
* Universal Time (UTC).
* @param timestamp_ns Nanoseconds since 1970.
*/
virtual void SetStartTimeUtc(uint64_t timestamp_ns) = 0;

/** \brief Sets the start time with a timezone offset.
*
* Sets the absolute start time for the measurement file with specific
* timezone and daylight saving time offsets.
* @param timestamp_ns Nanoseconds since 1970.
* @param tz_offset_min Timezone offset in minutes.
* @param dst_offset_min Daylight saving time offset in minutes.
*/
virtual void SetStartTimeWithZone(uint64_t timestamp_ns,
int16_t tz_offset_min,
int16_t dst_offset_min) = 0;

/** \brief Returns the time for the history block.
*
* Sets the time the history block was created.
Expand Down
27 changes: 27 additions & 0 deletions include/mdf/iheader.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,33 @@ class IHeader : public IBlock {
*/
virtual void StartTime(uint64_t ns_since_1970) = 0;

/** \brief Sets the local start time.
*
* Sets the absolute start time for the measurement file based on local time.
* @param timestamp_ns Nanoseconds since 1970.
*/
virtual void SetStartTimeLocal(uint64_t timestamp_ns) = 0;

/** \brief Sets the UTC start time.
*
* Sets the absolute start time for the measurement file based on Coordinated
* Universal Time (UTC).
* @param timestamp_ns Nanoseconds since 1970.
*/
virtual void SetStartTimeUtc(uint64_t timestamp_ns) = 0;

/** \brief Sets the start time with a timezone offset.
*
* Sets the absolute start time for the measurement file with specific
* timezone and daylight saving time offsets.
* @param timestamp_ns Nanoseconds since 1970.
* @param tz_offset_min Timezone offset in minutes.
* @param dst_offset_min Daylight saving time offset in minutes.
*/
virtual void SetStartTimeWithZone(uint64_t timestamp_ns,
int16_t tz_offset_min,
int16_t dst_offset_min) = 0;

/** \brief Returns the absolute measurement time for the file.
*
* Returns the absolute start time for the measurement file.
Expand Down
52 changes: 52 additions & 0 deletions include/mdf/mdfhelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,58 @@ class MdfHelper {
* @return Local date format 'HH:MM:SS'
*/
static std::string NanoSecToHHMMSS(uint64_t ns_since_1970);

/** \brief Converts ns since 1970 UTC to UTC time in 'HH:MM:SS' format.
*
* Generates a UTC time string in the 'HH:MM:SS' format from a timestamp
* representing nanoseconds since 1970-01-01 (midnight) UTC. This is useful for
* converting a high-precision timestamp to a human-readable time format in UTC.
*
* @param [in] timestamp_ns Nanoseconds since 1970 UTC.
* @return UTC time format 'HH:MM:SS'.
*/
static std::string NanoTimestampToHHMMSS(uint64_t timestamp_ns);

/** \brief Converts ns since 1970 UTC to UTC date in 'DD/MM/YYYY' format.
*
* Generates a UTC date string in the 'DD/MM/YYYY' format from a timestamp
* representing nanoseconds since 1970-01-01 (midnight) UTC. This function is
* useful for converting a high-precision timestamp into a human-readable date in UTC.
*
* @param [in] timestamp_ns Nanoseconds since 1970 UTC.
* @return UTC date format 'DD/MM/YYYY'.
*/
static std::string NanoTimestampToDDMMYYYY(uint64_t timestamp_ns);

/** \brief Converts ns since 1970 UTC to a time string in 'HH:MM:SS' format in a specified timezone.
*
* Generates a time string in the 'HH:MM:SS' format based on a timestamp
* representing nanoseconds since 1970-01-01 (midnight) UTC, adjusted for a
* specified timezone and daylight saving time (DST) offset. This function
* is useful for converting a high-precision timestamp into a human-readable
* time in a specific timezone.
*
* @param [in] timestamp_ns Nanoseconds since 1970 UTC.
* @param [in] tz_offset_min Timezone offset in minutes from UTC.
* @param [in] dst_offset_min Daylight saving time (DST) offset in minutes.
* @return Time format 'HH:MM:SS' adjusted for the specified timezone and DST offset.
*/
static std::string NanoTimestampToTimezoneHHMMSS(uint64_t timestamp_ns, int16_t tz_offset_min, int16_t dst_offset_min);

/** \brief Converts ns since 1970 UTC to a date string in 'DD/MM/YYYY' format in a specified timezone.
*
* Generates a date string in the 'DD/MM/YYYY' format based on a timestamp
* representing nanoseconds since 1970-01-01 (midnight) UTC, adjusted for a
* specified timezone and daylight saving time (DST) offset. This function
* is useful for converting a high-precision timestamp into a human-readable
* date in a specific timezone.
*
* @param [in] timestamp_ns Nanoseconds since 1970 UTC.
* @param [in] tz_offset_min Timezone offset in minutes from UTC.
* @param [in] dst_offset_min Daylight saving time (DST) offset in minutes.
* @return Date format 'DD/MM/YYYY' adjusted for the specified timezone and DST offset.
*/
static std::string NanoTimestampToTimezoneDDMMYYYY(uint64_t timestamp_ns, int16_t tz_offset_min, int16_t dst_offset_min);

/** \brief Remove white space from string.
*
Expand Down
14 changes: 14 additions & 0 deletions mdflib/src/fh4block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,18 @@ void Fh4Block::Time(uint64_t ns_since_1970) {

uint64_t Fh4Block::Time() const { return timestamp_.NsSince1970(); }

void Fh4Block::SetStartTimeLocal(uint64_t timestamp_ns) {
timestamp_.LocalTime(timestamp_ns);
}

void Fh4Block::SetStartTimeUtc(uint64_t timestamp_ns) {
timestamp_.NsSince1970(timestamp_ns);
}

void Fh4Block::SetStartTimeWithZone(uint64_t timestamp_ns,
int16_t tz_offset_min,
int16_t dst_offset_min) {
timestamp_.TimestampWithZone(timestamp_ns, tz_offset_min, dst_offset_min);
}

} // namespace mdf::detail
4 changes: 4 additions & 0 deletions mdflib/src/fh4block.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ class Fh4Block : public MdfBlock, public IFileHistory {
return MdfBlock::BlockType();
}
void Time(uint64_t ns_since_1970) override;
void SetStartTimeLocal(uint64_t timestamp_ns) override;
void SetStartTimeUtc(uint64_t timestamp_ns) override;
void SetStartTimeWithZone(uint64_t timestamp_ns, int16_t tz_offset_min,
int16_t dst_offset_min) override;
[[nodiscard]] uint64_t Time() const override;

void GetBlockProperty(BlockPropertyList& dest) const override;
Expand Down
25 changes: 25 additions & 0 deletions mdflib/src/hd3block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,31 @@ uint64_t Hd3Block::StartTime() const {
return local_timestamp_ - (MdfHelper::TimeZoneOffset() * 1'000'000'000LL);
}

void Hd3Block::SetStartTimeLocal(uint64_t ns_since_1970) {
StartTime(ns_since_1970);
}

void Hd3Block::SetStartTimeUtc(uint64_t timestamp_ns) {
date_ = MdfHelper::NanoTimestampToDDMMYYYY(timestamp_ns);
time_ = MdfHelper::NanoTimestampToHHMMSS(timestamp_ns);
local_timestamp_ = MdfHelper::NanoSecToLocal(timestamp_ns);
dst_offset_ = 0;
time_quality_ = 0;
timer_id_ = "Local PC Reference Time";
}
void Hd3Block::SetStartTimeWithZone(uint64_t timestamp_ns,
int16_t tz_offset_min,
int16_t dst_offset_min) {
date_ = MdfHelper::NanoTimestampToTimezoneDDMMYYYY(
timestamp_ns, tz_offset_min, dst_offset_min);
time_ = MdfHelper::NanoTimestampToTimezoneHHMMSS(timestamp_ns, tz_offset_min,
dst_offset_min);
local_timestamp_ = MdfHelper::NanoSecToLocal(timestamp_ns);
dst_offset_ = static_cast<int16_t>(tz_offset_min / 60);
time_quality_ = 0;
timer_id_ = "Local PC Reference Time";
}

IDataGroup *Hd3Block::CreateDataGroup() {
auto dg3 = std::make_unique<Dg3Block>();
dg3->Init(*this);
Expand Down
5 changes: 5 additions & 0 deletions mdflib/src/hd3block.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ class Hd3Block : public MdfBlock, public IHeader {
[[nodiscard]] std::string Description() const override;

void StartTime(uint64_t ns_since_1970) override;
void SetStartTimeLocal(uint64_t timestamp_ns) override;
void SetStartTimeUtc(uint64_t timestamp_ns) override;
void SetStartTimeWithZone(uint64_t timestamp_ns, int16_t tz_offset_min,
int16_t dst_offset_min) override;

[[nodiscard]] uint64_t StartTime() const override;

[[nodiscard]] IDataGroup *CreateDataGroup() override;
Expand Down
14 changes: 14 additions & 0 deletions mdflib/src/hd4block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,20 @@ void Hd4Block::StartTime(uint64_t ns_since_1970) {
timestamp_.NsSince1970(ns_since_1970);
}

void Hd4Block::SetStartTimeLocal(uint64_t timestamp_ns) {
timestamp_.LocalTime(timestamp_ns);
}

void Hd4Block::SetStartTimeUtc(uint64_t timestamp_ns) {
StartTime(timestamp_ns);
}

void Hd4Block::SetStartTimeWithZone(uint64_t timestamp_ns,
int16_t tz_offset_min,
int16_t dst_offset_min) {
timestamp_.TimestampWithZone(timestamp_ns, tz_offset_min, dst_offset_min);
}

uint64_t Hd4Block::StartTime() const { return timestamp_.NsSince1970(); }

IMetaData* Hd4Block::CreateMetaData() {
Expand Down
8 changes: 8 additions & 0 deletions mdflib/src/hd4block.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,14 @@ class Hd4Block : public MdfBlock, public IHeader {
[[nodiscard]] int64_t RecorderIndex() const override;

void StartTime(uint64_t ns_since_1970) override;

void SetStartTimeLocal(uint64_t timestamp_ns) override;

void SetStartTimeUtc(uint64_t timestamp_ns) override;

void SetStartTimeWithZone(uint64_t timestamp_ns, int16_t tz_offset_min,
int16_t dst_offset_min) override;

[[nodiscard]] uint64_t StartTime() const override;

[[nodiscard]] IMetaData *CreateMetaData() override;
Expand Down
16 changes: 16 additions & 0 deletions mdflib/src/mdf4timestamp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,20 @@ void Mdf4Timestamp::NsSince1970(uint64_t utc) {
dst_offset_ = 0;
flags_ = 0;
}

void Mdf4Timestamp::TimestampWithZone(uint64_t utc, int16_t tz_offset_min,
int16_t dst_offset_min) {
time_ = utc;
tz_offset_ = tz_offset_min;
dst_offset_ = dst_offset_min;
flags_ = 2;
}

void Mdf4Timestamp::LocalTime(uint64_t utc) {
time_ = utc;
tz_offset_ = 0;
dst_offset_ = 0;
flags_ = 1;
}

} // namespace mdf::detail
5 changes: 5 additions & 0 deletions mdflib/src/mdf4timestamp.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ class Mdf4Timestamp : public MdfBlock {
[[nodiscard]] uint64_t NsSince1970() const;
void NsSince1970(uint64_t utc);

void TimestampWithZone(uint64_t utc, int16_t tz_offset_min,
int16_t dst_offset_min);

void LocalTime(uint64_t utc);

private:
uint64_t time_ = MdfHelper::NowNs(); ///< Time in nanoseconds since 1970 also
///< known as UNIX time
Expand Down
3 changes: 2 additions & 1 deletion mdflib/src/mdfblock.h
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,8 @@ std::size_t MdfBlock::WriteNumber(std::FILE *file, const T &source) const {
}
} else {
const LittleBuffer buff(source);
auto count = std::fwrite(buff.data(), 1, sizeof(T), file);
auto buf = buff.data();
auto count = std::fwrite(buf, 1, sizeof(T), file);
if (count != sizeof(T)) {
throw std::runtime_error("Invalid number of bytes written");
}
Expand Down
37 changes: 37 additions & 0 deletions mdflib/src/mdfhelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,43 @@ std::string MdfHelper::NanoSecToHHMMSS(uint64_t ns_since_1970) {
return s.str();
}

std::string MdfHelper::NanoTimestampToHHMMSS(uint64_t timestamp_ns) {
auto utc_time = static_cast<time_t>(timestamp_ns / 1'000'000'000ULL);
struct tm *bt = gmtime(&utc_time);
std::ostringstream text;
text << std::put_time(bt, "%H:%M:%S");
return text.str();
}
std::string MdfHelper::NanoTimestampToDDMMYYYY(uint64_t timestamp_ns) {
auto utc_time = static_cast<time_t>(timestamp_ns / 1'000'000'000ULL);
struct tm *bt = gmtime(&utc_time);
std::ostringstream text;
text << std::put_time(bt, "%d:%m:%Y");
return text.str();
}
std::string MdfHelper::NanoTimestampToTimezoneHHMMSS(uint64_t timestamp_ns,
int16_t tz_offset_min,
int16_t dst_offset_min) {
auto target_time = static_cast<time_t>(timestamp_ns / 1'000'000'000ULL);
int offset = (tz_offset_min + dst_offset_min) * 60;
target_time += offset;
struct tm *bt = gmtime(&target_time);
std::ostringstream text;
text << std::put_time(bt, "%H:%M:%S");
return text.str();
}
std::string MdfHelper::NanoTimestampToTimezoneDDMMYYYY(uint64_t timestamp_ns,
int16_t tz_offset_min,
int16_t dst_offset_min) {
auto target_time = static_cast<time_t>(timestamp_ns / 1'000'000'000ULL);
int offset = (tz_offset_min + dst_offset_min) * 60;
target_time += offset;
struct tm *bt = gmtime(&target_time);
std::ostringstream text;
text << std::put_time(bt, "%d:%m:%Y");
return text.str();
}

void MdfHelper::Trim(std::string &text) {
LTrim(text);
RTrim(text);
Expand Down
19 changes: 19 additions & 0 deletions mdflibrary/src/MdfFileHistory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,25 @@ void MdfFileHistory::UserName::set(String^ user) {
}
}

void MdfFileHistory::SetStartTimeLocal(const uint64_t time) {
if (history_ != nullptr) {
history_->SetStartTimeLocal(time);
}
}

void MdfFileHistory::SetStartTimeWithZone(const uint64_t time, const int16_t tz_offset_min,
const int16_t dst_offset_min) {
if (history_ != nullptr) {
history_->SetStartTimeWithZone(time, tz_offset_min, dst_offset_min);
}
}

void MdfFileHistory::SetStartTimeUtc(const uint64_t time) {
if (history_ != nullptr) {
history_->SetStartTimeUtc(time);
}
}

MdfFileHistory::MdfFileHistory(mdf::IFileHistory* history)
: history_(history) {
}
Expand Down
6 changes: 6 additions & 0 deletions mdflibrary/src/MdfFileHistory.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ public ref class MdfFileHistory {
property String^ ToolVendor { String^ get(); void set(String^ vendor); }
property String^ ToolVersion { String^ get(); void set(String^ version); }
property String^ UserName { String^ get(); void set(String^ user); }

void SetStartTimeLocal(uint64_t time);
void SetStartTimeWithZone(uint64_t time, int16_t tz_offset_min,
int16_t dst_offset_min);
void SetStartTimeUtc(uint64_t time);

private:
MdfFileHistory() {}
internal:
Expand Down
20 changes: 20 additions & 0 deletions mdflibrary/src/MdfHeader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,26 @@ MdfDataGroup^ MdfHeader::CreateDataGroup() {
return gcnew MdfDataGroup(temp);
}

void MdfHeader::SetStartTimeLocal(const uint64_t time) {
if (header_ != nullptr) {
header_->SetStartTimeLocal(time);
}
}

void MdfHeader::SetStartTimeWithZone(const uint64_t time,
const int16_t tz_offset_min,
const int16_t dst_offset_min) {
if (header_ != nullptr) {
header_->SetStartTimeWithZone(time, tz_offset_min, dst_offset_min);
}
}

void MdfHeader::SetStartTimeUtc(const uint64_t time) {
if (header_ != nullptr) {
header_->SetStartTimeUtc(time);
}
}

bool MdfHeader::IsStartAngleUsed::get() {
return header_ != nullptr ? header_->StartAngle().has_value() : false;
}
Expand Down
Loading

0 comments on commit 756dbc6

Please sign in to comment.