Skip to content

Commit

Permalink
Merge pull request #251 from qorelanguage/bugfix_243_249_250_reldate_…
Browse files Browse the repository at this point in the history
…fixes

refs #243 #249 #250 fixed bugs in relative date/time arithmetic, adde…
  • Loading branch information
tethal committed Dec 11, 2015
2 parents 6c84248 + e46fdc8 commit bfb68b5
Show file tree
Hide file tree
Showing 8 changed files with 34 additions and 23 deletions.
2 changes: 1 addition & 1 deletion doxygen/lang/180_operators.dox.tmpl
Expand Up @@ -915,7 +915,7 @@ foreach my string $key in (keys $hash)

@par Synopsis
With @ref float "float", @ref integer "integer", or @ref number "number" arguments, subtracts one number from another.\n\n
With @ref date "date" arguments, subtracts one date from another; if both date arguments are absolute dates, the result is a relative date (duration) giving the time between them; if the first date argument is an absolute date and the second is a relative date (duration), then the result is an absolute date. If both date arguments are relative dates, then the result is a relative date. If the first argument is a relative date and the second date is an absolute date, the result is an absolute date as if the operands were reversed.\n\n
With @ref date "date" arguments, subtracts one date from another; if both date arguments are @ref absolute_dates "absolute dates", the result is a @ref relative_dates "relative date" (duration) giving the time between them; if the first date argument is an @ref absolute_dates "absolute date" and the second is a @ref relative_dates "relative date" (duration), then the result is an @ref absolute_dates "absolute date". If both date arguments are @ref relative_dates "relative dates", then the result is a @ref relative_dates "relative date". If the first argument is a @ref relative_dates "relative date" and the second date is an @ref absolute_dates "absolute date", the @ref absolute_dates "absolute date"'s epoch offset (offset in seconds and microseconds from \c 1970-01-01Z) is used to perform the calculation, and a @ref relative_dates "relative date/time value" is produced.\n\n
However, if the left-hand side is a @ref hash "hash", and the right-hand side is a string, then the hash key represented by the string will be removed from the hash. If the left-hand side is a hash and the right-hand side is a list, then each element in the list will be converted to a string and any hash key with that name will be deleted from the hash.

@par Syntax
Expand Down
2 changes: 2 additions & 0 deletions doxygen/lang/900_release_notes.dox.tmpl
Expand Up @@ -370,6 +370,8 @@
- fixed a bug where imported global variables (@ref Qore::Program::importGlobalVariable()) were added to the pending global variable list and therefore were removed if a parse exception occurred, hwoever the namespace indexes remained, which could lead to unexpected problems at runtime including a crash. Additionally the pending global variable list was not checked which could lead to a memory leak if the a single global variable name is pending, imported, and then committed to the @ref Qore::Program "Program" object.
- fixed memory errors managing program feature lists in the CharPtrList class by copying string memory instead of using sometimes temporary values in the list
- fixed minor bugs with directive parsing, mostly related to error reporting
- fixed bugs in relative date arithmetic where operands were swapped with the @ref minus_operator "- operator" if the first operand was a @ref relative_dates "relative date/time value", additionally an operation with the @ref minus_operator "- operator" where the first operand is a @ref relative_dates "relative date" and the second operand is a @ref absolute_dates "absolute date" is now calculated using the @ref absolute_dates "absolute date"'s epoch offset (offset in seconds and microseconds from \c 1970-01-01Z), and a @ref relative_dates "relative date/time value" is produced
- fixed a bug normalizing the result of date arithmetic between hour and minute components of @ref relative_dates "relative date/time value"

@section qore_0811 Qore 0.8.11

