Mongoose or MongoDB removing 24 hours from date? - mongodb

I have to be doing something wrong but I cannot figure out what it is. I currently have a date field in my application that has a value format of MMMM, D YYYY.
For this example, I am going to be using the date October 1, 2018.
In the application, the user selects October 1, 2018 which logs as
October 1, 2018
Later I convert this date into a savable date by using var docDate = new Date($('#insuranceExpiration').val()).toISOString(); which logs as
2018-10-01T04:00:00.000Z
I then add this to an object stringify it and send it to the server where I log the date and shows as
2018-10-01T04:00:00.000Z
I then use Mongoose to save this date to MongoDB but when I go to see the saved date I show
2018-09-30T04:00:00.000Z
I cannot figure out for the life of me why I am seeing a date 24 hours in the past from the date I choose. Below is the mongoose code to see if I am doing something wrong on that end.
app.post('/api/myDocuments/insuranceGeneral', function(req, res ) {
console.log(req.body.expires);
// prints 2018-10-01T04:00:00.000Z
InsuranceGeneral.findOneAndUpdate({
_id: req.rsaConPortal.id
}, {
$set: {
"documents.insurance.name": req.body.name,
"documents.insurance.expires": req.body.expires,
"documents.insurance.url": req.body.url,
"documents.insurance.uploadDate": req.body.uploadDate
}
}, function(err, doc) {
if (err) throw err;
res.send('Success');
});
});
Even if I use a standard javascript date object I can print this on the browswer log
Mon Oct 01 2018 00:00:00 GMT-0400 (Eastern Daylight Time)
This prints on the sever just before mongoose
2018-10-01T04:00:00.000Z
But this is the end result in mongodb
2018-09-30T04:00:00.000Z

I think you and your server in different timezone. And mongodb uses GMT. If you are not declaring time in your iso date, it is setting it's time as 00:00.000Z. So for GMT this is one day earlier. Simply you should convert your date to GMT, you can use moment or you can fix problem by subtraction offset from date like this:
var offset = new Date().getTimezoneOffset() * 60000;
var date = new Date(new Date($('#insuranceExpiration').val())) - offset).toISOString();
or with moment.js
var date = moment($('#insuranceExpiration').val()).tz('GMT').format('YYYY-MM-DD');

Related

MongoDB trigger does not doing anything, even everything is right

i have a problem with mongoDB, im trying to create trigger, that will take server date and compare it with property DueDate and if the DueTime is lesser or equal of the server time, it should swap property borrowed to false.
Problem is that it didnt work and im so lost i tried everything.
There is my trigger function:
exports = function(changeEvent) {
const mongo = context.services.get("MongoDB");
const now = new Date();
const booksLended = mongo.db("test").collection("bookslendeds");
var filter = {DueDate: {$lt: now.toISOString()}, Borrowed: true};
var update = {$set: {Borrowed: false}};
console.log(JSON.stringify(filter));
console.log(JSON.stringify(update));
return booksLended.updateMany(filter, update);
};
This is a console logs:
> ran on Wed Jan 18 2023 23:48:10 GMT+0100 (Central European Standard Time)
> took 524.689137ms
> logs:
{"DueDate":{"$lt":"2023-01-18T22:48:11.778Z"},"Borrowed":true}
{"$set":{"Borrowed":false}}
> result:
{
"matchedCount": {
"$numberInt": "0"
},
"modifiedCount": {
"$numberInt": "0"
}
}
> result (JavaScript):
EJSON.parse('{"matchedCount":{"$numberInt":"0"},"modifiedCount":{"$numberInt":"0"}}')
DataModel
The datatype of the DueDate field is probably UTC datetime, while .toISOString() is returning a string. MongoDB query operators are type-sensitive, so these will not match.
Instead, use the date object directly in the query, like:
var filter = {DueDate: {$lt: now}, Borrowed: true};

how to get only day number from date in flutter

I am trying to get day from date, and date comes from the api response, api response look like this
"data": [
{
_id: 6116c2e12760f71630342604,
username: 'abc',
Date: '2021-08-13',
},
{
_id: 6119ba9162069c32ccdf11c3,
username: 'acv',
Date: '2021-08-15',
}
]
i am trying to do it like this
date=Response.data['data']['Date']); //if i get date here 2021-08-15
day=date.split('-') //then will split it [2021,08,05]
day=date[2] //and then will get the day 05
but it is not working, it sends this error
type 'String' is not a subtype of type 'int' of 'index'
when i print this line day=Response.data['data']['Date']); it send same error, it is not getting date, but when i print onResponse.data it prints the api response.
please help how to do this
If your date String is in standard ISO format, simply use DateTime.parse then you can get the day easily, it would also allow you to check that the date is valid (parse will fail if date is not valid, see documentation):
String dateStr = Response.data['data']['Date']);
DateTime dateObj = DateTime.parse(dateStr);
print(dateObj.day);
If this is a custom format, you could use DateFormat from intl package (documentation):
String dateStr = Response.data['data']['Date']);
DateTime dateObj = DateFormat('yyyy-MM-dd').parse(dateStr);
print(dateObj.day);
you should use date.split("-").last and actually your index is wrong it should be day=date[2]
Let's try or you will use day[2]
day=Response.data['data']['Date']); //if i get date here 2021-08-15
day=date?.split('-').last; //then will split [05]
print(day) //and then will get the day 05

