1

I have a module to import nodes with a date/time field. All times are correctly written into the database. But when I view a node or in node/edit I get the time +1 h. In Drupal I have set the timezone to Berlin, which is GMT +1 h. When I change the timezone, the time in node/view/edit is not changing.

I don't know what to do to see the correct times in nodes.

  • Can you give an example of a date/time, before import, how it is stored in the database and then displayed. – 4k4 Dec 1 '18 at 13:32
  • I have an import file. In this file I have a date and a time in separate fields. The time field looks like '15:00 Uhr' (without apostrophe, 3 pm in German). After import I get it in DB as '2018-11-06T15:00:00' (also without apostrophe). The date is correct. In node view or edit I then I get '06.11.2018' (date, looks good) and '16:00:00' (time). But this should be 15:00:00. – deelite Dec 1 '18 at 16:29
2

Looks like a classic "off-by-one" error. You should make sure that you are storing all date stamps in the UTC format.

Read the section on "Converting to and from UTC" here: https://www.drupal.org/node/291799

If the date/time field is storing the German time (UTC+1h) then it will end up adding another +1h when it localizes the time, and you'll end up one hour ahead.

"There are two hard things in computer science: cache invalidation, naming things, and off-by-one errors."

UPDATE: As you say in your comment below, you can get the desired result by simply subtracting 1h from each datestamp in order to convert from Berlin time to UTC.

However, this approach will only work if you are certain that the time field in the import file will always contain UTC+1 times.

If you ever need to import files that could be in different time zones, you'll need to follow the API.

To convert a local date back to UTC to store it in the database, do:

$date = // local date value
$local_zone = // the name of the local timezone, e.g., 'Europe/Berlin'
$type = // the type of date value, DATE_DATETIME, DATE_ISO, or DATE_UNIX

$date = date_make_date($date, $local_zone, $type);
date_timezone_set($date, timezone_open('UTC'));

// $date now contains the UTC value of the date.
// Output it like:

print date_format_date($date, 'custom', 'm/d/Y H:i');

In order to generalize your database import, you would also need to include a field for the $local_zone for each timestamp.

It sounds like you will always be importing Berlin timestamps, but I just wanted to make sure that you understood the drawbacks to simply subtracting 1h from each timestamp rather than following the API.

Even if simply subtracting 1h works for you in this case, there is value to doing this the right way, in case you ever need to import a file from another timezone, or one with mixed timezones -- either in your current project, or a future one.

  • 1
    I think I see my problem: manually creating such a node with a time 15.00 writes 14.00 into DB. So Drupal converts the time to UTC. Which means that I need to import the times converted to UTC or simply -1h. – deelite Dec 2 '18 at 11:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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