Expand Down
8 changes: 8 additions & 0 deletions examples/test/qore/operators/operators.qtest
Expand Up @@ -81,6 +81,14 @@ class Test inherits QUnit::Test {
at -= (3h + 5m);
testAssertionValue("second date += operator", at, 2004-02-29-08:55:00);

# relative date arithmetic tests
assertEq(3s, 5s - 2s);
assertEq(-1s, 2s - 3s);
# check for normalization between hours & minutes
assertEq(30m, 1h - 30m);
# rel date - abs date is performed by using the seconds + us offset from the epoch in the absolute date
assertEq(15s, 30s - 1970-01-01T00:00:15Z);

any ni += 3.2;
testAssertionValue("float +=, lhs NOTHING", ni, 3.2);
delete ni;
Expand Down
12 changes: 9 additions & 3 deletions include/qore/intern/qore_date_private.h
Expand Up @@ -784,7 +784,10 @@ class qore_relative_time : public qore_simple_tm {
// no longer normalize days, as with DST not all days are 24 hours

// normalize hours from seconds
normalize_units<int, int>(hour, second, 3600);
//normalize_units<int, int>(hour, second, 3600);

// normalize hours from minutes
normalize_units<int, int>(hour, minute, 60);

// normalize minutes from seconds
normalize_units<int, int>(minute, second, 60);
Expand Down Expand Up @@ -953,6 +956,7 @@ class qore_relative_time : public qore_simple_tm {

DLLLOCAL qore_relative_time& operator+=(const qore_relative_time& dt);
DLLLOCAL qore_relative_time& operator-=(const qore_relative_time& dt);
DLLLOCAL qore_relative_time& operator-=(const qore_absolute_time& dt);

DLLLOCAL void getAsString(QoreString& str) const {
int f = 0;
Expand Down Expand Up @@ -1237,8 +1241,10 @@ class qore_date_private {
return;
}

assert(dt.relative);
d.rel -= dt.d.rel;
if (dt.relative)
d.rel -= dt.d.rel;
else
d.rel -= dt.d.abs;
}

DLLLOCAL void addSecondsTo(int64 secs, int us) {
Expand Down
11 changes: 2 additions & 9 deletions lib/DateTime.cpp
Expand Up @@ -297,15 +297,8 @@ DateTime* DateTime::subtractBy(const DateTime* dt) const {
}

DateTime* DateTime::subtractBy(const DateTime& dt) const {
DateTime* rv;
if (isRelative()) {
rv = new DateTime(dt);
rv->priv->subtractBy(*priv);
}
else {
rv = new DateTime(*this);
rv->priv->subtractBy(*dt.priv);
}
DateTime* rv = new DateTime(*this);
rv->priv->subtractBy(*dt.priv);
return rv;
}

Expand Down
11 changes: 2 additions & 9 deletions lib/DateTimeNode.cpp
Expand Up @@ -188,15 +188,8 @@ DateTimeNode* DateTimeNode::subtractBy(const DateTime& dt) const {
if (!dt.hasValue())
return refSelf();

DateTimeNode* rv;
if (isRelative()) {
rv = new DateTimeNode(dt);
rv->priv->subtractBy(*priv);
}
else {
rv = new DateTimeNode(*this);
rv->priv->subtractBy(*dt.priv);
}
DateTimeNode* rv = new DateTimeNode(*this);
rv->priv->subtractBy(*dt.priv);
return rv;
}

Expand Down
2 changes: 1 addition & 1 deletion lib/Operator.cpp
Expand Up @@ -388,7 +388,7 @@ static int64 op_multiply_bigint(int64 left, int64 right) {
}

static DateTimeNode* op_minus_date(const DateTimeNode* left, const DateTimeNode* right) {
return left->subtractBy(right);
return left->subtractBy(right);
}

static DateTimeNode* op_plus_date(const DateTimeNode* left, const DateTimeNode* right) {
Expand Down
9 changes: 9 additions & 0 deletions lib/qore_date_private.cpp
Expand Up @@ -501,6 +501,15 @@ qore_relative_time &qore_relative_time::operator-=(const qore_relative_time &dt)
return *this;
}

qore_relative_time &qore_relative_time::operator-=(const qore_absolute_time &dt) {
second -= dt.epoch;
us -= dt.us;

normalize();

return *this;
}

void qore_relative_time::set(const QoreValue v) {
switch (v.type) {
case QV_Bool: {
Expand Down

0 comments on commit bfb68b5

Please sign in to comment.