mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 13:10:05 +00:00
Fix text product start time when first P-VTEC uses 000000T0000Z
This commit is contained in:
parent
58a2d8982a
commit
45b0df3e0b
3 changed files with 90 additions and 5 deletions
|
|
@ -421,8 +421,7 @@ AlertModelImpl::GetStartTime(const types::TextEventKey& key)
|
|||
if (messageList.size() > 0)
|
||||
{
|
||||
auto& firstMessage = messageList.front();
|
||||
auto firstSegment = firstMessage->segment(0);
|
||||
return firstSegment->header_->vtecString_[0].pVtec_.event_begin();
|
||||
return firstMessage->segment_event_begin(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -91,11 +91,14 @@ public:
|
|||
std::shared_ptr<WmoHeader> wmo_header() const;
|
||||
std::vector<std::string> mnd_header() const;
|
||||
std::vector<std::string> overview_block() const;
|
||||
size_t segment_count() const;
|
||||
std::size_t segment_count() const;
|
||||
std::vector<std::shared_ptr<const Segment>> segments() const;
|
||||
std::shared_ptr<const Segment> segment(size_t s) const;
|
||||
std::shared_ptr<const Segment> segment(std::size_t s) const;
|
||||
|
||||
size_t data_size() const;
|
||||
std::chrono::system_clock::time_point
|
||||
segment_event_begin(std::size_t s) const;
|
||||
|
||||
std::size_t data_size() const;
|
||||
|
||||
bool Parse(std::istream& is) override;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include <scwx/awips/text_product_message.hpp>
|
||||
#include <scwx/common/characters.hpp>
|
||||
#include <scwx/util/logger.hpp>
|
||||
#include <scwx/util/streams.hpp>
|
||||
|
||||
#include <istream>
|
||||
|
|
@ -15,6 +16,7 @@ namespace awips
|
|||
{
|
||||
|
||||
static const std::string logPrefix_ = "scwx::awips::text_product_message";
|
||||
static const auto logger_ = scwx::util::Logger::Create(logPrefix_);
|
||||
|
||||
// Issuance date/time takes one of the following forms:
|
||||
// * <hhmm>_xM_<tz>_day_mon_<dd>_year
|
||||
|
|
@ -101,6 +103,87 @@ std::shared_ptr<const Segment> TextProductMessage::segment(size_t s) const
|
|||
return p->segments_[s];
|
||||
}
|
||||
|
||||
std::chrono::system_clock::time_point
|
||||
TextProductMessage::segment_event_begin(std::size_t s) const
|
||||
{
|
||||
std::chrono::system_clock::time_point eventBegin {};
|
||||
|
||||
auto& header = segment(s)->header_;
|
||||
if (header.has_value() && !header->vtecString_.empty())
|
||||
{
|
||||
// Determine event begin from P-VTEC string
|
||||
eventBegin = header->vtecString_[0].pVtec_.event_begin();
|
||||
|
||||
// If event begin is 000000T0000Z
|
||||
if (eventBegin == std::chrono::system_clock::time_point {})
|
||||
{
|
||||
using namespace std::chrono;
|
||||
|
||||
// Determine event end from P-VTEC string
|
||||
system_clock::time_point eventEnd =
|
||||
header->vtecString_[0].pVtec_.event_end();
|
||||
|
||||
auto endDays = floor<days>(eventEnd);
|
||||
year_month_day endDate {endDays};
|
||||
|
||||
// Determine WMO date/time
|
||||
std::string wmoDateTime = wmo_header()->date_time();
|
||||
|
||||
bool wmoDateTimeValid = false;
|
||||
unsigned long dayOfMonth = 0;
|
||||
unsigned long beginHour = 0;
|
||||
unsigned long beginMinute = 0;
|
||||
|
||||
try
|
||||
{
|
||||
// WMO date time is in the format DDHHMM
|
||||
dayOfMonth = std::stoul(wmoDateTime.substr(0, 2));
|
||||
beginHour = std::stoul(wmoDateTime.substr(2, 2));
|
||||
beginMinute = std::stoul(wmoDateTime.substr(4, 2));
|
||||
wmoDateTimeValid = true;
|
||||
}
|
||||
catch (const std::exception&)
|
||||
{
|
||||
logger_->warn("Malformed WMO date/time: {}", wmoDateTime);
|
||||
}
|
||||
|
||||
if (wmoDateTimeValid)
|
||||
{
|
||||
// Combine end date year and month with WMO date time
|
||||
eventBegin =
|
||||
sys_days {endDate.year() / endDate.month() / day {dayOfMonth}} +
|
||||
hours {beginHour} + minutes {beginMinute};
|
||||
|
||||
// If the begin date is after the end date, assume the start time
|
||||
// was the previous month
|
||||
if (eventBegin > eventEnd)
|
||||
{
|
||||
// If the current end month is January
|
||||
if (endDate.month() == January)
|
||||
{
|
||||
// The begin month must be December of last year
|
||||
eventBegin = sys_days {year {(endDate.year() - 1y).count()} /
|
||||
December / day {dayOfMonth}} +
|
||||
hours {beginHour} + minutes {beginMinute};
|
||||
}
|
||||
else
|
||||
{
|
||||
// Back up one month
|
||||
eventBegin =
|
||||
sys_days {endDate.year() /
|
||||
month {static_cast<unsigned int>(
|
||||
(endDate.month() - month {1}).count())} /
|
||||
day {dayOfMonth}} +
|
||||
hours {beginHour} + minutes {beginMinute};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return eventBegin;
|
||||
}
|
||||
|
||||
size_t TextProductMessage::data_size() const
|
||||
{
|
||||
return 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue