How to pass a DateTime from NodeJS Sequelize to MSSQL - javascript

I have a NodeJS project, and I am trying to pass an 'UpdateDate' field using Sequelize. I am receiving the error 'Conversion failed when converting date and/or time from character string'. I have tried passing a few different things:
Date.now()
new Date().toISOString()
Neither work. Am I missing something simple? I cannot change the column definition on the table. As far as I know, passing a string such as '2016-05-23 10:39:21.000' to a SQL DateTime field works in SSMS, but it seems to be an issue when using Sequelize and Node.
Thanks
Zach

This is caused by a known issue in Sequelize. The solution is to patch Sequelize's date to string format implementation, like explained here, so that all dates are handled properly. Below is the code that fixes the error.
const Sequelize = require('sequelize');
// Override timezone formatting for MSSQL
Sequelize.DATE.prototype._stringify = function _stringify(date, options) {
return this._applyTimezone(date, options).format('YYYY-MM-DD HH:mm:ss.SSS');
};

I figured this out, without changing the data type in the SQL database.
In my Model, I had my column defined as DataTypes.DATE, which, according to the Sequelize documentation, is the equivalent of a DateTime in SQL. However, this was throwing the error. When I changed the definition to DataTypes.STRING, and then added this:
var normalizedDate = new Date(Date.now()).toISOString();
normalizedDate now passes through to the DateTime column in SQL without a problem. The issue that I can tell, is Sequelize was adding a time zone to the Date before passing it. Such as, a date like:
'2017-11-01 16:00:49.349'
was being passed through as:
'2017-11-01 16:00:49.349 +00:00'
and it looks like SQL server does not like the '+00:00'.
I hope this helps others.

You can use this variable:
const timestamps = new Date() + 3600 * 1000 * 7;

I got the same issue. I was able to solve the issue by changing the model as follows.
ex:
create_at: {
type: 'TIMESTAMP',
defaultValue: new Date().toISOString(),
allowNull: false
},
update_at: {
type: 'TIMESTAMP',
defaultValue:new Date().toISOString(),
allowNull: false
}

Related

Validate both JS Date and Firestore Date with Joi

I'm currently discovering Joi library and - at this time - it's a great experience.
However, I'm facing a tiny problem I can't resolve. Help or advice needed!
Consider the following schema (a bit):
const workSchema = Joi.object({ timeline_created: Joi.date().allow(null).required()) }
It works perfectly fine when I submit a JS date (or null value).
However, I'm using Firestore which convert JS Date to this kind of object:
timeline_created: Timestamp { _seconds: 1637258607, _nanoseconds: 349000000 }
Thus, I can't validate my schema (it's not a date Joi knows).
Then, my question: how to write my schema (I want it to be strict/precise) but validating at the same time a JS Date and a Firestore Date.
Thanks
EDIT: I made some progress with:
timeline_created: Joi.object().keys({_seconds: Joi.number(),_nanoseconds: Joi.number()}).required()
It validates my Firestore object.
However, how could I also validate if timeline_created is null or a JS Date? Thx.
This is working:
Joi.alternatives([Joi.object().keys({ _seconds: Joi.number(), _nanoseconds: Joi.number() }), Joi.date(), null]).required()

How to convert JavaScript Date into PostgreSQL Time (no timezone)?

