QCron::next returns the next date matching the cron pattern.
This commit is contained in:
parent
0d57baf3f7
commit
311b6689fe
171
src/qcron.cpp
171
src/qcron.cpp
@ -1,4 +1,5 @@
|
||||
#include "qcron.hpp"
|
||||
#include "qcronnode.hpp"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
@ -87,15 +88,167 @@ _parsePattern(QString & pattern)
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
QList<EField>
|
||||
getPreviousFields(EField field)
|
||||
{
|
||||
QList<EField> fields;
|
||||
|
||||
switch (field)
|
||||
{
|
||||
case YEAR:
|
||||
fields << MONTH;
|
||||
case MONTH:
|
||||
fields << DOM;
|
||||
case DOW:
|
||||
case DOM:
|
||||
fields << HOUR;
|
||||
case HOUR:
|
||||
fields << MINUTE;
|
||||
case MINUTE:
|
||||
break;
|
||||
default:
|
||||
qFatal("Should not be in getPreviousTimeUnit");
|
||||
}
|
||||
|
||||
return fields;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void
|
||||
QCron::
|
||||
add(QDateTime & dt, EField field, int value)
|
||||
{
|
||||
switch (field)
|
||||
{
|
||||
case YEAR:
|
||||
dt = dt.addYears(value);
|
||||
break;
|
||||
case MONTH:
|
||||
dt = dt.addMonths(value);
|
||||
break;
|
||||
case DOW:
|
||||
case DOM:
|
||||
dt = dt.addDays(value);
|
||||
break;
|
||||
case HOUR:
|
||||
dt = dt.addSecs(3600 * value);
|
||||
break;
|
||||
case MINUTE:
|
||||
dt = dt.addSecs(60 * value);
|
||||
break;
|
||||
default:
|
||||
qFatal("Unknown value in add");
|
||||
}
|
||||
QList<EField> previous_fields = getPreviousFields(field);
|
||||
foreach (EField field, previous_fields)
|
||||
{
|
||||
_fields[field].reset(dt);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void
|
||||
set(QDateTime & dt, EField field, int value)
|
||||
{
|
||||
QDate date = dt.date();
|
||||
QTime time = dt.time();
|
||||
|
||||
switch (field)
|
||||
{
|
||||
case YEAR:
|
||||
dt.setDate(QDate(value, date.month(), date.day()));
|
||||
break;
|
||||
case MONTH:
|
||||
dt.setDate(QDate(date.year(), value, date.day()));
|
||||
break;
|
||||
case DOW:
|
||||
case DOM:
|
||||
dt.setDate(QDate(date.year(), date.month(), value));
|
||||
break;
|
||||
case HOUR:
|
||||
dt.setTime(QTime(value, time.minute(), 0));
|
||||
break;
|
||||
case MINUTE:
|
||||
dt.setTime(QTime(time.hour(), value, 0));
|
||||
break;
|
||||
default:
|
||||
qFatal("Unknown value in add");
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void
|
||||
QCron::
|
||||
catchUp(QDateTime & dt, EField field, int value)
|
||||
{
|
||||
int current_time_unit = _fields[field].getDateTimeSection(dt);
|
||||
if (current_time_unit < value)
|
||||
{
|
||||
add(dt, field, value - current_time_unit);
|
||||
}
|
||||
else if (current_time_unit == value)
|
||||
{
|
||||
// Nothing
|
||||
}
|
||||
else if (current_time_unit > value)
|
||||
{
|
||||
if (YEAR == field)
|
||||
{
|
||||
dt = QDateTime();
|
||||
}
|
||||
else if (MINUTE != field)
|
||||
{
|
||||
int max = _fields[field].getMax();
|
||||
add(dt, field, (max - current_time_unit + value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void
|
||||
QCron::
|
||||
chiche(QDateTime & dt, EField field)
|
||||
{
|
||||
QCronNode * node = _fields[field].getRoot();
|
||||
if (NULL == node)
|
||||
{
|
||||
qFatal("Problem");
|
||||
}
|
||||
node->process(this, dt, field);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
QDateTime
|
||||
QCron::
|
||||
next(QDateTime dt)
|
||||
{
|
||||
for (int i = 0; i < 6; ++i)
|
||||
dt = dt.addSecs(60);
|
||||
while (!match(dt))
|
||||
{
|
||||
_fields[i].next(dt);
|
||||
//qDebug() << dt << "doesn't match";
|
||||
for (int i = YEAR; i >= 0; --i)
|
||||
{
|
||||
chiche(dt, (EField)i);
|
||||
//qDebug() << dt << "after Chcihe";
|
||||
if (!dt.isValid())
|
||||
{
|
||||
return dt;
|
||||
}
|
||||
while (!_fields[(EField)i].match(dt))
|
||||
{
|
||||
//qDebug() << dt << (EField)i << "doesn't match";
|
||||
int dummy = 1;
|
||||
_fields[(EField)i].applyOffset(dt, dummy);
|
||||
}
|
||||
}
|
||||
}
|
||||
return dt;
|
||||
}
|
||||
@ -111,3 +264,17 @@ next(int n)
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
bool
|
||||
QCron::
|
||||
match(const QDateTime & dt) const
|
||||
{
|
||||
bool does_match = true;
|
||||
for (int i = 0; i < 6; ++i)
|
||||
{
|
||||
does_match &= _fields[i].match(dt);
|
||||
}
|
||||
return does_match;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -28,6 +28,10 @@ public:
|
||||
|
||||
QDateTime next(int n = 1);
|
||||
QDateTime next(QDateTime dt);
|
||||
void catchUp(QDateTime & dt, EField field, int value);
|
||||
bool match(const QDateTime & dt) const;
|
||||
void add(QDateTime & dt, EField field, int value);
|
||||
|
||||
|
||||
signals:
|
||||
void activated();
|
||||
@ -45,7 +49,7 @@ private:
|
||||
void _parseField(QString & field_str,
|
||||
EField field);
|
||||
QString _validCharacters(EField field);
|
||||
|
||||
void chiche(QDateTime & dt, EField field);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "qcronfield.hpp"
|
||||
#include "qcronnode.hpp"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
@ -29,7 +30,6 @@ _parseInt(QString & str)
|
||||
.arg(str));
|
||||
}
|
||||
str.remove(0, char_idx);
|
||||
//qDebug() << "Parsing int" << value;
|
||||
if (value < _min || _max < value)
|
||||
{
|
||||
throw QCronFieldException(QString("Value %1 out of range [%2;%3]")
|
||||
@ -44,7 +44,6 @@ QCronRangeNode*
|
||||
QCronField::
|
||||
_parseRange(QString & str)
|
||||
{
|
||||
// qDebug() << "Parsing a Range";
|
||||
if (_last_node == NULL)
|
||||
{
|
||||
throw QCronFieldException(QString("Syntax error at %1: range has no beginning")
|
||||
@ -77,7 +76,6 @@ QCronEveryNode*
|
||||
QCronField::
|
||||
_parseEvery(QString & str)
|
||||
{
|
||||
// qDebug() << "Parsing an Every";
|
||||
str.remove(0, 1);
|
||||
return new QCronEveryNode(_last_node, _parseInt(str));
|
||||
}
|
||||
@ -88,13 +86,15 @@ QCronListNode*
|
||||
QCronField::
|
||||
_parseList(QString & str)
|
||||
{
|
||||
// qDebug() << "Parsing a List";
|
||||
QCronListNode * list = new QCronListNode();
|
||||
list->nodes() << _last_node;
|
||||
_last_node = list;
|
||||
while (str[0] == ',')
|
||||
while (!str.isEmpty())
|
||||
{
|
||||
if (str[0] == ',')
|
||||
{
|
||||
str.remove(0, 1);
|
||||
}
|
||||
QCronNode * node = _parseNode(str);
|
||||
list->nodes() << node;
|
||||
_last_node = node;
|
||||
@ -108,69 +108,75 @@ QCronNode *
|
||||
QCronField::
|
||||
_parseNode(QString & str)
|
||||
{
|
||||
//qDebug() << "Parsing a node";
|
||||
QCronNode * node = NULL;
|
||||
QChar c = str[0];
|
||||
if (c.isDigit())
|
||||
{
|
||||
return _parseInt(str);
|
||||
node = _parseInt(str);
|
||||
}
|
||||
else if ("-" == c)
|
||||
{
|
||||
return _parseRange(str);
|
||||
node = _parseRange(str);
|
||||
}
|
||||
else if ("/" == c)
|
||||
{
|
||||
return _parseEvery(str);
|
||||
node = _parseEvery(str);
|
||||
}
|
||||
else if ("*" == c)
|
||||
{
|
||||
return new QCronAllNode;
|
||||
str.remove(0, 1);
|
||||
node = new QCronAllNode;
|
||||
}
|
||||
else if ("," == c)
|
||||
{
|
||||
return _parseList(str);
|
||||
node = _parseList(str);
|
||||
}
|
||||
if (NULL == node)
|
||||
{
|
||||
throw QCronFieldException(QString("Unexpected character %1").arg(c));
|
||||
}
|
||||
node->setField(this);
|
||||
return node;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void
|
||||
QCronField::
|
||||
parse(QString & str)
|
||||
{
|
||||
try
|
||||
{
|
||||
_last_node = NULL;
|
||||
_root = _parseNode(str);
|
||||
if (!str.isEmpty())
|
||||
while (!str.isEmpty())
|
||||
{
|
||||
_last_node = _root;
|
||||
_root = _parseNode(str);
|
||||
}
|
||||
_is_valid = true;
|
||||
}
|
||||
catch (int)
|
||||
{
|
||||
_is_valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
int
|
||||
QCronField::
|
||||
getDateTimeSection(QDateTime & dt) const
|
||||
getDateTimeSection(const QDateTime & dt) const
|
||||
{
|
||||
switch (_field)
|
||||
{
|
||||
case MINUTE: return dt.time().minute();
|
||||
case HOUR: return dt.time().hour();
|
||||
case DOM: return dt.date().day();
|
||||
case MONTH: return dt.date().month();
|
||||
case DOW: return dt.date().dayOfWeek();
|
||||
case YEAR: return dt.date().year();
|
||||
default: qFatal("Shouldn't be here");
|
||||
case MINUTE:
|
||||
return dt.time().minute();
|
||||
case HOUR:
|
||||
return dt.time().hour();
|
||||
case DOM:
|
||||
return dt.date().day();
|
||||
case MONTH:
|
||||
return dt.date().month();
|
||||
case DOW:
|
||||
return dt.date().dayOfWeek();
|
||||
case YEAR:
|
||||
return dt.date().year();
|
||||
default:
|
||||
qFatal("Shouldn't be here");
|
||||
}
|
||||
}
|
||||
|
||||
@ -178,40 +184,34 @@ getDateTimeSection(QDateTime & dt) const
|
||||
|
||||
void
|
||||
QCronField::
|
||||
applyOffset(QDateTime & dt, int offset) const
|
||||
applyOffset(QDateTime & dt, int & offset) const
|
||||
{
|
||||
bool overflow = offset < 0 || (offset == 0 && _field == MINUTE);
|
||||
|
||||
offset += overflow ? 1 : 0;
|
||||
|
||||
switch (_field)
|
||||
{
|
||||
case MINUTE:
|
||||
{
|
||||
offset -= overflow ? 1 : 0;
|
||||
offset += offset <= 0 ? 60 : 0;
|
||||
dt = dt.addSecs(60 * offset);
|
||||
break;
|
||||
}
|
||||
case HOUR:
|
||||
{
|
||||
dt.addSecs(3600 * offset);
|
||||
dt = dt.addSecs(3600 * offset);
|
||||
break;
|
||||
}
|
||||
case DOM:
|
||||
case DOW:
|
||||
{
|
||||
dt.addDays(offset);
|
||||
dt = dt.addDays(offset);
|
||||
break;
|
||||
}
|
||||
case MONTH:
|
||||
{
|
||||
dt.addMonths(offset);
|
||||
dt = dt.addMonths(offset);
|
||||
break;
|
||||
}
|
||||
case YEAR:
|
||||
{
|
||||
dt.addYears(offset);
|
||||
dt = dt.addYears(offset);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -223,11 +223,54 @@ applyOffset(QDateTime & dt, int offset) const
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void
|
||||
int
|
||||
QCronField::
|
||||
next(QDateTime & dt)
|
||||
{
|
||||
int time_section = getDateTimeSection(dt);
|
||||
int offset = _root->next(time_section);
|
||||
applyOffset(dt, offset);
|
||||
return _root->next(time_section);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void
|
||||
QCronField::
|
||||
reset(QDateTime & dt)
|
||||
{
|
||||
int value = _min;
|
||||
QDate date = dt.date();
|
||||
QTime time = dt.time();
|
||||
|
||||
switch (_field)
|
||||
{
|
||||
case YEAR:
|
||||
dt.setDate(QDate(value, date.month(), date.day()));
|
||||
break;
|
||||
case MONTH:
|
||||
dt.setDate(QDate(date.year(), value, date.day()));
|
||||
break;
|
||||
case DOW:
|
||||
case DOM:
|
||||
dt.setDate(QDate(date.year(), date.month(), value));
|
||||
break;
|
||||
case HOUR:
|
||||
dt.setTime(QTime(value, time.minute(), 0));
|
||||
break;
|
||||
case MINUTE:
|
||||
dt.setTime(QTime(time.hour(), value, 0));
|
||||
break;
|
||||
default:
|
||||
qFatal("Unknown value in add");
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
bool
|
||||
QCronField::
|
||||
match(const QDateTime & dt) const
|
||||
{
|
||||
return _root->match(getDateTimeSection(dt));
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -4,7 +4,6 @@
|
||||
#include <QDateTime>
|
||||
#include <QList>
|
||||
#include <QString>
|
||||
#include "qcronnode.hpp"
|
||||
|
||||
enum EField
|
||||
{
|
||||
@ -16,6 +15,12 @@ enum EField
|
||||
YEAR
|
||||
};
|
||||
|
||||
class QCronIntNode;
|
||||
class QCronRangeNode;
|
||||
class QCronNode;
|
||||
class QCronEveryNode;
|
||||
class QCronListNode;
|
||||
|
||||
class QCronFieldException
|
||||
{
|
||||
public:
|
||||
@ -47,21 +52,36 @@ public:
|
||||
case DOM: _min = 1; _max = 31; break;
|
||||
case MONTH: _min = 1; _max = 12; break;
|
||||
case DOW: _min = 1; _max = 7 ; break;
|
||||
case YEAR: _min = 2016; _max = 2099; break;
|
||||
case YEAR: _min = 1; _max = 2099; break;
|
||||
default: throw 42;
|
||||
}
|
||||
}
|
||||
EField getField() const
|
||||
{ return _field; }
|
||||
|
||||
int getMax() const
|
||||
{ return _max; }
|
||||
|
||||
int getMin() const
|
||||
{ return _min; }
|
||||
|
||||
// Features.
|
||||
void parse(QString & str);
|
||||
|
||||
bool isValid() const
|
||||
{ return _is_valid; }
|
||||
bool match(const QDateTime & dt) const;
|
||||
|
||||
void next(QDateTime & dt);
|
||||
QCronNode * getRoot() const
|
||||
{ return _root; }
|
||||
|
||||
int next(QDateTime & dt);
|
||||
|
||||
int getDateTimeSection(const QDateTime & dt) const;
|
||||
void applyOffset(QDateTime & dt, int & offset) const;
|
||||
|
||||
void reset(QDateTime & dt);
|
||||
|
||||
int getDateTimeSection(QDateTime & dt) const;
|
||||
void applyOffset(QDateTime & dt, int offset) const;
|
||||
|
||||
private:
|
||||
int _min;
|
||||
|
@ -1,4 +1,10 @@
|
||||
#include "qcronnode.hpp"
|
||||
#include "qcronfield.hpp"
|
||||
#include "qcron.hpp"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
@ -9,6 +15,16 @@ QCronNode::
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void
|
||||
QCronNode::
|
||||
setField(QCronField * field)
|
||||
{
|
||||
_field = field;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
QCronIntNode::
|
||||
QCronIntNode(int v)
|
||||
: _value(v)
|
||||
@ -35,6 +51,27 @@ next(int t) const
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void
|
||||
QCronIntNode::
|
||||
process(QCron * cron,
|
||||
QDateTime & dt,
|
||||
EField field)
|
||||
{
|
||||
cron->catchUp(dt, field, _value);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
bool
|
||||
QCronIntNode::
|
||||
match(int tu) const
|
||||
{
|
||||
return tu == _value;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
int
|
||||
QCronStrNode::
|
||||
next(int t) const
|
||||
@ -44,16 +81,61 @@ next(int t) const
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void
|
||||
QCronStrNode::
|
||||
process(QCron *,
|
||||
QDateTime &,
|
||||
EField )
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
bool
|
||||
QCronStrNode::
|
||||
match(int tu) const
|
||||
{
|
||||
return tu;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
int
|
||||
QCronAllNode::
|
||||
next(int t) const
|
||||
{
|
||||
Q_UNUSED(t);
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void
|
||||
QCronAllNode::
|
||||
process(QCron * cron,
|
||||
QDateTime & dt,
|
||||
EField field)
|
||||
{
|
||||
Q_UNUSED(cron);
|
||||
Q_UNUSED(dt);
|
||||
Q_UNUSED(field);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
bool
|
||||
QCronAllNode::
|
||||
match(int tu) const
|
||||
{
|
||||
Q_UNUSED(tu);
|
||||
return true;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
QCronRangeNode::
|
||||
QCronRangeNode(const QCronIntNode * begin,
|
||||
const QCronIntNode * end)
|
||||
@ -64,19 +146,71 @@ QCronRangeNode(const QCronIntNode * begin,
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void
|
||||
QCronRangeNode::
|
||||
process(QCron * cron,
|
||||
QDateTime & dt,
|
||||
EField field)
|
||||
{
|
||||
int begin = beginValue();
|
||||
int end = endValue();
|
||||
int current_time_unit = _field->getDateTimeSection(dt);
|
||||
if (current_time_unit < begin || end < current_time_unit)
|
||||
{
|
||||
cron->catchUp(dt, field, begin);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (field == MINUTE)
|
||||
{
|
||||
cron->add(dt, field, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
int
|
||||
QCronRangeNode::
|
||||
beginValue() const
|
||||
{
|
||||
return _begin->value();
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
int
|
||||
QCronRangeNode::
|
||||
endValue() const
|
||||
{
|
||||
return _end->value();
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
int
|
||||
QCronRangeNode::
|
||||
next(int t) const
|
||||
{
|
||||
if (_begin->value() <= t && t < _end->value())
|
||||
if (_begin->value() <= t && t <= _end->value())
|
||||
{
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
return _begin->value() - t;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
bool
|
||||
QCronRangeNode::
|
||||
match(int tu) const
|
||||
{
|
||||
return _begin->value() <= tu && tu <= _end->value();
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
QCronEveryNode::
|
||||
QCronEveryNode(QCronNode * what,
|
||||
QCronIntNode * freq)
|
||||
@ -85,27 +219,82 @@ QCronEveryNode(QCronNode * what,
|
||||
{
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void
|
||||
QCronEveryNode::
|
||||
process(QCron * cron ,
|
||||
QDateTime & dt,
|
||||
EField field)
|
||||
{
|
||||
int freq = _freq->value();
|
||||
_what->process(cron, dt, field);
|
||||
while (_field->getDateTimeSection(dt) % freq)
|
||||
{
|
||||
cron->add(dt, field, 1);
|
||||
_what->process(cron, dt, field);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
int
|
||||
QCronEveryNode::
|
||||
next(int t) const
|
||||
{
|
||||
int next = _what->next(t) % _freq->value();
|
||||
int what_next = _what->next(t);
|
||||
if (what_next == 1)
|
||||
{
|
||||
/* what_next == 1 if we're in the right range AND if we're one
|
||||
* time unit ahead of it */
|
||||
int next = t % _freq->value();
|
||||
return _freq->value() - next;
|
||||
}
|
||||
return what_next;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
QList<QCronNode *>
|
||||
bool
|
||||
QCronEveryNode::
|
||||
match(int tu) const
|
||||
{
|
||||
return _what->match(tu) && tu % _freq->value() == 0;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
QList<QCronNode *> &
|
||||
QCronListNode::
|
||||
nodes() const
|
||||
nodes()
|
||||
{
|
||||
return _nodes;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void
|
||||
QCronListNode::
|
||||
process(QCron * cron,
|
||||
QDateTime & dt,
|
||||
EField field)
|
||||
{
|
||||
foreach (QCronNode * node, _nodes)
|
||||
{
|
||||
int node_next = node->next(_field->getDateTimeSection(dt));
|
||||
if (node_next >= 0)
|
||||
{
|
||||
node->process(cron, dt, field);
|
||||
return;
|
||||
}
|
||||
}
|
||||
_nodes[0]->process(cron, dt, field);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
int
|
||||
QCronListNode::
|
||||
next(int t) const
|
||||
@ -113,7 +302,7 @@ next(int t) const
|
||||
foreach (const QCronNode * node, _nodes)
|
||||
{
|
||||
int node_next = node->next(t);
|
||||
if (t > 0)
|
||||
if (node_next > 0 && node_next != _field->getMax() + 1)
|
||||
{
|
||||
return node_next;
|
||||
}
|
||||
@ -122,3 +311,20 @@ next(int t) const
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
bool
|
||||
QCronListNode::
|
||||
match(int tu) const
|
||||
{
|
||||
foreach (const QCronNode * node, _nodes)
|
||||
{
|
||||
if (node->match(tu))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/******************************************************************************/
|
||||
|
@ -4,12 +4,27 @@
|
||||
#include <QList>
|
||||
#include <QtGlobal>
|
||||
|
||||
#include "qcronfield.hpp"
|
||||
|
||||
class QCron;
|
||||
class QCronField;
|
||||
|
||||
class QCronNode
|
||||
{
|
||||
public:
|
||||
virtual ~QCronNode();
|
||||
|
||||
void setField(QCronField * field);
|
||||
|
||||
virtual int next(int t) const = 0;
|
||||
|
||||
virtual bool match(int tu) const = 0;
|
||||
virtual void process(QCron * cron,
|
||||
QDateTime & dt,
|
||||
EField field) = 0;
|
||||
|
||||
protected:
|
||||
QCronField * _field;
|
||||
};
|
||||
|
||||
class QCronValueNode : public QCronNode
|
||||
@ -24,6 +39,11 @@ public:
|
||||
int value() const;
|
||||
|
||||
virtual int next(int t) const Q_DECL_OVERRIDE;
|
||||
virtual bool match(int tu) const Q_DECL_OVERRIDE;
|
||||
|
||||
virtual void process(QCron * cron,
|
||||
QDateTime & dt,
|
||||
EField field) Q_DECL_OVERRIDE;
|
||||
|
||||
private:
|
||||
int _value;
|
||||
@ -33,12 +53,20 @@ class QCronStrNode : public QCronValueNode
|
||||
{
|
||||
public:
|
||||
virtual int next(int t) const Q_DECL_OVERRIDE;
|
||||
virtual bool match(int tu) const Q_DECL_OVERRIDE;
|
||||
virtual void process(QCron * cron,
|
||||
QDateTime & dt,
|
||||
EField field) Q_DECL_OVERRIDE;
|
||||
};
|
||||
|
||||
class QCronAllNode : public QCronValueNode
|
||||
{
|
||||
public:
|
||||
virtual int next(int t) const Q_DECL_OVERRIDE;
|
||||
virtual bool match(int tu) const Q_DECL_OVERRIDE;
|
||||
virtual void process(QCron * cron,
|
||||
QDateTime & dt,
|
||||
EField field) Q_DECL_OVERRIDE;
|
||||
};
|
||||
|
||||
class QCronRangeNode : public QCronNode
|
||||
@ -47,7 +75,15 @@ public:
|
||||
QCronRangeNode(const QCronIntNode * begin,
|
||||
const QCronIntNode * end);
|
||||
|
||||
int beginValue() const;
|
||||
int endValue() const;
|
||||
|
||||
virtual int next(int t) const Q_DECL_OVERRIDE;
|
||||
virtual bool match(int tu) const Q_DECL_OVERRIDE;
|
||||
|
||||
virtual void process(QCron * cron,
|
||||
QDateTime & dt,
|
||||
EField field) Q_DECL_OVERRIDE;
|
||||
|
||||
private:
|
||||
const QCronIntNode * _begin;
|
||||
@ -60,6 +96,11 @@ public:
|
||||
QCronEveryNode(QCronNode *, QCronIntNode *);
|
||||
|
||||
virtual int next(int t) const Q_DECL_OVERRIDE;
|
||||
virtual bool match(int tu) const Q_DECL_OVERRIDE;
|
||||
|
||||
virtual void process(QCron * cron,
|
||||
QDateTime & dt,
|
||||
EField field) Q_DECL_OVERRIDE;
|
||||
|
||||
private:
|
||||
QCronNode * _what;
|
||||
@ -69,9 +110,13 @@ private:
|
||||
class QCronListNode : public QCronNode
|
||||
{
|
||||
public:
|
||||
QList<QCronNode *> nodes() const;
|
||||
QList<QCronNode *> & nodes();
|
||||
|
||||
virtual int next(int t) const Q_DECL_OVERRIDE;
|
||||
virtual bool match(int tu) const Q_DECL_OVERRIDE;
|
||||
virtual void process(QCron * cron,
|
||||
QDateTime & dt,
|
||||
EField field) Q_DECL_OVERRIDE;
|
||||
|
||||
private:
|
||||
QList<QCronNode*> _nodes;
|
||||
|
@ -11,7 +11,7 @@ void
|
||||
QCronTest::
|
||||
init()
|
||||
{
|
||||
_dnow = QDate::currentDate();
|
||||
_dnow = QDate(1, 1, 1);
|
||||
_tnow = QTime(0, 0, 0);
|
||||
}
|
||||
|
||||
@ -28,29 +28,338 @@ actual(QString & pattern)
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void
|
||||
QCronTest::
|
||||
minutes()
|
||||
{
|
||||
// Star
|
||||
QString pattern = "* * * * * *";
|
||||
_tnow.setHMS(0, 0, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 1));
|
||||
|
||||
// Int
|
||||
pattern = "30 * * * * *";
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 30));
|
||||
_tnow.setHMS(0, 31, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 59));
|
||||
_tnow.setHMS(0, 30, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 60));
|
||||
|
||||
pattern = "0 * * * * *";
|
||||
_tnow.setHMS(0, 0, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 60));
|
||||
_tnow.setHMS(0, 31, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 29));
|
||||
_tnow.setHMS(0, 59, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 1));
|
||||
|
||||
pattern = "59 * * * * *";
|
||||
_tnow.setHMS(0, 0, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 59));
|
||||
_tnow.setHMS(0, 58, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 1));
|
||||
_tnow.setHMS(0, 59, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 60));
|
||||
|
||||
// Range
|
||||
pattern = "10-20 * * * * *";
|
||||
_tnow.setHMS(0, 5, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 5));
|
||||
_tnow.setHMS(0, 9, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 1));
|
||||
_tnow.setHMS(0, 10, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 1));
|
||||
_tnow.setHMS(0, 15, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 1));
|
||||
_tnow.setHMS(0, 20, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 50));
|
||||
_tnow.setHMS(0, 30, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 40));
|
||||
|
||||
// Every - easy
|
||||
pattern = "*/5 * * * * *";
|
||||
_tnow.setHMS(0, 0, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 5));
|
||||
_tnow.setHMS(0, 4, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 1));
|
||||
_tnow.setHMS(0, 5, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 5));
|
||||
_tnow.setHMS(0, 16, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 4));
|
||||
_tnow.setHMS(0, 54, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 1));
|
||||
_tnow.setHMS(0, 57, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 3));
|
||||
|
||||
// Every - medium
|
||||
pattern = "14-28/2 * * * * *";
|
||||
_tnow.setHMS(0, 0, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 14));
|
||||
_tnow.setHMS(0, 13, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 1));
|
||||
_tnow.setHMS(0, 14, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 2));
|
||||
_tnow.setHMS(0, 15, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 1));
|
||||
_tnow.setHMS(0, 16, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 2));
|
||||
_tnow.setHMS(0, 28, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 46));
|
||||
|
||||
// List - easy
|
||||
pattern = "10,15,16 * * * * *";
|
||||
_tnow.setHMS(0, 5, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 5));
|
||||
_tnow.setHMS(0, 9, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 1));
|
||||
_tnow.setHMS(0, 10, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 5));
|
||||
_tnow.setHMS(0, 14, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 1));
|
||||
_tnow.setHMS(0, 15, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 1));
|
||||
_tnow.setHMS(0, 16, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 54));
|
||||
_tnow.setHMS(0, 17, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 53));
|
||||
|
||||
// List - medium
|
||||
pattern = "10,15-20,30 * * * * *";
|
||||
_tnow.setHMS(0, 5, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 5));
|
||||
_tnow.setHMS(0, 9, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 1));
|
||||
_tnow.setHMS(0, 10, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 5));
|
||||
_tnow.setHMS(0, 15, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 1));
|
||||
_tnow.setHMS(0, 19, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 1));
|
||||
_tnow.setHMS(0, 20, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 10));
|
||||
_tnow.setHMS(0, 30, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 40));
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
QDateTime
|
||||
QCronTest::
|
||||
expected(int offset)
|
||||
now()
|
||||
{
|
||||
QDateTime exp(_dnow, _tnow);
|
||||
return exp.addSecs(offset * 60);
|
||||
return QDateTime(_dnow, _tnow);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
||||
void
|
||||
QCronTest::
|
||||
years()
|
||||
{
|
||||
// Int
|
||||
QString pattern = "* * * * * 30";
|
||||
_dnow.setDate(15, 1, 2);
|
||||
QCOMPARE(actual(pattern), now().addYears(15).addDays(-1));
|
||||
_dnow.setDate(31, 1, 1);
|
||||
QCOMPARE(actual(pattern), QDateTime());
|
||||
_dnow.setDate(30, 1, 1);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60));
|
||||
_dnow.setDate(30, 12, 31);
|
||||
_tnow.setHMS(23, 59, 0);
|
||||
QCOMPARE(actual(pattern), QDateTime());
|
||||
|
||||
pattern = "* * * 6 * 30";
|
||||
_dnow.setDate(15, 1, 1);
|
||||
_tnow.setHMS(0, 0, 0);
|
||||
QCOMPARE(actual(pattern), QDateTime(QDate(30, 6, 1), _tnow));
|
||||
_dnow.setDate(31, 1, 1);
|
||||
QCOMPARE(actual(pattern), QDateTime());
|
||||
_dnow.setDate(30, 6, 1);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60));
|
||||
|
||||
// Range
|
||||
pattern = "* * * * * 10-20";
|
||||
_dnow.setDate(5, 1, 1);
|
||||
QCOMPARE(actual(pattern), now().addYears(5));
|
||||
_dnow.setDate(9, 1, 1);
|
||||
QCOMPARE(actual(pattern), now().addYears(1));
|
||||
_dnow.setDate(10, 1, 1);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60));
|
||||
_dnow.setDate(15, 1, 1);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60));
|
||||
_dnow.setDate(20, 12, 31);
|
||||
_tnow.setHMS(23, 59, 0);
|
||||
QCOMPARE(actual(pattern), QDateTime());
|
||||
_dnow.setDate(20, 12, 31);
|
||||
QCOMPARE(actual(pattern), QDateTime());
|
||||
|
||||
// Every - easy
|
||||
pattern = "* * * * * */5";
|
||||
_dnow.setDate(1, 1, 1);
|
||||
_tnow.setHMS(0, 0, 0);
|
||||
QCOMPARE(actual(pattern), now().addYears(4));
|
||||
_dnow.setDate(4, 1, 1);
|
||||
QCOMPARE(actual(pattern), now().addYears(1));
|
||||
_dnow.setDate(5, 1, 1);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60));
|
||||
_dnow.setDate(16, 1, 1);
|
||||
QCOMPARE(actual(pattern), now().addYears(4));
|
||||
_dnow.setDate(54, 1, 1);
|
||||
QCOMPARE(actual(pattern), now().addYears(1));
|
||||
_dnow.setDate(57, 1, 1);
|
||||
QCOMPARE(actual(pattern), now().addYears(3));
|
||||
|
||||
// Every - medium
|
||||
pattern = "* * * * * 14-28/2";
|
||||
_dnow.setDate(1, 1, 1);
|
||||
QCOMPARE(actual(pattern), now().addYears(13));
|
||||
_dnow.setDate(13, 1, 1);
|
||||
QCOMPARE(actual(pattern), now().addYears(1));
|
||||
_dnow.setDate(14, 1, 1);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60));
|
||||
_dnow.setDate(15, 1, 1);
|
||||
QCOMPARE(actual(pattern), now().addYears(1));
|
||||
_dnow.setDate(16, 1, 1);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60));
|
||||
_dnow.setDate(28, 12, 31);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60));
|
||||
_tnow.setHMS(23, 59, 0);
|
||||
QCOMPARE(actual(pattern), QDateTime());
|
||||
|
||||
// List - easy
|
||||
pattern = "* * * * * 10,15,16";
|
||||
_dnow.setDate(5, 1, 1);
|
||||
_tnow.setHMS(0, 0, 0);
|
||||
QCOMPARE(actual(pattern), now().addYears(5));
|
||||
_dnow.setDate(9, 1, 1);
|
||||
QCOMPARE(actual(pattern), now().addYears(1));
|
||||
_dnow.setDate(10, 1, 1);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60));
|
||||
_dnow.setDate(14, 1, 1);
|
||||
QCOMPARE(actual(pattern), now().addYears(1));
|
||||
_dnow.setDate(15, 1, 1);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60));
|
||||
_dnow.setDate(16, 1, 1);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60));
|
||||
_dnow.setDate(16, 12, 31);
|
||||
_tnow.setHMS(23, 59, 00);
|
||||
QCOMPARE(actual(pattern), QDateTime());
|
||||
|
||||
// List - medium
|
||||
pattern = "* * * * * 10,15-20,30";
|
||||
_dnow.setDate(5, 1, 1);
|
||||
_tnow.setHMS(0, 0, 0);
|
||||
QCOMPARE(actual(pattern), now().addYears(5));
|
||||
_dnow.setDate(9, 1, 1);
|
||||
QCOMPARE(actual(pattern), now().addYears(1));
|
||||
_dnow.setDate(10, 1, 1);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60));
|
||||
_dnow.setDate(15, 1, 1);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60));
|
||||
_dnow.setDate(20, 1, 1);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60));
|
||||
_dnow.setDate(20, 12, 31);
|
||||
_tnow.setHMS(23, 59, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60).addYears(9));
|
||||
|
||||
// Star
|
||||
pattern = "* * * * * *";
|
||||
_dnow.setDate(1, 1, 1);
|
||||
_tnow.setHMS(0, 0, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60));
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void
|
||||
QCronTest::
|
||||
minutes()
|
||||
hours()
|
||||
{
|
||||
QString pattern = "* * * * * *";
|
||||
QCOMPARE(actual(pattern), expected(1));
|
||||
// Int
|
||||
QString pattern = "* 1 * * * *";
|
||||
_dnow.setDate(2016, 1, 1);
|
||||
_tnow.setHMS(0, 0, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 60));
|
||||
_tnow.setHMS(0, 59, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 1));
|
||||
_tnow.setHMS(1, 0, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 1));
|
||||
_tnow.setHMS(1, 58, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 1));
|
||||
_tnow.setHMS(1, 59, 0);
|
||||
QCOMPARE(actual(pattern), now().addDays(1).addSecs(-60 * 59));
|
||||
|
||||
pattern = "30 1,3 * * * *";
|
||||
_tnow.setHMS(0, 0, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 90));
|
||||
_tnow.setHMS(1, 30, 0);
|
||||
QCOMPARE(actual(pattern), now().addSecs(60 * 120));
|
||||
_tnow.setHMS(3, 30, 0);
|
||||
QCOMPARE(actual(pattern), now().addDays(1).addSecs(-120 * 60));
|
||||
|
||||
pattern = "* * * * * 2017";
|
||||
_tnow.setHMS(0, 0, 0);
|
||||
QCOMPARE(actual(pattern), now().addYears(1));
|
||||
|
||||
pattern = "* 2 * * * 2017";
|
||||
QCOMPARE(actual(pattern), now().addYears(1).addSecs(60 * 120));
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void
|
||||
QCronTest::
|
||||
dow()
|
||||
{
|
||||
// 1 = Mon; 7 = Sun
|
||||
QString pattern = "* * * * 1 *"; // Mon
|
||||
|
||||
_dnow.setDate(2016, 1, 1); // Fri
|
||||
_tnow.setHMS(0, 0, 0);
|
||||
QCOMPARE(actual(pattern), now().addDays(3));
|
||||
|
||||
pattern = "* * * * 5 *"; // Fri
|
||||
QCOMPARE(actual(pattern), now().addSecs(60));
|
||||
_tnow.setHMS(23, 59, 59);
|
||||
QCOMPARE(actual(pattern), now().addSecs(1).addDays(6));
|
||||
|
||||
pattern = "* * * * 3 *"; // Wed
|
||||
_tnow.setHMS(0, 0, 0);
|
||||
QCOMPARE(actual(pattern), now().addDays(5));
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void
|
||||
QCronTest::
|
||||
realLife()
|
||||
{
|
||||
/* From monday to friday, from 8:00 to 11:59 and from 14:00 to 17:59. */
|
||||
QString working_hours = "* 8-11,14-17 * * 1-5 *";
|
||||
_dnow.setDate(2016, 1, 4); // Mon
|
||||
_tnow.setHMS(0, 0, 0);
|
||||
QCOMPARE(actual(working_hours), now().addSecs(8 * 3600));
|
||||
_tnow.setHMS(7, 59, 59);
|
||||
QCOMPARE(actual(working_hours), now().addSecs(60));
|
||||
_tnow.setHMS(8, 0, 0);
|
||||
QCOMPARE(actual(working_hours), now().addSecs(60));
|
||||
_tnow.setHMS(11, 58, 0);
|
||||
QCOMPARE(actual(working_hours), now().addSecs(60));
|
||||
_tnow.setHMS(11, 59, 0);
|
||||
QCOMPARE(actual(working_hours), now().addSecs(60 + 3600 * 2));
|
||||
_tnow.setHMS(13, 59, 0);
|
||||
QCOMPARE(actual(working_hours), now().addSecs(60));
|
||||
_tnow.setHMS(14, 0, 0);
|
||||
QCOMPARE(actual(working_hours), now().addSecs(60));
|
||||
_tnow.setHMS(17, 58, 0);
|
||||
QCOMPARE(actual(working_hours), now().addSecs(60));
|
||||
_tnow.setHMS(17, 59, 0);
|
||||
QCOMPARE(actual(working_hours), now().addSecs(60 + 14 * 3600));
|
||||
|
||||
_dnow.setDate(2016, 1, 8); // Fri
|
||||
QCOMPARE(actual(working_hours), now().addSecs(60 + 14 * 3600).addDays(2));
|
||||
|
||||
pattern = "30 * * * * *";
|
||||
QCOMPARE(actual(pattern), expected(30));
|
||||
_tnow.setHMS(0, 31, 0);
|
||||
QCOMPARE(actual(pattern), expected(59));
|
||||
_tnow.setHMS(0, 30, 0);
|
||||
QCOMPARE(actual(pattern), expected(60));
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -10,14 +10,18 @@ class QCronTest : public QObject
|
||||
|
||||
private slots:
|
||||
void init();
|
||||
void years();
|
||||
void dow();
|
||||
void hours();
|
||||
void minutes();
|
||||
void realLife();
|
||||
|
||||
private:
|
||||
QDate _dnow;
|
||||
QTime _tnow;
|
||||
|
||||
QDateTime actual(QString & pattern);
|
||||
QDateTime expected(int offset);
|
||||
QDateTime now();
|
||||
|
||||
};
|
||||
|
||||
|
@ -47,7 +47,12 @@ buildTests(QStringList & good,
|
||||
buildPattern(pattern_idx, QString("%1,%2,").arg(min).arg(min + 1)) <<
|
||||
buildPattern(pattern_idx, "1,a") <<
|
||||
buildPattern(pattern_idx, QString("%1,%2").arg(min).arg(max + 1)) <<
|
||||
buildPattern(pattern_idx, QString("%1,%2").arg(min).arg(min - 1));
|
||||
buildPattern(pattern_idx, QString("%1,%2").arg(min).arg(min - 1)) <<
|
||||
buildPattern(pattern_idx, "1/2/3 * * * * *") <<
|
||||
buildPattern(pattern_idx, "1-2-3 * * * * *") << // Bad range
|
||||
buildPattern(pattern_idx, "** * * * * *") << // Bad star
|
||||
buildPattern(pattern_idx, "1,,2 * * * * *") // Bad list
|
||||
;
|
||||
good << buildPattern(pattern_idx, QString::number(min)) <<
|
||||
buildPattern(pattern_idx, QString("000000000%1").arg(min)) <<
|
||||
buildPattern(pattern_idx, QString::number(max)) <<
|
||||
@ -142,7 +147,7 @@ years()
|
||||
{
|
||||
QStringList good;
|
||||
QStringList bad;
|
||||
buildTests(good, bad, 5, 2016, 2099);
|
||||
buildTests(good, bad, 5, 1, 2099);
|
||||
doTest(good, bad);
|
||||
}
|
||||
|
||||
@ -160,7 +165,7 @@ doTest(QStringList good, QStringList bad)
|
||||
}
|
||||
foreach (QString s, bad)
|
||||
{
|
||||
// qDebug() << s;
|
||||
qDebug() << s;
|
||||
QCron cron(s);
|
||||
QVERIFY(!cron.isValid());
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user