How to insert a midnight datetime into mysql?

Asked

Viewed 552 times

2

I’m using the Laravel Framework 5.8, I am trying to register a record in the database where I need to set in API some dates.

Although they are CURRENT_TIMESTAMP, i also need to be able to enter a record defined by parameter through this API (in this table, I have 4 date fields: start, end, updated, created):

Here begins the problem:

The problem only happens when the date is midnight, ie: 00:00:00

First I tried to insert in the same American format, and gave the following error:

"SQLSTATE[22007]: Invalid datetime format: 1292 Incorrect datetime value: '2018-11-04 00:10:10' for column 'end' at Row 1 (SQL: Insert into Schools (scb_code, owner_id, name, cnpj, zipcode, neighborhood, city, state, phone, site, number, plan, start, end, access, address, guten_version, type, domain, scn_id) values (1, 2, Escola teste, 123, 123, Jardim Paulista, São Paulo, SP, (11) 123-123, http://www.xxx.com.br, 123, 14, 2018-05-04 15:46:39, 2018-11-04 00:10:10, ? , Al. Xyz, ? , 1, ?, ?))"

So I created a method for the date to convert to the format timestamp since it is a timestamp the field of the bank, I believed that it would solve the problem, but, it did not solve

Fail method:

public static function setFormatDateTimeToTimestamp($data, 
                                                    $fields = ['start', 
                                                               'end',
                                                               'created', 
                                                               'updated']
)
{
    if (count($fields)) 
    {
        foreach($fields as $field) 
        {
            if (isset($data[$field]) && 
                $data[$field] != null && 
                strrpos($data[$field], " 00:") !== false) 
            {

                $dt = \DateTime::createFromFormat('Y-m-d H:i:s', $data[$field]);
                if ($dt) 
                {
                   $data[$field] = $dt->getTimestamp();
                }
            }
        }
    }
    return $data;
}

Gave in the same, only different, the error still persists:

"SQLSTATE[22007]: Invalid datetime format: 1292 Incorrect datetime value: '1541290210' for column 'end' at Row 1 (SQL: Insert into Schools (scb_code, owner_id, name, cnpj, zipcode, neighborhood, city, state, phone, site, number, plan, start, end, access, address, guten_version, type, domain, scn_id) values (1, 2, Escola teste, 123, 123, Jardim Paulista, São Paulo, SP, (11) 123-123, http://www.xxx.com.br, 123, 14, 2018-05-04 15:46:39, 123, ? , Al. Santos, ? , 1, ?, ?))"

The table is in this format:

CREATE TABLE `Schools` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `scb_code` varchar(10) COLLATE utf8_unicode_ci DEFAULT NULL,
  `scb_code_owner` varchar(10) COLLATE utf8_unicode_ci DEFAULT NULL,
  `owner_id` int(11) NOT NULL,
  `name` text COLLATE utf8_unicode_ci NOT NULL,
  `cnpj` varchar(20) COLLATE utf8_unicode_ci NOT NULL,
  `zipcode` varchar(15) COLLATE utf8_unicode_ci NOT NULL,
  `neighborhood` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
  `city` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
  `state` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
  `phone` varchar(20) COLLATE utf8_unicode_ci NOT NULL,
  `site` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
  `number` varchar(14) COLLATE utf8_unicode_ci NOT NULL,
  `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `updated` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
  `plan` text COLLATE utf8_unicode_ci NOT NULL,
  `start` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
  `end` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
  `access` tinyint(2) DEFAULT NULL,
  `address` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `guten_version` varchar(5) COLLATE utf8_unicode_ci DEFAULT NULL,
  `type` tinyint(4) DEFAULT '0',
  `domain` varchar(300) COLLATE utf8_unicode_ci DEFAULT NULL,
  `scn_id` int(2) DEFAULT NULL,
  `disable_block_content_teacher` tinyint(4) DEFAULT '1',
  `external_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`ID`),
  KEY `fk_Schools_schools_base1_idx` (`scb_code`)
) ENGINE=InnoDB AUTO_INCREMENT=1589 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Now I don’t understand why through Mysql Workbench in a newer version I can insert the radius of the date in the format I want using a simple INSERT, but when I’m using the Laravel Framework, I have this problem, which actually seems to be a problem of MySQL and not of Laravel, or is the Laravel who’s sabotaging me in MySQL, someone knows what’s going on here?