.timeFormat(%b %Y) not giving me the right dates

I'm a beginner with d3.js. The goal for now is to take the date column from "2018-11-01" to "Nov 18".
The dates start from "2016-11-01" to "2020-08-01" and each date in between is only the first of each month.
For example:
"2016-11-01",
"2016-12-01",
"2017-01-01",
"2017-02-01",
"2017-03-01",
"2017-04-01",
"2017-05-01",
The code I've used is below:
var format = d3.timeFormat("%b %Y");
var data = d3.dsv(",", dsvPath, function (d) {
return {
//Year : getYear(new Date(+d.year,0,1)),
date: format(new Date(d.date)),
['Catan=count']:+d['Catan=count'],
['Dominion=count']:+d['Dominion=count'],
['Codenames=count']:+d['Codenames=count'],
['Terraforming Mars=count']:+d['Terraforming Mars=count'],
['Gloomhaven=count']:+d['Gloomhaven=count'],
['Magic: The Gathering=count']:+d['Magic: The Gathering=count'],
['Dixit=count']:+d['Dixit=count'],
['Monopoly=count']:+d['Monopoly=count']
//['Running Total'] : +d["running_total"]
};
}).then(function (data) {
console.log(data[0]);
minDate = d3.min(data,function(d){console.log(d); return d.date;});
maxDate = d3.max(data,function(d){console.log(d); return d.date;});
console.log(minDate);
However, for the minimum date, I get April 2017 instead of November 2016. The max date is May 2020 instead of September 2020.
When I read in the data as is without the data formatting, the minDate and maxDate are correct. As soon as I format, however, Oct 2016, which doesn't exist in the dataset, is somehow logged twice.
Furthermore, the data in the console stops at "July 2020": there's no August and Sept 2020. I'm honestly very puzzled.
Any help would be much appreciated!
Thank you!
Converting to a Date via the Date() constructor is notoriously tricky. Thankfully, since D3 gives us methods to go from a date to a string, it also has the reverse, going from a string to a date.
Our process will be twofold:
For each string in a certain format, convert to Date with d3.timeParse().
Convert each date to your desired string format.
(1.) (2.)
"2016-01-01" 🡒 Date<2016-01-01T00:0O> 🡒 "January 2016"
d3.timeParse d3.timeFormat
You already have (2.) in your code, so we need (1.):
var toDate = d3.timeParse("%Y-%M-%d");
var format = d3.timeFormat("%b %Y"); // (2.)
var data = d3.dsv(",", dsvPath, function (d) {
return {
date: format(toDate(d.date)),
};
})

ngx-bootstrap datepicker output format is not ISO format

The default output format of ngx-bootstrap datepicker is not ISO format as documented.
I would welcome this format but the actual format that I get is:
Sun Aug 02 2020 19:17:00 GMT-0400 (Eastern Daylight Time)
Stackblitz Example
I know there are ways to post process the format but this format seems weird for a default output format. Does anyone have experience with this?
In vanilla JavaScript there is a 'Date' object, the default output of which gives you the line you are seeing:
Sun Aug 02 2020 19:17:00 GMT-0400 (Eastern Daylight Time)
In physical memory, your Date object is actually being stored as the number of milliseconds since "January 1, 1970, 00:00:00" which using our above line is actually "1596410220000" milliseconds.
You can read the full specifications for the 'Date' object here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Numbers_and_dates
Meanwhile, to answer your question more specifically, your date picker is not giving the output you listed but instead applying its date to a 'Date' object (newDate). You are then setting another 'Date' object (updatedDate) to be equal to the Date object assigned by your date-picker (newDate).
This is done here:
onValueChange(newDate: Date) {
this.updatedDate = newDate;
}
So in memory your updatedDate is now represented as "1596410220000" milliseconds. When you output that 'Date' object to your HTML your browser is going to use the default output for the 'Date' object, giving you:
Sun Aug 02 2020 19:17:00 GMT-0400 (Eastern Daylight Time)
So there are two solutions that you can use if you want to get that Date into a different format.
First you can call a method on your newDate to return a different formatted string. For example, if we wanted to output it as the ISO string that you were looking for originally we change this:
export class AppComponent implements OnInit {
myDateValue: Date;
updatedDate: Date;
ngOnInit() {
this.myDateValue = new Date();
}
onValueChange(newDate: Date) {
this.updatedDate = newDate;
}
To this:
export class AppComponent implements OnInit {
myDateValue: Date;
updatedDate: String;
ngOnInit() {
this.myDateValue = new Date();
}
onValueChange(newDate: Date) {
this.updatedDate = newDate.toISOString();
}
First we changed "updatedDate" to be a string object and we called the method "toISOString()" on our "newDate" (which is the Date returned from our date-picker). This gives us the ISO formatted string, which for our example is:
2020-08-02T23:17:00.000Z
The other option is to simply apply formatting to your date in your angular DatePipe. For example, if we change this:
</div>
Updated Date: {{updatedDate}}
</div>
To this:
</div>
Updated Date: {{updatedDate | date:"shortTime"}}
</div>
We would be applying the shortTime format which is "h:mm a" or for our example:
7:17 PM
You can read the full list of angular date formats here: https://angular.io/api/common/DatePipe
To summarize:
Vanilla JavaScript (not angular or ngx-bootstrap) is controlling the output format for the "Date" object here. While the output looks weird, the variable itself is not stored in that format but in milliseconds (UNIX epoch time). You can call methods on a Date object to get various formats (including ISO, UTC, etc) or you can format from angular by passing a format command along the datepipe.

Comparing Date elements return wrong results - Swift

I'm focusing on developing an app which deals with Date objects. I'm facing a problem related to comparing 2 Date object, I think I've identified the issue but can't really figure out a solution.
Consider the following:
extension Date{
func nextDay(distance: Int = 1) -> Date {
return Calendar.current.date(byAdding: .day, value: distance, to: self)!
}
}
func generateTask(forProjects: [Project]){
for project in forProjects {
if tasks(forProject: project).isEmpty{
var startDate = Date()
var currentMilestone : Task = project.mostRecentMilestone
var indexMilestone : Int = 0
while startDate < project.lastMilestone.day!{ // Suppose last milestone differs 20 days from startDate
print("StartDate: \(startDate), Current: \(currentMilestone.day!)")
// Something
startDate = startDate.nextDay()
}
}
else {
print("Tasks already present")
}
}
DB.shared.save()
}
}
lastMilestone.day has been produced by this code:
lastMilestone.day = Date().nextDay(distance: 20)
Some clarification: Project is a structure which contains a day: Date attribute and Task is another object which contains the same attribute.
Suppose I'm incrementing the date by 1 day for every while cycle. The expected result would be:
StartDate: 2020-05-20 11:07:52 +0000, Current: 2020-06-09 11:07:49 +0000
StartDate: 2020-05-21 11:07:52 +0000, Current: 2020-06-09 11:07:49 +0000
StartDate: 2020-05-22 11:07:52 +0000, Current: 2020-06-09 11:07:49 +0000
...
StartDate: 2020-06-08 11:07:52 +0000, Current: 2020-06-09 11:07:49 +0000
*EXIT LOOP*
whereas I get
StartDate: 2020-05-20 11:07:52 +0000, Current: 2020-06-09 11:07:49 +0000
StartDate: 2020-05-21 11:07:52 +0000, Current: 2020-06-09 11:07:49 +0000
*EXIT LOOP*
Which means that comparision fail the second time. I've tried changing the code in this way:
//...
startDate = startDate.addingTimeInterval(3600*24)
//...
Which holds same result as before.
I'm starting to think this is related to TimeZone settings, or maybe the fact that compareDate is fetched from an entity contained in CoreData.
As regards my first thought, I saw it is possible to setup the Calendar.current timezone manually but when I try to do it, I get a read-only error, which seems reasonable to me.
Any idea?
EDIT: Since I've verified that this code works on a clean project, I'm aware that I have to be more specific. Updated accordingly.
EDIT 2: As requested, here is the value of Date for lastMilestone.day
print("StartDate: \(startDate), Current: \(project.lastMilestone.day!)")
OUTCOME:
StartDate: 2020-05-20 17:59:48 +0000, Current: 2020-06-09 17:59:47 +0000
Just for reference, I want to leave a solution to my question, which now I see could not be infered by it.
As I stated, the problem was linked to Core Data and my organisation of models.
In specific, Task entity was manipulated in the //Something part, but I didn't noticed that a particular relationship in Core Data model would influence the value of task stored in project.
To be more clear, the structure of my app is the following:
Task could be a normal task or a milestone. They held the same meaning, yet I know see they need to be 2 separate concept. In fact, both of them share a relationship with project, and project just take a reference of milestone. Yet, they share the same inverse relationship. This lead probably to a manipulation of day attribute of Task that invalidated the while loop in the answer.
The solution was to separate entities and remove the inverse relationship.
I'm really sorry for the poor accuracy in my question, I should have included an explaination of the problem in more detail.