Why JS saves difference date in storage? - javascript

I have variable formValuesChanged that contains the following data:
Then I save this data to storage:
sessionStorage.setItem("filters", JSON.stringify(formValuesChanged));
Then if explore session storage I see this object but with different date:
{ classNumber: 2
classSuffix: 5772436057100
date: "2018-09-23T21:07:47.043Z"
teacher: 25203
type: "teacher"
}
Why does JS save wrong date?

There is no date type in the JSON format, it is a bit of a pain but if you want to store a date in a string format you will need to parse it when you read it back.
let obj = JSON.parse(sessionStorage.getItem("filters"));
let objWithDate = { ...obj, date: new Date(obj.date) };

Related

Inconsistent string to date conversion in Mongoose

Model:
const fooSchema = new mongoose.Schema({
fooCreationDate: {
type: Date
},
bar: [{
barCreationDate: {
type: Date
}
}]
});
const foo = mongoose.model(`foo`, fooSchema);
If we want to search for foo objects that were created between 2022-01-01 and 2022-01-02, we can use the following mongoose query:
foo.find({
fooCreationDate: {
$gte: "2022-01-01T00:00:00.000",
$lt: "2022-01-02T00:00:00.000"
}
});
Please note that I'm using strings instead of date objects. The reason is that the query is passed by the client through an AJAX call with dataType: "jsonp". Every date object that is passed like that to the backend is automatically converted to an ISO string. Despite that, the query works without any issues - the find function automatically parses dates represented as ISO strings.
We'd now like to extract every bar object that was created in the same time range, so we'll need to use an aggregation:
foo.aggregate([{
$unwind: `$bar`,
}, {
$match: {
"bar.barCreationDate": {
$gte: "2022-01-01T00:00:00.000",
$lt: "2022-01-02T00:00:00.000"
}
}
}]);
Unfortunately, nothing is found despite the fact that the database contains matching bar objects. This can be confirmed by passing Date objects instead of strings to the $match aggregation:
foo.aggregate([{
$unwind: `$bar`,
}, {
$match: {
"bar.barCreationDate": {
$gte: new Date("2022-01-01T00:00:00.000"),
$lt: new Date("2022-01-02T00:00:00.000")
}
}
}]);
This query returns some results, so the conclusion is that mongoose accepts ISO date strings in the find function, but can't handle them in the aggregate function.
Is there any known workaround? I could, for example, deep-scan every query object passed from the client and search for ISO date strings, then convert them to Date objects, but that's a bit dirty in my opinion. I'm using mongoose v5.6.4 and mongodb v4.2.2.

How to get current date/time using database timezone in sequelize

