Problem/Motivation

Trying to set a date field to now()

For either Before saving a content item or After saving a content item, are there any examples anywhere that show the correct action for setting a date to the current date/time?

Set a data value
Parameters: data: node.field_approval_date.value, value: 2020-11-12 08:00:00
does nothing

Also tried @rules.current_date_context:current_date ?

Comments

mchaplin created an issue. See original summary.

mchaplin’s picture

Issue summary: View changes
mchaplin’s picture

Issue summary: View changes
mchaplin’s picture

Here's an export of a test rule that just times out

uuid: 1773974c-4515-4efa-84ce-97ccbecfa198
langcode: en
status: true
dependencies: { }
id: test1
label: test1
events:
-
event_name: 'rules_entity_presave:node--job'
description: ''
tags: { }
config_version: '3'
expression:
id: rules_rule
uuid: f87f1be1-87e4-4afa-a1bc-319c4d00ed9d
weight: 0
conditions:
id: rules_and
uuid: 2dad0d04-a038-4a52-aa8d-4a8748574ee1
weight: 0
conditions:
-
id: rules_condition
uuid: c6123b02-a589-4de1-93df-1036a743372f
weight: 0
condition_id: rules_entity_is_of_bundle
negate: false
context_values:
type: node
bundle: job
context_mapping:
entity: node
context_processors:
type:
rules_tokens: { }
bundle:
rules_tokens: { }
provides_mapping: { }
actions:
id: rules_action_set
uuid: 91e1cde3-aa98-4642-98bc-6374b0976006
weight: 0
actions:
-
id: rules_action
uuid: ca2d3735-fffb-4bdc-8a11-9bcc7bb686ee
weight: 0
action_id: rules_system_message
context_values:
message: hi
type: status
repeat: false
context_mapping: { }
context_processors:
message:
rules_tokens: { }
type:
rules_tokens: { }
repeat:
rules_tokens: { }
provides_mapping: { }
-
id: rules_action
uuid: f9ffdc4a-b1e0-41a5-ab8a-77f023694d23
weight: 0
action_id: rules_data_set
context_values:
value: '2020-11-12 08:00:00'
context_mapping:
data: node.field_approval_date.value
context_processors:
value:
rules_tokens: { }
provides_mapping: { }

mchaplin’s picture

Trial and error and using a site message reveals that you should surround the token with brackets
{{@rules.current_date_context:current_date}}
and that returns a Unix timestamp for now.

Can format that
{{@rules.current_date_context:current_date | format_date('custom','Y-m-d H:i:s')}}
but the rule still crashes if you try to set a date value with that.

tawellman’s picture

For anyone else having troubles figuring this out. The Date/Time field is saved in this format: 2024-01-20T07:01:53

To get it to work, for me, I had to set up a Date Format in Configuration > Region and language > Date and time formats

I set the Name to 'Rules Format' and the Format String to 'Y-m-d\TH:m:s'

In the Rules Actions, 'Add action' of 'Set a Data Value'

Use the Data selector to pick your Entity and add a period '.' to get your field to show. Example: wo_time_clock_created.field_start_time

In the Value field, as described above, enter the token with brackets. Just add your new Date Format.

{{@rules.current_date_context:current_date | format_date('rules_format')}}

I am sure there may be a better way to do it but I got it to work. The documentation about this sure needs some help.

UPDATE: This doesn't actually work, the time does not reflect your current time zone. Could really use better documentation on this.

tawellman’s picture

Ok, I think I may have finally figured it out. The Rules CurrentDateContext.php is saving the DateTime in your current timezone and not in a UTC without applying the Mountain Time (or any other specific timezone) adjustment.

So I hacked the code, with a little trial and error I got the following to work...

namespace Drupal\rules\ContextProvider;

use Drupal\Component\Datetime\TimeInterface;
use Drupal\Core\Plugin\Context\Context;
use Drupal\Core\Plugin\Context\ContextDefinition;
use Drupal\Core\Plugin\Context\ContextProviderInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Datetime\DrupalDateTime;

class CurrentDateContext implements ContextProviderInterface {
  use StringTranslationTrait;

  protected $datetime;

  public function __construct(TimeInterface $datetime) {
    $this->datetime = $datetime;
  }

  public function getRuntimeContexts(array $unqualified_context_ids) {
    // Get the current Unix timestamp
    $timestamp = $this->datetime->getCurrentTime();

    // Create a DrupalDateTime object from the timestamp in UTC
    $dateTime = DrupalDateTime::createFromTimestamp($timestamp, new \DateTimeZone('UTC'));

    // Format the DateTime object to an ISO 8601 string in UTC
    $formattedDateTime = $dateTime->format('Y-m-d\TH:i:s');

    // Create the context with the formatted date time in UTC
    $context_definition = new ContextDefinition('string', $this->t('Current UTC date'));
    $context = new Context($context_definition, $formattedDateTime);

    $result = [
      'current_date' => $context,
    ];

    return $result;
  }

  /**
   * {@inheritdoc}
   */
  public function getAvailableContexts() {
    return $this->getRuntimeContexts([]);
  }

}

So now I can use just the '@rules.current_date_context:current_date' token in the 'Set a data value' Data selector. The time is saved in the database in UTC without timezone adjustments. Then when the Display is rendered with the site's timezone, it is the correct time that shows up.

I am just useful enough to get myself in trouble. So creating a patch is above me. I hope someone can make that happen. I will check back and create a new issue that is more direct if I need to.