mysql

Datetime-value's time inserted incorrectly in one column but not in another MYSQL


I have a mysql database where im inserting data that has a "StartTime" and "EndTime". The EndTime is inserted correctly, but the StartTime has its Time sifted by -1 hour. I checked the Mysql logs that the actual "insert" command has the correct values, but when inspecting the table, or reading to other software the "StartTime" value is -1 hour off. (But not the "EndTime")

This happens on multiple different tables in the same Schema. Allways on the "StartTime"-value. The date columns are "datetime"-type (both)

What could be causing this?

If I change the values with each other IT STILL changes the "StartTime"-value (that is now going in to the "EndTime"-column), but not the "EndTime"-value (that is now going to the "startTime-colum".)

For example:

INSERT INTO sessionData.sessionHistory (sesConsump,sesTagId,sesDevice,sesStartDate,sesEndDate,sesId,sesCost)
VALUES (37232,'AABBCCDD','Station01','2024-10-14 15:13:11.486+03:00','2024-10-15 07:39:33.742+03:00','U01SQ5QH0JFAJ6SL',558.4819)

This will result in:

sesConsump sesTagId sesDevice sesStartDate sesEndDate sesId sesCost
37232 AABBCCDD Station01 2024-10-14 14:13:11 2024-10-15 07:39:34 U01SQ5QH0JFAJ6SL 558.4819

Table create statement:

CREATE TABLE `sessionHistory` (
  `sesId` varchar(16) NOT NULL,
  `sesConsump` int DEFAULT NULL,
  `sesTagId` varchar(16) DEFAULT NULL,
  `sesDevice` varchar(45) DEFAULT NULL,
  `sesStartDate` datetime DEFAULT NULL,
  `sesEndDate` datetime DEFAULT NULL,
  `sesCost` float DEFAULT '0',
  PRIMARY KEY (`sesId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

Mysql-server global.time_zone = +02:00


Solution

  • Data type datetime by default is datetime(0). A value of 0 signifies that there is no fractional part.
    When literal value like '2024-10-15 07:39:33.742+03:00' converted to datetime, the rounded value differs from the initial value:
    '2024-10-15 07:39:33+03:00'<>'2024-10-15 07:39:34+03:00'
    In this case no warning or error is given when such rounding occurs,
    and timezone part of literal is ignored.

    To resolve this behaviour You can

    1. Use datetime(6) for datetime column with fraction part of seconds.
    2. Or Set 'TIME_TRUNCATE_FRACTIONAL'.
    3. Or Truncate fractional part before insert
      '2024-10-15 07:39:33.742+03:00'->'2024-10-15 07:39:33.000+03:00'

    Doc

    See
    Example1. Your case.

    create table test (id int,first datetime DEFAULT NULL
      , second datetime DEFAULT NULL, third datetime DEFAULT NULL);
    insert into test values
     (1,'2024-10-15 10:00:00.123000+02:00'
       ,'2024-10-15 11:00:00.499000+02:00'
       ,'2024-10-15 11:00:00.501000+02:00')
    ;
    select * from test;
    
    id first second third
    1 2024-10-15 08:00:00 2024-10-15 09:00:00 2024-10-15 11:00:01

    Example2. All right:

    create table test2 (id int,first datetime(6) DEFAULT NULL
      , second datetime(6) DEFAULT NULL, third datetime(6) DEFAULT NULL);
    insert into test2 values
     (1,'2024-10-15 10:00:00.123000+02:00'
       ,'2024-10-15 11:00:00.499000+02:00'
       ,'2024-10-15 11:00:00.501000+02:00')
    ;
    select * from test2;
    
    id first second third
    1 2024-10-15 08:00:00.123000 2024-10-15 09:00:00.499000 2024-10-15 09:00:00.501000

    Example 3. All right:

    SET @@sql_mode = sys.list_add(@@sql_mode, 'TIME_TRUNCATE_FRACTIONAL');
    
    create table test3 (id int,first datetime DEFAULT NULL
      , second datetime DEFAULT NULL, third datetime DEFAULT NULL);
    insert into test3 values
     (1,'2024-10-15 10:00:00.123000+02:00'
       ,'2024-10-15 11:00:00.499000+02:00'
       ,'2024-10-15 11:00:00.501000+02:00')
    ;
    select * from test3;
    
    id first second third
    1 2024-10-15 08:00:00 2024-10-15 09:00:00 2024-10-15 09:00:00

    fiddle