24#include <QtCore/QDate>
44namespace LinguisticProcessing {
45namespace SpecificEntities {
47#define DATESTRING_FEATURE_NAME "date_string"
48#define DATE_FEATURE_NAME "date"
49#define DATE_BEGIN_FEATURE_NAME "date_begin"
50#define DATE_END_FEATURE_NAME "date_end"
51#define DATE_SPAN_FEATURE_NAME "date_span"
52#define DAY_FEATURE_NAME "day"
53#define DAYEND_FEATURE_NAME "dayend"
54#define MONTH_FEATURE_NAME "month"
55#define MONTHEND_FEATURE_NAME "monthend"
56#define YEAR_FEATURE_NAME "year"
57#define NUMDAY_FEATURE_NAME "numday"
58#define NUMDAYEND_FEATURE_NAME "numdayend"
59#define NUMMONTH_FEATURE_NAME "nummonth"
60#define NUMMONTHEND_FEATURE_NAME "nummonthend"
61#define NUMDAYMONTH_FEATURE_NAME "numdaymonth"
62#define NUMYEAR_FEATURE_NAME "numyear"
63#define NUMYEAREND_FEATURE_NAME "numyearend"
65#define LOCALTIME_FEATURE_NAME "local_time"
66#define UTCTIME_FEATURE_NAME "utc_time"
67#define TIMESTRING_FEATURE_NAME "time_string"
85m_dateRefName(
"document"),
86m_timeRefName(
"document"),
87m_locRefName(
"document")
94 if (! complement.isEmpty()) {
98 i=complement.indexOf(
LimaChar(
','),prev);
111 if (str.indexOf(datePrefix)==0) {
114 else if (str.indexOf(locPrefix)==0) {
117 else if (str.indexOf(timePrefix)==0) {
127 auto data = analysis.
getData(
"LinguisticMetaData");
130 LERROR <<
"missing data 'LinguisticMetaData'";
133 auto metadata = std::dynamic_pointer_cast<const LinguisticMetaData>(data);
135 date=metadata->getDate(m_dateRefName);
138 LDEBUG <<
"m_dateRefName =" << m_dateRefName <<
" , date = " << date.toString();
140 if (!date.isValid()) {
143 LWARN <<
"no reference date '"<< m_dateRefName <<
"'";
145 date=metadata->getDate(
"document");
146 if (!date.isValid()) {
148 LWARN <<
"no reference date 'document'";
161 auto data = analysis.
getData(
"LinguisticMetaData");
164 LERROR <<
"missing data 'LinguisticMetaData'";
167 auto metadata = std::dynamic_pointer_cast<const LinguisticMetaData>(data);
169 time=metadata->getTime(m_timeRefName);
170 return (time.isValid());
175 std::string& location)
const
178 auto data = analysis.
getData(
"LinguisticMetaData");
181 LERROR <<
"missing data 'LinguisticMetaData'";
184 auto metadata = std::dynamic_pointer_cast<const LinguisticMetaData>(data);
186 location=metadata->getLocation(m_locRefName);
187 return (! location.empty());
231 auto micros = std::dynamic_pointer_cast<MicrosForNormalization>(res);
235 catch (std::exception& e) {
237 LWARN <<
"Exception caught: " << e.what();
238 LWARN <<
"-> micros for person name normalization are not initialized";
246 LWARN <<
"no resource 'DateTimeNormalization'";
249 m_resources = std::dynamic_pointer_cast<NormalizeDateTimeResources>(res);
252 catch (std::exception& e) {
255 LWARN <<
"Exception caught: " << e.what();
259 if (complement.indexOf(intervalString)!=-1) {
266 const QDate& currentDate)
const
269 auto data = analysis.
getData(
"LinguisticMetaData");
272 LERROR <<
"missing data 'LinguisticMetaData'";
275 auto metadata = std::dynamic_pointer_cast<LinguisticMetaData>(data);
277 metadata->setDate(
"current", currentDate);
286 unsigned short day =
m_resources->getValueFromNumberOrdinal(numdayString);
288 LDEBUG <<
"NormalizeDate::getDayFromString: testConversion 1 of " << numdayString <<
"1 day=" << day;
293 day =
m_resources->getValueFromWordCardinalOrOrdinal(numdayString);
295 LDEBUG <<
"NormalizeDate::getDayFromString: testConversion 2 of " << numdayString <<
"1 day=" << day;
301 day = numdayString.toUShort(&ok);
303 LDEBUG <<
"NormalizeDate::getDayFromString: testConversion 3 of " << numdayString <<
"1 day=" << day;
312 const std::string& featureName)
const
316 unsigned short day(0);
324 LWARN <<
"Error in date normalization: wrong value for day (" << day <<
")";
331 const std::string& featureName)
const
333 unsigned short day(0);
341 const std::string& featureName,
342 const std::string& alternative)
const
344 unsigned short month(0);
348 month = (*m.
features().
find(featureName)).getValueLimaString().toUShort(&ok);
350 else if ((alternative !=
"") &&
360 const std::string& featureName)
const
362 unsigned short year(0);
364 year = (*m.
features().
find(featureName)).getValueLimaString().toUShort();
366 if (year!=0 && year<99)
370 unsigned short currentYear=QDate::currentDate().year();
372 unsigned short century=int(
float(currentYear)/100)*100;
373 if (century+year<=currentYear+10) {
377 year=(century-100)+year;
386 QString dateSpan =
"XXXX";
388 dateSpan = QString::number(year);
389 dateSpan.append(
"-");
392 dateSpan.append(
"XX-XX");
396 QString monthString = QString(QLatin1String(
"%1")).arg(month, 2, 10, QLatin1Char(
'0'));
397 dateSpan.append(monthString);
398 dateSpan.append(
"-");
401 dateSpan.append(
"XX");
405 QString dayString = QString(QLatin1String(
"%1")).arg(day, 2, 10, QLatin1Char(
'0'));
406 dateSpan.append(dayString);
418 LDEBUG <<
"NormalizeDate::operator()"<<m;
441 QStringList l=daymonth.split(
"/");
443 month=l[1].toUShort();
445 if (month >12 && day <=12 ) {
451 unsigned short refyear(0), refmonth(0);
454 refyear=referenceDate.year();
455 refmonth=referenceDate.month();
462 if ( year_end == 0 && (day_end != 0 || month_end != 0) ) {
471 dateEnd=QDate(year_end,12,31);
473 else if (day_end==0) {
475 dateEnd=QDate(year_end,month_end,1).addMonths(1).addDays(-1);
478 dateEnd=QDate(year_end,month_end,day_end);
495 QDate firstDayOfMonth(year,month,1);
500 if (dateEnd.isValid()) {
510 QDate date=QDate(year,month,day);
515 if (dateEnd.isValid()) {
542 if (complement.indexOf(nextString)!=-1) {
550 int i=complement.indexOf(diffString);
553 uint64_t end=complement.indexOf(days,i);
560QDate
adjustDate(
unsigned short mention,
unsigned short ref,
const QDate& refDate,
bool getNext,
bool months=
false) {
564 int diff=mention - ref;
565 unsigned short modulo=7;
571 add=(modulo+diff)%modulo;
577 add=-((modulo-diff)%modulo);
583 newDate=refDate.addMonths(add);
586 newDate=refDate.addDays(add);
602 LDEBUG <<
"NormalizeRelativeDate: no resources" ;
614 unsigned short year=0;
620 QString dateSpan=
getDateSpan(year,month,dayOfMonth);
628 unsigned short refday=referenceDate.dayOfWeek();
629 unsigned short refmonth=referenceDate.month();
631 QDate newCurrentDate;
642 QDate newDate=
adjustDate(month, refmonth, referenceDate, m_getNext,
true);
645 newCurrentDate=QDate(newDate.year(),newDate.month(),dayOfMonth);
651 QDate firstDayOfMonth(newDate.year(),newDate.month(),1);
660 newCurrentDate=referenceDate.addDays(m_diff);
665 unsigned short century(0);
669 century = boost::any_cast<unsigned short>((*m.
features().
find(
"century")).getValue());
671 catch(
const boost::bad_any_cast &) {
672 century = (*m.
features().
find(
"century")).getValueLimaString().toUShort();
675 year = (century-1)*100;
678 if (newCurrentDate.isValid()) {
705 LWARN <<
"no resource 'DateTimeNormalization'";
708 m_resources = std::dynamic_pointer_cast<NormalizeDateTimeResources>(res);
711 catch (std::exception& e) {
721 LDEBUG <<
"NormalizeTime::getTimeDuration...";
725 unsigned short hou(0),min(0),sec(0);
728 hou = boost::any_cast<unsigned short>((*m.
features().
find(
"hour")).getValue());
730 catch(
const boost::bad_any_cast &) {
731 hou = (*m.
features().
find(
"hour")).getValueLimaString().toUShort();
736 min = boost::any_cast<unsigned short>((*m.
features().
find(
"minute")).getValue());
738 catch(
const boost::bad_any_cast &) {
739 min = (*m.
features().
find(
"minute")).getValueLimaString().toUShort();
744 sec = boost::any_cast<unsigned short>((*m.
features().
find(
"second")).getValue());
746 catch(
const boost::bad_any_cast &) {
747 sec = (*m.
features().
find(
"second")).getValueLimaString().toUShort();
752 LDEBUG <<
"NormalizeTime::getTimeDuration h=" << hou <<
",m=" << min <<
",s" << sec;
756 std::string timeString=(*m.
features().
find(
"time")).getValueLimaString().toUtf8().constData();
758 string::size_type i=timeString.find(
':');
759 if (i!=string::npos) {
763 timeDuration=QTime::fromString(QString::fromUtf8(timeString.c_str()));
765 catch (std::exception& e) {
767 LWARN <<
"Error getting time duration from string '"
768 << timeString <<
"'";
773 i=timeString.find_first_of(
"hH");
774 if (i!=string::npos) {
775 hou=atoi(
string(timeString,0,i).c_str());
776 min=atoi(
string(timeString,i+1).c_str());
780 timeDuration=QTime(hou,min,sec);
788 const QTime& duration
792 return QDateTime(d,duration).toUTC().time();
812 std::string referenceLocation;
813 bool hasReferenceLocation(
true);
820 if (!
getReferenceData().getReferenceLocation(analysis,referenceLocation)) {
824 hasReferenceLocation=
false;
829 if (!timeDuration.isValid()) {
835 QTime local(QDateTime(referenceDate,timeDuration).time());
839 if (! hasReferenceLocation) {
844 QTime utc=
getUTCTime(referenceDate,timeDuration
847 if (!utc.isValid()) {
849 LWARN <<
"failed to normalize time: ";
850 LDEBUG <<
"NormalizeLocalTime::operator(): m.getString()=" << m.
getString();
858 catch (std::exception& e) {
860 LWARN <<
"exception caught in time normalization of '"
862 <<
"': " << e.what();
883 LDEBUG <<
"NormalizeUTCTime::operator()...";
891 LDEBUG <<
"NormalizeUTCTime::operator: setFeature(TIMESTRING_FEATURE_NAME=" << m.
getString();
897 if (!timeDuration.isValid()) {
899 LWARN <<
"cannot compute time duration for '"
907 QTime utcTime(QDateTime(referenceDate,timeDuration).toUTC().time());
910 catch (std::exception& e) {
912 LWARN <<
"exception caught in time normalization of '"
914 <<
"': " << e.what();
#define DEFAULT_ATTRIBUTE
#define DATE_SPAN_FEATURE_NAME
#define MONTHEND_FEATURE_NAME
#define DATE_FEATURE_NAME
#define NUMDAY_FEATURE_NAME
#define NUMYEAREND_FEATURE_NAME
#define NUMYEAR_FEATURE_NAME
#define NUMMONTH_FEATURE_NAME
#define NUMMONTHEND_FEATURE_NAME
#define DATE_END_FEATURE_NAME
#define UTCTIME_FEATURE_NAME
#define DATESTRING_FEATURE_NAME
#define MONTH_FEATURE_NAME
#define NUMDAYEND_FEATURE_NAME
#define TIMESTRING_FEATURE_NAME
#define LOCALTIME_FEATURE_NAME
#define DATE_BEGIN_FEATURE_NAME
#define NUMDAYMONTH_FEATURE_NAME
#define NormalizeRelativeDateId
#define NormalizeLocalTimeId
#define NormalizeUTCTimeId
Holds all data that pass through the ProcessUnits Analysis data are shared pointers,...
std::shared_ptr< AnalysisData > getData(const QString &id)
return AnalysisData by id
␈rief A class for the description of automata
void setFeature(const std::string &name, const ValueType &value)
void addFeature(const std::string &name, const ValueType &value)
EntityFeatures::const_iterator find(const std::string &featureName) const
const EntityFeatures & features() const
LimaString getString() const
static const unsigned short no_day
ReferenceData m_referenceData
const std::set< LinguisticCode > * m_microsForMonth
unsigned short getDayFromString(const LimaString &numdayString) const
std::shared_ptr< NormalizeDateTimeResources > m_resources
NormalizeDate(MediaId language, const LimaString &complement=LimaString())
unsigned short getDay(Automaton::RecognizerMatch &m, const std::string &featureName) const
const std::set< LinguisticCode > * m_microsForDays
unsigned short getYear(Automaton::RecognizerMatch &m, const std::string &featureName) const
unsigned short getMonth(Automaton::RecognizerMatch &m, const std::string &featureName, const std::string &alt="") const
unsigned short getWeekDay(Automaton::RecognizerMatch &m, const std::string &featureName) const
QString getDateSpan(unsigned short year, unsigned short month, unsigned short day) const
bool operator()(Automaton::RecognizerMatch &m, AnalysisContent &analysis) const override
zero-ary constraint function : applies the function without a vertex indication (used for actions,...
const Common::PropertyCode::PropertyAccessor * m_microAccessor
void updateCurrentDate(AnalysisContent &analysis, const QDate ¤tDate) const
bool operator()(Automaton::RecognizerMatch &m, AnalysisContent &analysis) const override
zero-ary constraint function : applies the function without a vertex indication (used for actions,...
NormalizeLocalTime(MediaId language, const LimaString &complement=LimaString())
bool operator()(Automaton::RecognizerMatch &m, AnalysisContent &analysis) const override
zero-ary constraint function : applies the function without a vertex indication (used for actions,...
NormalizeRelativeDate(MediaId language, const LimaString &complement=LimaString())
QTime getUTCTime(const QDate &d, const QTime &duration) const
const ReferenceData & getReferenceData() const
const std::shared_ptr< NormalizeDateTimeResources > getResources() const
NormalizeTime(MediaId language, const LimaString &complement=LimaString())
bool hasResources() const
QTime getTimeDuration(const Automaton::RecognizerMatch &m) const
NormalizeUTCTime(MediaId language, const LimaString &complement=LimaString())
bool operator()(Automaton::RecognizerMatch &m, AnalysisContent &analysis) const override
zero-ary constraint function : applies the function without a vertex indication (used for actions,...
void parseComplement(const LimaString &complement)
void parseReference(const LimaString &str)
bool getReferenceDate(const AnalysisContent &analysis, QDate &date) const
const std::string & getLocRefName() const
bool getReferenceLocation(const AnalysisContent &analysis, std::string &location) const
bool getReferenceTime(const AnalysisContent &analysis, QTime &time) const
static const MediaticData & single()
const singleton accessor
static LinguisticResources & changeable()
singleton accessor
std::string limastring2utf8stdstring(const Lima::LimaString &phrase, uint32_t size0)
Convert a wide string to a string , in dest up to size bytes.
LimaString utf8stdstring2limastring(const std::string &src)
Automaton::ConstraintFunctionFactory< NormalizeLocalTime > NormalizeLocalTimeFactory(NormalizeLocalTimeId)
Automaton::ConstraintFunctionFactory< NormalizeDate > NormalizeDateFactory(NormalizeDateId)
QDate adjustDate(unsigned short mention, unsigned short ref, const QDate &refDate, bool getNext, bool months=false)
void updateNormalizedForm(RecognizerMatch &m)
Automaton::ConstraintFunctionFactory< NormalizeUTCTime > NormalizeUTCTimeFactory(NormalizeUTCTimeId)
Automaton::ConstraintFunctionFactory< NormalizeRelativeDate > NormalizeRelativeDateFactory(NormalizeRelativeDateId)
void swap(T &lhs, T &rhs)