This is an issue that manifests a problem in Signup module. Signup provides the ability to set a reminder for an event a variable number of days before it, and the date on the event can be configurable. When using a date cck field the math of checking if the current date is within the range that a reminder should go out is incorrect, and the reminder is sent before the correct point. Much more information is at #856140: Reminder E-mails Sent as Soon as Cron Runs

The problem has been narrowed down to date module's sql_field handler, specifically STR_TO_DATE. When STR_TO_DATE is used on a Date field and then used within a conditional after DATE_SUB it is incorrect, it is expected to evaluate false and it instead evaluates true.

This is the query that Signup module generates: Assume there is an event node with Date field field_dates with start value ' 2011-11-30T00:00:00' and that we have the Signup 'send_reminder' set to 2.
SELECT n.title, n.nid, n.type, s.reminder_email, s.forwarding_email, field_dates_value FROM node n INNER JOIN signup s ON s.nid = n.nid INNER JOIN content_type_event ON content_type_event.vid = n.vid WHERE (s.send_reminder = 1) AND (n.type = 'event') AND ('2011-04-25 21:11:34' >= DATE_SUB(STR_TO_DATE(field_dates_value, '%Y-%m-%dT%T'), INTERVAL s.reminder_days_before DAY)) AND ('2011-04-25 21:11:34' <= DATE_ADD( STR_TO_DATE(field_dates_value, '%Y-%m-%dT%T'), INTERVAL 1 HOUR));
The above query should not return a result, but it does.

Steps to replicate:

1. Install Date 2.7, CCK, Signup 6.x-1.0
2. Enable Signup
3. Create signup-enabled node type with date field (Date type)
4. Create Signup node, set date many months in the future, enable reminder for 2 days before the event
5. Signup for the event
6. Hit cron, see email reminder

While looking into STR_TO_TIME I came across http://lists.mysql.com/mysql/204350 which says to use DATE_FORMAT

I propose altering
$field = "STR_TO_DATE($field, '%Y-%m-%%dT%T')";
to be
$field = "DATE_FORMAT(STR_TO_DATE($field, '%Y-%m-%%dT%T'), '%Y-%m-%%dT%T')";
which fixes the Signup bug. I will make a patch and test out other Date functionality with it.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

coltrane’s picture

Status: Active » Needs review
FileSize
524 bytes

Proposed one change patch.

scottrigby’s picture

@coltrane from #856140: Reminder E-mails Sent as Soon as Cron Runs I was seeing the same issues, and this patch seems to do the trick. I haven't tested it out exhaustively, but so far so good. Not sure that qualifies for RTBC, but +1 from me.

gjerdery’s picture

This change causes all events to disappear from my calendar view.

echoz’s picture

subscribe

gjerdery’s picture

When the date patch suggested above encounters a view which is set to filter a date by a granularity of less than a day - this causes the view to return nothing. Specifically, it appears the ADDTIME function doesn't cope well with being passed the results of a DATE_FORMAT call. Here's the where clause of my view which doesn't work.

WHERE ((node.status <> 0) AND (node.type in ('event'))) AND (DATE_FORMAT(ADDTIME(DATE_FORMAT(STR_TO_DATE(node_data_field_event_date.field_event_date_value, '%Y-%m-%dT%T'), '%Y-%m-%dT%T'), SEC_TO_TIME(-18000)), '%Y-%m-%d\T%H:%i') > '2011-09-22T10:25') ORDER BY node_data_field_event_date_field_event_date_value ASC
gjerdery’s picture

Am I correct that STR_TO_DATE takes in a string and returns a DATETIME value, while DATE_FORMAT takes in a DATETIME value and returns a string? If so, in the code listed by the OP, are we comparing a string with a DATETIME value, whereas after the patch we are comparing string to string?

gjerdery’s picture

I finally got all my views to show using the recent dev version of date and the patch. I had to change the granularity of the date filter from minute to day. This doesn't yet appear to cause any adverse effects.

gjerdery’s picture

An update - while for those views that you can change to a granularity of Day - this solution above works. However, if you need hour, minute or second granularity for a view, this change to the Date module gives incorrect results.

djdevin’s picture