I need to get the current time, according to the database timezone (not my local timezone, and not default UTC timezone), using Sequelize. Is there a Sequelize method to do this?
My database is in Eastern time, and when I query the db directly SELECT CURRENT_TIMESTAMP; it returns the date/time in Eastern time (which is correct).
But when I query via Sequelize in Node const [[{time}]] = await db.sequelize.query('SELECT CURRENT_TIMESTAMP AS time'); it returns the date/time in UTC.
Two problems:
1 - I would prefer using a Sequelize method instead of a raw query.
2 - This still doesn't get me the result I want. The time needs to be Eastern.
This is my DB setup:
const sequelize = new Sequelize(dbUrl, {
dialectOptions: {
useUTC: false // for reading from database
},
timezone: '-04:00', // for writing to database
define: {
charset: 'utf8'
}
})
As mentioned above, when I query using the above queries, the date is always returned in UTC, which I did not expect, given I said useUTC: false. How do I get it in Eastern time (the database timezone)?
I'm not aware of a sequelize method like getCurrentDate().
The UTC conversion problem seems to bite everyone (myself included). Here are some details. Not sure if dialectOptions: {useUTC: false }, has any function at all - just adding the typeCast method solved the problem for me.
dialectOptions: {
typeCast: function (field, next) { // for reading from database
if (field.type === 'DATETIME') {
return field.string()
}
return next()
},
The result can be used for a new js Date object:
const sql = 'select current_timestamp';
my_app.my_DB.query(sql, {raw: true, type: Sequelize.QueryTypes.SELECT})
.then(data => {
console.log(data[0].current_timestamp);
let d1 = new Date(data[0].current_timestamp);
});
This works fine for me - but make sure to test thoroughly!
Add useUTC property in your dialectOptions like this
dialectOptions: {
encrypt: false ,
options: {
useUTC: false, // for reading from database
},
},

nodejs unable to parse date with momentjs

I am trying to parse some csv data, however, I am not able to parse date with momentjs library.
var csv = require('csv-parser');
var fs = require('fs');
var moment = require('moment');
const bittrexDateFormat = "MM/DD/YYYY hh:mm:ss a";
var count = 0;
fs.createReadStream('orders.csv')
.pipe(csv({
headers: ['OrderUuid', 'Exchange', 'Type', 'Quantity', 'Limit', 'CommissionPaid', 'Price', 'Opened', 'Closed']
}))
.on('data', function(data) {
var createDate = moment(data.Opened, bittrexDateFormat);
console.log(createDate.toDate());
});
And the csv data looks like;
OrderUuid,Exchange,Type,Quantity,Limit,CommissionPaid,Price,Opened,Closed
24245deb-134c-4da7-990e-8d22d8fd728c,BTC-STRAT,LIMIT_SELL,77.12739479,0.00087503,0.00016874,0.06749952,12/24/2017 12:09:20 AM,12/24/2017 12:09:21 AM
And this the output;
0002-01-02T09:00:02.000Z
On the other hand, if I directly hardcode the date string I am able to get Date object.
var createDate = moment("12/24/2017 12:09:20 AM", bittrexDateFormat);
console.log(createDate.toDate());
Another thing I figured out is if I print data in event .on('data') it prints encoded string version
Row {
OrderUuid: 'O\u0000r\u0000d\u0000e\u0000r\u0000U\u0000u\u0000i\u0000d\u0000',
Exchange: '\u0000E\u0000x\u0000c\u0000h\u0000a\u0000n\u0000g\u0000e\u0000',
Type: '\u0000T\u0000y\u0000p\u0000e\u0000',
Quantity: '\u0000Q\u0000u\u0000a\u0000n\u0000t\u0000i\u0000t\u0000y\u0000',
Limit: '\u0000L\u0000i\u0000m\u0000i\u0000t\u0000',
CommissionPaid: '\u0000C\u0000o\u0000m\u0000m\u0000i\u0000s\u0000s\u0000i\u0000o\u0000n\u0000P\u0000a\u0000i\u0000d\u0000',
Price: '\u0000P\u0000r\u0000i\u0000c\u0000e\u0000',
Opened: '\u0000O\u0000p\u0000e\u0000n\u0000e\u0000d\u0000',
Closed: '\u0000C\u0000l\u0000o\u0000s\u0000e\u0000d\u0000\r\u0000' }
Row {
OrderUuid: '\u00002\u00004\u00002\u00004\u00005\u0000d\u0000e\u0000b\u0000-\u00001\u00003\u00004\u0000c\u0000-\u00004\u0000d\u0000a\u00007\u0000-\u00009\u00009\u00000\u0000e\u0000-\u00008\u0000d\u00002\u00002\u0000d\u00008\u0000f\u0000d\u00007\u00002\u00008\u0000c\u0000',
Exchange: '\u0000B\u0000T\u0000C\u0000-\u0000S\u0000T\u0000R\u0000A\u0000T\u0000',
Type: '\u0000L\u0000I\u0000M\u0000I\u0000T\u0000_\u0000S\u0000E\u0000L\u0000L\u0000',
Quantity: '\u00007\u00007\u0000.\u00001\u00002\u00007\u00003\u00009\u00004\u00007\u00009\u0000',
Limit: '\u00000\u0000.\u00000\u00000\u00000\u00008\u00007\u00005\u00000\u00003\u0000',
CommissionPaid: '\u00000\u0000.\u00000\u00000\u00000\u00001\u00006\u00008\u00007\u00004\u0000',
Price: '\u00000\u0000.\u00000\u00006\u00007\u00004\u00009\u00009\u00005\u00002\u0000',
Opened: '\u00001\u00002\u0000/\u00002\u00004\u0000/\u00002\u00000\u00001\u00007\u0000 \u00001\u00002\u0000:\u00000\u00009\u0000:\u00002\u00000\u0000 \u0000A\u0000M\u0000',
Closed: '\u00001\u00002\u0000/\u00002\u00004\u0000/\u00002\u00000\u00001\u00007\u0000 \u00001\u00002\u0000:\u00000\u00009\u0000:\u00002\u00001\u0000 \u0000A\u0000M\u0000' }
I am pretty new to nodejs but I don't think the problem occurs from either momentjs or csv-parser libraries. Instead it should be string format of stream api nodejs. Thanks a lot.
I just ran your code, and it worked just fine.
Try updating your node version or try invoking the function with
fs.createReadStream('orders.csv', 'utf16le')
the encoding should make the difference...
https://nodejs.org/api/fs.html#fs_fs_createreadstream_path_options

Put json string into a javascript variable json

I have this in my console chrome:
[{"id":40,"endDate":"2017-04-22","dataA":"2017-04-19","nrC":2,"type":"CO","dataD":"2017-04-19","startDate":"2017-04-20"},{"id":40,"endDate":"2017-04-26","dataA":"2017-04-26","nrC":4,"tyoe":"CP","dataD":"2017-04-23","startDate":"2017-04-25"},
This json string is comming from the servlet that calls DAO class to take the information from db.
So, this string is (dynamically) passed into a jsp page from request session...and i put it into var DAYS = '${jsonArrayString}'; then console.log(DAYS); then it prints that json string above.
So...it can print more data then two.
It has to be put into a javascript variable loke this:
var DAYS = '${jsonArrayString}'; //That's what's on my console..and it comes from session into this jsp page
I think it has to be iterated through a foreach and print it in that format.
var USER_DAYS = [
{
id: value from jsonArrayString,
date: value from jsonArrayString,
title: value from jsonArrayString,
start: new Date(value from jsonArrayString),
end: new Date(value from jsonArrayString),
allDay: true,
className: 'done'
},
];
I tried to put the values ​​manually and it works...like this:
var USER_DAYS = [
{
id: 1,
date: '2017-04-05',
title: 'CO',
start: new Date(2017, 3, 5),
end: new Date(2017, 3, 7),
allDay: true,
className: 'done'
},
I don't know hot to put the values from that json string(
Which can be anythong ... more than 2 records)...that why I need to iterate through that json string.
I want the values to be put only in that format, in that variable (var USER_DAYS)
I tried somthing like this, but it does't work:
<c:forEach items="${jsonArrayString}" var="jsonArrayString">
{
id: '${jsonArrayString.nrC}' ,
date: '${jsonArrayString.dataD}' ,
title: '${jsonArrayString.type}' ,
startDate: '${jsonArrayString.startDate}',
endDate: '${jsonArrayString.endDate}',
allDay: true,
className: 'done'
},
</c:forEach>
];
or like this:
var USER_DAYS = [
{
id: DAYS.nrC,
date: DAYS.dataD,
title: DAYS.type,
start: new Date(DAYS.startDate),
end: new Date(DAYS.endDate),
allDay: true,
className: 'done'
},
];
How to do this?
try parse to json string into json objects.
Example
var USER_DAYS = JSON.parse('${jsonArrayString}')
JavaScript code runs only on the client side, while JSP on the server. You cannot iterate over the JavaScript variable while the page is rendered at the server.
If you want to serve a page that already contains the data, you should pass the data to the JSP page as a model attribute. To do this, take a look at this post.
If you want to populate the page with data after it has been loaded to the browser, you have to use a JavaScript library, such as jQuery. In this case, you have to send a request to the server to get the data in JSON format, and then you can manipulate them on the client side.

formatting bound property in javascript before it is displayed

I'm trying to format a JSON date to a JavaScript date to display it in a nice way. The original date comes from a JSON-object, which looks like this:
{
"name": "foo",
"num": "1",
"date": "\/Date(1367539200000)\/"
}
The place where the JSON elements should be displayed later is a SAPUI5 object header:
objectHeader = new sap.m.ObjectHeader({
title: "{/name}",
number: "{/num}",
attributes: [
new sap.m.ObjectAttribute({
text: "{/date}"
})
]
});
Since the JSON object is bound to the object header via
dataModel.setData(json)
objectHeader.setModel(dataModel)
the values are correctly substituted. But i want to have the date correctly formatted to a more readable format instead of seeing /Date(1367539200000)/ on my website. I tried with
new sap.m.ObjectAttribute({
text: new Date(parseInt("{/date}".substr(6))).toLocaleString('de');
})
But that failed with an 'Invalid Date'. What would be the right syntax to format the JSON date to a Javascript data object in a model binding?
You can use a formatter to do that for you. The advantage is that you can properly use databinding, so your controls will be updated automatically in case the model changes.
new sap.m.ObjectAttribute({
text: {
parts: [
{path: "/date"}
],
formatter: function(date){
//do whatever you want
return /* the value you want to have as result */;
}
}
})

Categories