Date mismatch in database when queried by node script - mysql

I have a node script that creates a date object, converts it into a string, console logs date and date as string and then inserts date string into a sql database fields of type DATE, DATETIME and TIMESTAMP. The database is on Windows 10 in XAMPP, local time is 2PM.
(async () => {
const fs = require("fs");
const mysql = require('mysql2/promise');
let date = new Date();
let dateString = date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate();
console.log("date: ", date);
console.log("datestring: ", dateString);
const connection = await mysql.createConnection(JSON.parse(fs.readFileSync("../test/databaseLogin.json")));
await connection.execute("INSERT INTO dates VALUES (?, ?, ?, ?)", [1, dateString, dateString, dateString]);
const selectResults = await connection.execute("SELECT * FROM `dates` WHERE mainKey = ?", [1]);
console.log("DB field of type DATE: ", selectResults[0][0].date);
console.log("DB field of type DATETIME: ", selectResults[0][0].datetime);
console.log("DB field of type TIMESTAMP: ", selectResults[0][0].timestamp);
connection.close();
})();
If I query the database from node process with mysql2 npm I get different result that says 24th instead of 25th.
Complete console output:
date: 2019-12-25T13:19:01.204Z
datestring: 2019-12-25
DB field of type DATE: 2019-12-24T23:00:00.000Z
DB field of type DATETIME: 2019-12-24T23:00:00.000Z
DB field of type TIMESTAMP: 2019-12-24T23:00:00.000Z
I don’t understand why there is a difference. Maybe some sort of localization issue? But the date was created in same locale as it was read.
Databse representation of data:
MariaDB [test]> SELECT * FROM dates;
+---------+------------+---------------------+---------------------+
| mainKey | date | datetime | timestamp |
+---------+------------+---------------------+---------------------+
| 1 | 2019-12-25 | 2019-12-25 00:00:00 | 2019-12-25 00:00:00 |
+---------+------------+---------------------+---------------------+
MariaDB [test]> describe dates;
+-----------+-----------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-----------+------+-----+-------------------+-----------------------------+
| mainKey | int(11) | NO | PRI | NULL | |
| date | date | NO | PRI | NULL | |
| datetime | datetime | NO | | NULL | |
| timestamp | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+-----------+-----------+------+-----+-------------------+-----------------------------+
MySQL converts TIMESTAMP values from the current time zone to UTC for storage, and back from UTC to the current time zone for retrieval. (This does not occur for other types such as DATETIME.) By default, the current time zone for each connection is the server's time. The time zone can be set on a per-connection basis. As long as the time zone setting remains constant, you get back the same value you store.
I think mysql2 npm does not support time zone config per connection.

I found the answer when visiting issues page of the mysql2 npm module.
To get the date string "as is" back form the database, I had to add the following connection settings: dateStrings: true. Full connection object looks now like so:
const connection = await mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'pass',
database: 'test',
dateStrings: true
});
Console output:
date: 2019-12-25T20:38:09.522Z
datestring: 2019-12-25
DB field of type DATE: 2019-12-25
DB field of type DATETIME: 2019-12-25
DB field of type TIMESTAMP: 2019-12-25

Related

mysql update datetime date with slashes

How to update DATETIME column in mysql
Tried using: (and many others)
I do not really care how the date is formatted in the database however need to be able to update the current row with the 01/01/2001 01:01 format
update contacts set replydate=STR_TO_DATE('1/9/2020 13:32', '%m/%d/%Y hh:mm') where id='3';
The date is not the current date, these are all different dates from a spread sheet, that all have the same formatting.
MariaDB [ddcontactsdb]> describe contacts;
+----------------+-----------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+-----------------+------+-----+-------------------+-----------------------------+
| replydate | datetime | YES | | NULL | |
+----------------+-----------------+------+-----+-------------------+-----------------------------+
You must use this format:
update contacts set replydate=STR_TO_DATE('1/9/2020 13:32', '%m/%d/%Y %H:%i') where id='3';
because m stands for month and i for minutes, also H for hour 00-23.

DBeaver: display datetime with milliseconds

This is MySQL 5.7 column:
`date` datetime(6) NOT NULL
I can see milliseconds using console:
mysql> select * from teq_log_1;
+----+----------------------------+-------+---------+---------+
| id | date | level | message | details |
+----+----------------------------+-------+---------+---------+
| 4 | 2019-08-01 12:23:34.123457 | 2 | test | NULL |
+----+----------------------------+-------+---------+---------+
but I cannot see milliseconds in DBeaver client:
There is format option for the date column (Right Click on date column / View/Format / Data Formats ...):
There are Date, Time, Timestamp & Number types (w/o Datetime). I set yyyy-MM-dd HH:mm:ss.sss & yyyy-MM-dd HH:mm:ss.mmm patterns but without result.
How can I display milliseconds/microseconds for datetime(6) in DBeaver (v. 6.1.3)?
Turning on Use native date/time format did it for me.
Using uppercase SSS as in yyyy-MM-dd HH:mm:ss.SSS shows milliseconds - you were using lowercase sss
Probably, this is a cache related issue. I recreated my tables and reconnect DBeaver. Now I see milliseconds in DBeaver client:
... and I see microseconds in mysql console (but the last 3 digits are "0" - unixtime was inserted, w/o microseconds):
mysql> select * from teq_log;
+----+----------------------------+-------+-
| id | date | level |
+----+----------------------------+-------+-
| 5 | 2019-08-01 11:10:27.247000 | 1 |
| 6 | 2019-08-01 11:10:27.259000 | 1 |
| 7 | 2019-08-01 11:10:27.636000 | 1 |
| 8 | 2019-08-01 11:10:27.713000 | 1 |
| 9 | 2019-08-01 11:10:27.758000 | 1 |
| 10 | 2019-08-01 11:10:31.768000 | 1 |
| 11 | 2019-08-01 11:10:32.300000 | 1 |
+----+----------------------------+-------+-
Using yyyy-MM-dd HH:mm:ss:S:Z in Timestamp under (for mac :: prefernces -> Editors -> Data Editor -> Data Formats ) helped me.
More on dBeaver documentation can be found here :: https://dbeaver.com/docs/wiki/Managing-Data-Formats/
Using "Datetime" instead of "Date" as data type worked for me.
My java time's variable was--> Date now = new Date(System.currentTimeMillis());
I saved the "now" variable in DBeaver as "Datetime" type and this is the result--> 2022-11-11 15:15:17.000

"Unknown column COUNTRY in field list" after dockerizing express.js app

I have this express.js application with a set of Mocha tests I run. At some point not long ago I dockerized the project. After dockerizing, it only half of my tests pass because due to mysql errors. To generate these SQL statements I use Bookshelf.js/Knex.js. I wont show all the tests because they all have a common problem.
The first test runs this code.
method.registerUser = (request, callBack) => {
let {
email,
username,
address,
city,
zip,
state,
password,
country,
} = request.body;
password = hashPassword(decrypt(password));
if(!testRegistration(request)) {
return callBack ({
success: false,
});
}
let insert = {
NAME: username,
PASSWORD: password,
EMAIL: email,
ADDRESS: address,
CITY: city,
ZIP: zip,
STATE: state,
COUNTRY: country,
};
User.forge(insert)
.save()
.then((user) => {
return callBack ({
success: true,
});
})
.catch(function (err) {
logger.log(err);
return callBack ({
success: false,
});
});
}
This is where it gives the User model to add a new user to the mysql database. The User model is defined by this json.
"database_test" : {
"client": "mysql",
"connection": {
"host": "DB",
"database": "TERRA_TEST",
"user": "root",
"port": "3306",
"password": "goon",
"charset": "utf8"
}
},
I have a series of migrations that run before every test and the outcome schema of the database looks like this.
+----------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| NAME | varchar(255) | YES | | NULL | |
| PASSWORD | varchar(255) | YES | | NULL | |
| EMAIL | varchar(255) | YES | | NULL | |
| ADDRESS | varchar(255) | YES | | NULL | |
| CITY | varchar(255) | YES | | NULL | |
| ZIP | varchar(30) | YES | | NULL | |
| STATE | varchar(255) | YES | | NULL | |
| COUNTRY | varchar(255) | YES | | NULL | |
+----------+------------------+------+-----+---------+----------------+
However when the test that executes that code to create a new user is run it fails and returns this error.
code: 'ER_BAD_FIELD_ERROR',
errno: 1054,
sqlMessage: 'Unknown column \'COUNTRY\' in \'field list\'',
sqlState: '42S22',
index: 0,
sql: 'insert into `USERS` (`ADDRESS`, `CITY`, `COUNTRY`, `EMAIL`, `NAME`, `PASSWORD`, `STATE`, `ZIP`) values (\'4909 Jean Manors\', \'New Parkerville\', \'Kiribati\', \'Matilde.Wiegand#hotmail.com\', \'Sarina_Anderson\', \'$2a$10$nsaL/4DyHquIlHKQOxjPiObBZJykbNlSZYCJCe0m3fREN4XD0c9o2\', \'Alaska\', \'01524\')' }
When I run this SQL code though in the mysql CLI it is applied without errors.
also, here is the DB section of the docker-compose
DB:
image: mysql:5.7
container_name: mysql
restart: always
environment:
- MYSQL_ROOT_PASSWORD=goon
- MYSQL_DATABASE=TERRA_TEST
- MYSQL_USER=tester
- MYSQL_PASSWORD=goon
- DATABASE_HOST=docker-mysql
ports:
- "3306:3306"
networks:
- web_sql_bridge
Would any of you have any idea why these errors are occurring and how to fix them? They started happening after dockerizing the project. Before it ran all the tests without errors?
If problems started after dockerizing, maybe you are actually running migrations to local database and running application against DB inside docker.
Anyways question doesn't have currently enough info about setup to give definitive answer. Please ping if you add more info to the question and I'll update the answer.
We need to know how are you running your dockerized setup. How are you running migrations. Do you have local mysql install and docker mysql server running at the same time. Are you stopping container at some point (thus loosing data setup by migrations). Basically complete code for reproducing your problem would be needed.

Mysql date warning data truncated

I'm having an interesting issue with Mysql DATE format.
I have this table :
| id | int(11) | NO | PRI | NULL | auto_increment |
| file_path | varchar(255) | YES | | NULL | |
| date_export | date | YES | | NULL | |
When i'm updating a row using the date function : NOW(), the date is updated with this format :
'2014-01-23'
But when i'm using another date format, like hand-written one like :
update backup_conf_allied set date_export='2014-23-01' where file_path='IDF-952584-SW1' ;
The date_export column transforms into :
'0000-00-00'
Warning table tells me that :
| Warning | 1265 | Data truncated for column 'date_export' at row 3628 |
Why? The date format is the same as NOW() function.
Thanks.
Posted query
update backup_conf_allied set `date_export='2014-23-01'` where file_path='IDF-952584-SW1' ;
What it should be
update backup_conf_allied set `date_export='2014-01-23'` where file_path='IDF-952584-SW1' ;
MySQL Support DATE format as 'YYYY-MM-DD' , Year then Month then Date, So you are updating a Date column with wrong value "2014-23-01" , There are only 12 months in year, you are using month 23 which is invalid that's MySQL is converting it to ZERO DATE (0000-00-00)
I had a similar problem recently, my issue was that I was trying to upload a datetime object as a date object. Although that's not the same issue that Gui O was having, if you run into this, make sure that you're actually trying to upload a date object.
I'm having this same problem but for a different reason. My MySQL column has a datetime type, but my datetime values are from Python, and they look like this: `'2021-04-01 03:58:50.088087'.
So the result is to truncate before the period:
t = t[0:19]
e.g.:
>>> datetime.datetime.now().isoformat()
'2021-04-03T08:28:41.602373'
>>> datetime.datetime.now().isoformat()[0:19]
'2021-04-03T08:28:44'
>>>

View hook only displays 1969 dates

I have a table that looks like:
+--------------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------------+-------------+------+-----+---------+-------+
| ProductsDownloadId | int(11) | NO | PRI | 0 | |
| RCContactID | int(11) | NO | MUL | NULL | |
| product_name | varchar(50) | YES | MUL | NULL | |
| download_date | timestamp | YES | | NULL | |
+--------------------+-------------+------+-----+---------+-------+
I'm writing a module for this table to be viewable in a Drupal 6 View.
I followed the example I found here:
http://drupalcontrib.org/api/drupal/contributions--views--docs--docs.php/function/hook_views_data/6
So I exposed the download_date as thus:
$data['products_downloaded']['download_date']=array(
'title'=>t("Download Date"),
'help'=>t("When Product was downloaded by the user"),
'field' => array(
'handler' => 'views_handler_field_date',
'click sortable' => TRUE,
),
'sort' => array(
'handler' => 'views_handler_sort',
),
'filter' => array(
'handler' => 'views_handler_filter_date',
),
);
But when I add it to a view, all the dates are displayed as "12/31/1969 - 19:33". And none of the dates in my table are:
EDIT: Corrected query:
mysql> select count(1) from products_downloaded where download_date <'2000-12-31 23:59:59.999999';
+----------+
| count(1) |
+----------+
| 0 |
+----------+
1 row in set (0.04 sec)
I also did a custom date format with the format 'r' in the View and I got
Wed, 31 Dec 1969 19:33:31 -0500 for all the dates.
So what did I do wrong on my module?
Your query:
select count(1) from products_downloaded where download_date <'12/31/2000 - 19:33'
Your problem here is that MySQL expects dates to be given in a different format to that.
You need to provide your dates in the following format:
'2007-12-31 23:59:59.999999'
(you can drop the microseconds, seconds, etc to get the precision you need as required)
So in your case, your query should look like this:
select count(1) from products_downloaded where download_date <'2000-12-31 19:33'
This should query the field correctly.
By the way -- If you have dates showing up unexpectedly as 1969, it implies that perhaps you've been using the wrong format in other queries as well. You may want to check that too.
See the MySQL manual page for date times: http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html
What I was able to determine was that PHP or Drupal wasn't able to understand whatever was being returned to the processor. I messed around with a custom hook and got the value to be accepted by the DateTime constructor. From there . . . it was easy to get the date formats back.