I use knex with PosgreSQL. I have a table with a Time column.
After trying to insert data in the table, knex throws an error with the following message:
...invalid input syntax for type time: \"2021-07-21T14:40:00.000+03:00\..."
Code example
await knex('table_name')
.insert({ id: 1, time: new Date() })
What is a correct way to preserve JavaScript Date object as a PosgreSQL Time? Should I use 3rd party libs? Or it can be done using knex only?
I was able to fix this issue by manually converting the JavaScript Date object into one of the supported formats of the PostgreSQL.
The 8.5.1.1. Dates and 8.5.1.2. Times chapters have a full list of supported types.
My solution was to use date-fns/format (e.g. format(new Date(), 'HH:mm') // 14:00)
P.S. I'm not sure if this approach is right but it works.

Mongoose only sorting dates by time

I am running a Node.JS server which uses Mongoose to query a MongoDB table that contains a date field. However, when I sort the results by date, they are actually only sorted by the time, disregarding the actual date. For example when I run the query
Competition.find({})
.sort('date')
.exec()
.then(data => {
res.json(data);
})
.catch(console.log);
It returns:
{"_id":"5c6c99e6e7179a27eb63a9a0","date":"2019-02-24T01:00:00.000Z","game_name":"UFO","status":"WAITING","comp_id":7},
{"_id":"5c6b95c8e7179a27eb62e7cf","date":"2019-02-19T06:41:47.185Z","game_name":"UFO","status":"COMPLETED","comp_id":6},
{"_id":"5c6b95b4e7179a27eb62e7cb","date":"2019-02-19T06:41:57.174Z","game_name":"UFO","status":"COMPLETED","comp_id":5},
{"_id":"5c6b95a4e7179a27eb62e7be","date":"2019-02-19T06:42:02.170Z","game_name":"UFO","status":"COMPLETED","comp_id":4},
{"_id":"5c6b9533e7179a27eb62e7a9","date":"2019-02-19T06:42:07.176Z","game_name":"UFO","status":"COMPLETED","comp_id":1},
{"_id":"5c6b958de7179a27eb62e7b8","date":"2019-02-21T18:48:50.497Z","game_name":"UFO_test","status":"COMPLETED","comp_id":3}
You can see here that the first entry has a date of 02-24 so it should show up last, but since the time is 1:00:00 it shows up before the other entries with the dates 02-19 and 02-21, since their times are later (06:41:47 for example).
The schema for the competition table is as follows:
const schema = new mongoose.Schema({
date: Date,
game_name: String,
status: String,
comp_id: Number,
});
I've tried to execute the date sort in a few different ways that Mongoose supports, but they all return the same results. If anyone could provide a fix or a workaround for this issue it would be greatly appreciated!
I had a similar problem and in my case, the dates were not saved as date in mongo like so:
"createdAt": {
"$date": "2018-04-25T22:48:06.863Z"
}
It could be related to the way you are creating your date object. Are you using moment or new Date() or anything else?

Problem with MongoDB's aggregate function, getting erromessage not understanding why

For school assignment, I've got to execute several MongoDB queries regarding specific problems related to Sales and their details. I'm now getting a problem I haven't encountered before, and being completly new to Mongo doesn't help.
I've been using Robo 3t to help me in the task, and I haven't been able to get anywhere, having tried multiple solutions. I also can't seem to find the problem online, hence me asking here.
So, the code is as it follows:
db.salesdetails.aggregate(
[
{
$project: {
month: { $month: "$OrderDate" },
year: { $year: "$OrderDate" },
store:{$toInt:"$Store"},
ReceiptID:1,
_id:0
}
},
{
$match: {
month: 05,
year: 2011,
store:1046
}
}
])
The expected output would be the Store(an integer, as noted), the month, year and the ID of the Receipt that fall into the specificed timeframe and store.
However, instead of returning it, I get the following error:
https://i.imgur.com/NIYnelc.png
Once I remove the "store:1046" on the match field, the aggregation is sucessful, and I don't have any idea why it is behaving like this.
Thanks in advance.
The error shows you use MongoDB date operators ($month and $year in this case) on a string type. Do a db.salesdetails.findOne() and post the result. I believe you have a string value in OrderDate field instead of a date (ISODate(...)) I have verified on both Compass and Robo 3T that your aggregate pipeline work if the data type is correct.

Creating Breeze.js query with DateTimeOffset fails

I am running Breeze.WebApi v1.2.5 and I am also having problems with querying DateTimeOffset types.
Here is my query:
var query = entityQuery.from('Sessions')
.where('startTime', ">", new Date(2013, 3, 19));
This generates
http://localhost/api/breeze/Sessions?$filter=StartTime%20gt%20datetime'2013-04-19T05%3A00%3A00.000Z'
Which throws an error.
However, if I manually change the above generated query to use datetimeoffset (instead of datetime) Like so:
http://localhost/api/breeze/Sessions?$filter=StartTime%20gt%20datetimeoffset'2013-04-19T05%3A00%3A00.000Z'
It queries correctly and returns the appropriate response.
How can I get breeze to generate the appropriate query with datetimeoffset, instead of datetime?
As of v 1.2.7, this has been fixed
--- previous post
Ok, I've repro'd this. We should have a fix in the next release. I will post back here when it is released. and thx for finding it.

Categories

Resources