I found this in the MySQL manual, for DATE_ADD():

The return value depends on the arguments:

    - DATETIME if the first argument is a DATETIME (or TIMESTAMP) value, or if the first argument is a DATE and the unit value uses HOURS, MINUTES, or SECONDS.

    - String otherwise.

To ensure that the result is DATETIME, you can use CAST() to convert the first argument to DATETIME.

I think it's possible for DATE_ADD() to be returning a type/value that isn't comparable to Signup's input. Based on MySQL's recommendations I added a CAST() to DATETIME in the DATE_ADD() and DATE_SUB() calls in Date module. This fixed it for us without having to change signup or our other modules that use different intervals.

The only thing I'm unsure about is whether or not there is a use case for working with DATE, sans time.

protitude’s picture

Tested and seems to fix the issue on the Signup module.

KarenS’s picture

Status: Needs review » Postponed (maintainer needs more info)

Earlier in the code, in sql_offset(), we switched to using ADDTIME instead of DATE_ADD for later versions of MYSQL. I wonder if we need the same change here. The sql_date_math() function is not used much so may need to be updated.

JvE’s picture

Status: Postponed (maintainer needs more info) » Reviewed & tested by the community

No, ADDTIME() takes a TIME or DATETIME, adds a TIME and returns a TIME or DATETIME.
It does not support INTERVAL and so cannot deal with the $granularity needed by sql_date_math().
In fact, I can see no reason why ADDTIME() is used in sql_offset() except that maybe it is slightly faster due to being simpler.

Patch from #9 looks simple and clean and solves our problems.

RobLoach’s picture

Still applies too.

cafuego’s picture

Status: Reviewed & tested by the community » Fixed

Applied to 6.x-2.x-dev.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

kyoder’s picture

Version: 6.x-2.x-dev » 7.x-1.x-dev
Status: Closed (fixed) » Patch (to be ported)

The patch in this ticket needs to be ported to the D7 version.

kyoder’s picture

FileSize
658 bytes

Here's an updated version of the patch for 7.x-2.9-beta2

kyoder’s picture

Version: 7.x-1.x-dev » 7.x-2.9-beta2
Status: Patch (to be ported) » Needs review
cafuego’s picture

Version: 7.x-2.9-beta2 » 7.x-2.x-dev

Can you ensure that patch applies against HEAD please, 7.x-2.x?

djdevin’s picture

Nique’s picture

I need some help understanding the status of this issue.

On 2013-Oct-10, in comment #14, cafuego said that the patch was applied to "Applied to 6.x-2.x-dev" and changed the status to "Fixed" which I believe refers to the patch by djdevin in comment #9.) I am using Date 6.x-2.10 which is dated 2014-Mar-31. I assumed that the bug fixes made to Date 6.x-2.x-dev prior to 2014-Mar-31 would be included in that release. (Date 6.x-2.x-dev is currently dated 2015-May-09.)

Is that wrong?

I ask because I am using Date 6.x-2.10 and Signup 6.x-1.x-dev, and I am still having the problem of reminder e-mails being sent as soon as Cron runs. I don't know if I need to upgrade to or if I need to pursue another avenue for fixing this problem.

Chris Matthews’s picture

The 3 year old patch in #20 to date_api_sql.inc still applies cleanly to the latest 7.x-2.x-dev. Would anyone be able/willing to review/test this patch?

JvE’s picture

Status: Needs review » Reviewed & tested by the community

I reviewed and tested the original D6 patch and have used the D7 patch for many years without issue.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 20: date_sql_handler-1138210-20.patch, failed testing. View results

  • DamienMcKenna committed d3034a9 on 7.x-2.x
    Revert "Issue #1138210 by djdevin, kyoder, coltrane, cafuego, JvE:...
DamienMcKenna’s picture

Status: Needs work » Reviewed & tested by the community
Parent issue: » #2867810: Plan for Date 7.x-2.11 release

  • DamienMcKenna committed 7d4c0b4 on 7.x-2.x
    Issue #1138210 by djdevin, kyoder, coltrane, cafuego, JvE:...
DamienMcKenna’s picture

Status: Reviewed & tested by the community » Fixed

Committed. Thanks.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.