mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 20:40:04 +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)
|
if (messageList.size() > 0)
|
||||||
{
|
{
|
||||||
auto& firstMessage = messageList.front();
|
auto& firstMessage = messageList.front();
|
||||||
auto firstSegment = firstMessage->segment(0);
|
return firstMessage->segment_event_begin(0);
|
||||||
return firstSegment->header_->vtecString_[0].pVtec_.event_begin();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -91,11 +91,14 @@ public:
|
||||||
std::shared_ptr<WmoHeader> wmo_header() const;
|
std::shared_ptr<WmoHeader> wmo_header() const;
|
||||||
std::vector<std::string> mnd_header() const;
|
std::vector<std::string> mnd_header() const;
|
||||||
std::vector<std::string> overview_block() 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::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;
|
bool Parse(std::istream& is) override;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
#include <scwx/awips/text_product_message.hpp>
|
#include <scwx/awips/text_product_message.hpp>
|
||||||
#include <scwx/common/characters.hpp>
|
#include <scwx/common/characters.hpp>
|
||||||
|
#include <scwx/util/logger.hpp>
|
||||||
#include <scwx/util/streams.hpp>
|
#include <scwx/util/streams.hpp>
|
||||||
|
|
||||||
#include <istream>
|
#include <istream>
|
||||||
|
|
@ -15,6 +16,7 @@ namespace awips
|
||||||
{
|
{
|
||||||
|
|
||||||
static const std::string logPrefix_ = "scwx::awips::text_product_message";
|
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:
|
// Issuance date/time takes one of the following forms:
|
||||||
// * <hhmm>_xM_<tz>_day_mon_<dd>_year
|
// * <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];
|
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
|
size_t TextProductMessage::data_size() const
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue