5

I use the following code to create a node.

    $datetime = "2016-08-01 12:30:00";
    $values = array(
      'title' => $data['title'],
      'body' => $data['body'],
      'field_client' => $uid,
      'field_appointment_date_time' => $datetime,
      'type' => 'appointment'
   );

  $appointment = Node::create($values);
  $appointment->save();

The problem is that field_appointment_date_time (a Datetime field) is not been saved.

Why does this happen?

3 Answers 3

11

The above code is correct, date time was saved into DB. the problem is frontend.

frontend expected this format:

"2016-08-01T12:30:00", need a "T" as separator.

here is how to put that T as separator,

\DateTime::format("Y-m-d\Th:i:s"), need a escape character in-front of T.

2016-01-22 update:

By the way, I have found out in Drupal 8 , correct way to store datetime is follow:

1> first , find out current user timezone, \Drupal::currentUser()->getTimezone()

2> $given = new \Drupal\Core\Datetime\DrupalDateTime("2016-08-01T12:30:00",$user->getTimezone());

3> $given->setTimezone(new \DateTimeZone("UTC"));

4> then get back formated datetime string $given->format("Y-m-d\Th:i:s");
4
  • 3
    Use the DATETIME_DATETIME_STORAGE_FORMAT constant.
    – Berdir
    Commented Jan 21, 2016 at 22:25
  • For Date only use DATETIME_DATE_STORAGE_FORMAT Commented Jun 14, 2017 at 18:04
  • DATETIME_DATETIME_STORAGE_FORMAT is deprecated.
    – neuquen
    Commented May 10, 2019 at 19:42
  • 1
    @Keven Drupal now wants us to use: DateTimeItemInterface::DATETIME_STORAGE_FORMAT Commented Aug 31, 2019 at 22:22
4

I had the same problem, please try this

$dateTime = \DateTime::createFromFormat('Y-m-d','2000-01-30');
$newDateString = $dateTime->format('Y-m-d\TH:i:s');
$node = \Drupal\node\Entity\Node::create(array(
          'type' => 'article',
          'title' => 'The title',
          'langcode' => 'en',
          'uid' => 1,
          'status' => 1,
          'body' => array('The body text'),
          //'field_date' => array("2000-01-30"),
          'field_date' => $newDateString,
    ));
$node->save();

I've picked it from here:https://www.drupal8.ovh/en/tutoriels/64/create-a-node-date-field

I hope it helps you.

0

Since Drupal 8.5.x this works a little differently.

Firstly it's good practice to set the timezone explicitly so you know what is going on:

Set the timezone:

$timezone = new \DateTimeZone('UTC');
// Or
$timezone = new \DateTimeZone(date_default_timezone_get());
// Or 
$timezone = new \DateTimeZone(DateTimeItemInterface::STORAGE_TIMEZONE);

Then create the date object using the PHP DateTime class:

$date_time = new \DateTime('now', $timezone);
$drupal_date_time = DrupalDateTime::createFromDateTime($date_time);

Or the DrupalDateTime class:

$drupal_date_time = new DrupalDateTime('yesterday', $timezone);

I like to use DateTime (or DateTimeImmutable) and then pass into the DrupalDateTime wrapper. That way native methods are highlighted in the IDE and also date comparisons (e.g. $now > $somedatetime work reliably.

Prior to saving the date/time you must set the timezone to DateTimeItemInterface::STORAGE_TIMEZONE:

$drupal_date_time->setTimezone(new \DateTimeZone(DateTimeItemInterface::STORAGE_TIMEZONE))

You can then format the date for storage using the the DateTimeItemInterface::DATETIME_STORAGE_FORMAT constant:

$drupal_date_time->format(DateTimeItemInterface::DATETIME_STORAGE_FORMAT)

Here is an example based on above use case:

$datetime_string = "2016-08-01 12:30:00";

// Get the default timezone
$timezone = new \DateTimeZone(date_default_timezone_get());
// Or set the timezone explicitly to match the $datetime_string
$timezone = new \DateTimeZone('Europe/London');

// Create the DateTime object
$datetime = new \DateTime($datetime_string, $timezone);

// Optionally convert to DrupalDateTime if you need the custom methods, etc
$datetime = DrupalDateTime::createFromDateTime($datetime);

// Create and save the node
$node = Node::create([
  'type' => 'appointment'
  'title' => $data['title'],
  'body' => $data['body'],
  'field_client' => $uid,
  'field_appointment_date_time' => $datetime
    ->setTimezone(new \DateTimeZone(DateTimeItemInterface::STORAGE_TIMEZONE))
    ->format(DateTimeItemInterface::DATETIME_STORAGE_FORMAT),

]);

$node->save();

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.