That one documentation can perhaps answer the problem, but I still don’t understand what’s wrong. And this only happens when the month is 11.

  • 2

    My guess is it’s because of daylight savings. PHP and/or Mysql must be configured with a Timezone from Brazil, and on 11/04/2018, at midnight, the clocks were advanced by an hour, so every minute between 00:00 and 00:59 is skipped and does not exist in this Timezone. So 00:10:10 is an invalid date for this Timezone. The way is to change Timezone, or change to a valid time (01:10:10, for example) - ah yes, Timezone tb can be changed by connection (in addition to PHP and Mysql having their own configs)

  • Take the test with "2017-10-15 00:10:10" (it is also a day that there was a daylight saving time), if you give the same error it is probably because of Timezone Brazil itself. Behold this test, if you remove the set time_zone works (because SQL Fiddle is configured with UTC)

  • But daylight saving time doesn’t start in October?

  • 2018 was changed to November: news story - wikipedia - decree

  • All very strange, you report: O problema só acontece quando a data é meia-noite, ou seja: 00:00:00 and in error the date is 2018-11-04 00:10:10 that is, it is already a strange information of reporting errors. I ended up doing the test and did not give any error that date, missed you put your model on the question and how this data is really coming, is it possible to put? The Timezone influences in other aspects, but, in this no, because the complaint is the format has to see settings of this database

  • @Virgilionovic I did tests forcing the Timezone with set time_zone='America/Sao_Paulo' and the error occurs. When using another Timezone (such as UTC, or another that has no daylight saving time on this date), the error does not occur. What can happen is that the timezone information is not up to date in your case (It may still be with the old rule, because in 2017 daylight saving time starts in October, and only in 2018 was changed to November, but Mysql does not update automatically - test with '2018-10-21 00:10:10' just to see if this is it). Or you’re using another Timezone anyway...

  • @hkotsubo I did the two tests ... both my site and UTC, I did several tests and did not give any error, in my experience is MYSQL, but, I can not confirm!

  • @hkotsubo >>> App\TimesOf::create(['description' => 'Time 3', 'created' => '2018-10-21 00:10:10']);
=> App\TimesOf {#753
 description: "Time 3",
 created: "2018-10-21 00:10:10",
 id: 5,
 } wheel that is a beauty ... I think it is the database, these days I had a problem with Sqlserver (it records in Brazilian format and send the information in North American format, ie, a serious error of server configuration)

  • 1

    @Virgilionovic Actually I tested directly in Mysql, but anyway the problem must be in some config even (or in the bank, or in the connection)

  • I tested on another machine here with a newer Mysql and stopped giving problem, must be some configuration of the version of my Mysql: 5.7.25. I’m not even going to warm up with this anymore because Mysql in production is newer.

Show 5 more comments

2 answers

1

The problem of dates is very common. The problem usually comes from the fact that the server is not in your country. The solution but easy and put at the beginning of each page:

// Para todas as datas
date_default_timezone_set('America/Sao_Paulo');
// Para triagem e todas as funçoes de "string"
$ret = setlocale(LC_ALL, "pt_BR.utf-8");

After that, you need to think only "I’m in Brazil" and stop using a US format.

The other point comes from the kind you choose for the fields:

  • "end" is timestamp type. And "2018-11-04 00:10:10" is not a Time Stamp.

  • Please insert "2018-11-04 00:10:10" in a "date" field will insert "2018-11-04"

  • Please insert "2018-11-04 00:10:10" in a field type "datetime" will insert "2018-11-04 00:10:10"

  • Please insert "2018-11-04 00:10:10" into a "timestamp" field will give error.

Either you change the type of your field, or you turn the date into TimeStamp using mktime().

Just to put an additional info: if you try to record "2018-11-04 00:00:00" in a "date" field or in a "datetime" field the two cases will give the same result, because "2018-11-04 00:00:00 = 2018-11-04". The difference will be visible only with value type "2018-11-04 00:10:10" why "2018-11-04 00:10:10 != 2018-11-04". This may explain the confusion.

0

The problem has been solved. Mysql version 5.7.x does not have the incorrect Timezone from Brazil, correction:

SET @@global.time_zone = '+3:00';
QUIT
  • 1

    But then I disagree, Timezone in the bank should always be in GMT/"utc" and the application that uses the bank should compensate the schedule, after all if you have a daylight saving time (Daylight Saving Time) in a Brazilian state things will conflict, I understand that it can be a simple application and that it solves for you at the moment, but believe me, this is accumulating problems for the future. It seems to me your bank was correct, and saving correctly [...]

  • 1

    [...] what was WRONG is your app, which should know that downloaded in UTC and should apply the Timezone of Brazil (of its state) at the time of reading the database info, can do directly in the query or parse of the string that contains the date.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.