How to keep date from client saved in MongoDB as date? - angularjs

I'm using Node.js and Angular.js for a web project. I understand that date is saved as date if it's created on server using new Date() (e.g. 2015-04-08 04:15:18.712Z shown in Robomongo as Date type). However, if the date is created on client using new Date(), it is then saved as a string (e.g. 2015-04-07T04:58:12.771Z shown in Robomongo as String type), because it becomes a string through node API. How to make it save as a Date instead of String?
UPDATE:
This is what I got based on Jason Cust's input. In node's server.js specify the reviver option as follows:
app.use(bodyParser.json({ reviver: function(key, value) {
if ( typeof value === 'string' && value.length === 24) {
if (value.match(/^\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d.\d\d\dZ$/)){
return new Date(value);
}
}
return value;
}}));
This will automatically converts all date strings to date objects when data is sent from client to server.
If you want to do the same thing for the Angular.js client, I found a good blog by Andrew Davey Automatic JSON date parsing with AngularJS

I am going to assume you are using JSON to send the date from your Angular app to your Node app. The JSON spec doesn't reconstitute a Date object so you will have to do it yourself first before inserting it into MongoDB.
Example:
// simulate JSON from HTTP request
var json = JSON.stringify({date: new Date()});
console.log(json);
// outputs: '{"date":"2015-04-08T04:50:04.252Z"}'
var obj = JSON.parse(json);
console.log(obj);
// outputs: { date: '2015-04-08T04:50:04.252Z' }
// reconstitute Date object
obj.date = new Date(obj.date);
console.log(obj);
// outputs: { date: Wed Apr 08 2015 00:50:04 GMT-0400 (EDT) }

Related

How to enable Time Zone support for ASP.NET Core API?

I've got a mobile app and a Web application that consumes an ASP.NET Core 3.x WEB API that uses SQL Server as it's datastore. The client applications can be in different Time Zones.
The dilemma I'm facing is filtering records with a date range.
For instance, I've got a table called 'PaymentTransaction' that consists of a column 'TransactionDateTime' that is of type DateTimeOffset.
Entity object:
[Table("PaymentTransaction")]
public class PaymentTransaction
{
public DateTimeOffset TransactionDateTime { get; set; }
}
API endpoint for creating the records: PaymentRequestDto content excluded for brevity
[HttpPost, Route("Create")]
public async Task<ActionResult> Create([Required] PaymentRequestDto)
{
await _context.PayoutTransactions.AddAsync(new PaymentTransaction()
{
TransactionDateTime = DateTimeOffset.UtcNow;
});
await _context.SaveChangesAsync();
return Ok();
}
API endpoint for filtering the records:
[HttpGet, Route("GetRangeSample/{startDateTime}/{endDateTime}")]
public async Task<ActionResult> GetRangeSample([Required] DateTimeOffset startDateTime, [Required] DateTimeOffset endDateTime)
{
var result = await _context.PaymentTransactions.Where(x => x.TransactionDateTime >= date && x.TransactionDateTime <= date).ToListAsync();
return Ok(result);
}
JavaScript Client requesting filtered records;
var startDate = new Date();
var endDate = new Date();
endDate.setDate(endDate.getDate() + 7)
$.ajax({
type: "get",
url: "http://localhost:55724/api/GetRangeSample",
data:{
startDateTime: startDate,
endDateTime: endDate
},
success: function(response){
console.log(response);
},
error: function(error)
{
console.log(error);
}
});
If I'm to filter records for a given date range, let's say 02-21-2022 to 02-28-2022. some records are not returned.
What am I doing wrong? How do you normally go about saving a DateTimeOffset and retrieving records based on a date filter?
Presuming you mean to have the user select entire days in their time zone, the issue is in the way you've created the start and end dates in your JavaScript code. Keep in mind that a JavaScript Date object represents a point in time (not a whole date), and that new Date() gives the point in time that is now.
Thus, you should probably create your start and end dates like this instead, so they are inclusive of the entire day rather than just the remainder of the day after the time ran the code.
var startDate = new Date(); // get the current "now"
startDate.setHours(0,0,0,0); // adjust to the start of the local day
var endDate = new Date(startDate); // copy to another instance
endDate.setDate(endDate.getDate() + 7); // advance 7 days

Receiving an incorrect time in SQL

I'm interested in getting a full date in SQL this way 2021/02/02 20:12:36
And the date is kept in such a way 2021/02/02 00:00:00
On the server side I get a correct date like this 2021/02/02 20:12:36
On the client side I get this way 2021/02/02 03:00:00
This is the format I get in React
I don't know why:(
Maybe here's the problem
const FormatDate = (date) => {
try {
console.log(date);
return format(date, "yyyy/MM/dd hh:mm:ss");
} catch (e) {
return "";
}
};
I think this is error of browser auto add offset at client
You can try this code to show right time at client
new Date(DATE_REPONSE_FROM_SERVER).getTime() - new Date().getTimezoneOffset() * 60 * 1000
But you need add offset at server if you send this time to server
Other way, I this you convert time to string and response this string
Hope this help for you

How to extract JSON object in a Google Apps Script web app?

Can someone point out why this function would not work?
function doPost(e) {
var contents = JSON.parse(e.postData.contents);
var data = JSON.stringify(contents,null,4);
var x = data["inboundSMSMessageList"];
var y= x.inboundSMSMessage[0].senderAddress;
GmailApp.sendEmail("sample.email#gmail.com", "test5", y);
}
It takes an event listener, e, parses its contents and then stringily the contents using JSON.parse() and JSON.stringify() respectively. This is a sample stringified data:
var data = {
"inboundSMSMessageList": {
"inboundSMSMessage": [
{
"dateTime": "Sun Jan 03 2021 01:25:03 GMT+0000 (UTC)",
"destinationAddress": "tel:21585789",
"messageId": "5ff11cef73cf74588ab2a735",
"message": "Yes",
"resourceURL": null,
"senderAddress": "tel:+63917xxxxx"
}
],
"numberOfMessagesInThisBatch": 1,
"resourceURL": null,
"totalNumberOfPendingMessages": 0
}
}
The script seems to fail on the second to the last line (var y); but when I run it on the sample data, I'm able to access the key and value pair Im targeting- which is the sender address (it sends "tel:+63917xxxxx: to my email). Anybody has an idea why it's failing when it's ran as a web app?
I thought that in your script, var contents = JSON.parse(e.postData.contents); can be used as the parsed object. I thought that the reason of your error is due to that the object is converted to the string by var data = JSON.stringify(contents,null,4). So how about the following modification?
From:
var contents = JSON.parse(e.postData.contents);
var data = JSON.stringify(contents,null,4);
To:
var data = JSON.parse(e.postData.contents);
In this modification, y is tel:+63917xxxxx.
Note:
When you modified the script of Web Apps, please redeploy the Web Apps as new version. By this, the latest script is reflected to the Web Apps. Please be careful this.

Angular resource converting Date object into String while fetching data

I am using Angular resource for ajax operations in my project. I have some date fields i am converting them into JavaScript Date() Object at server when i am fetching the data, i am using Node js (Express js ) at server side. At client side i require this date object for uib datepicker. My Server code for date conversion is:
findAndFormatDate: function (data) {
Object.keys(data).forEach(function (key) {
if (key.indexOf("date") !== -1 || key.indexOf("Date") !== -1) {
data[key] = new Date(data[key]);
if (data[key] instanceof Date) {
console.log("Yes it is a date, and the type is ", typeof data[key]);
}
}
});
return data;
}
and at server console i am getting the message Yes it is a date, and the type is object, but when i am getting this data at client side and checking the typeof this date field then it is showing string and i need to again convert it at client side then it is working properly, i am not able to understand why it requires two time conversion, i want to convert in only at server side so how can i avoid the conversion at client side?

Get error when I try to pass date value in URL to web api method

I create this date variable in client side:
this.latestDate = new Date(2001, 1, 1,1,1,1,1);
Here how it looks in client watch:
self.latestDate: Thu Feb 01 2001 01:01:01 GMT+0200 (Jerusalem Standard Time)
here is angularjs service that I use to asyncroniusly call my web api method:
$http.get(serviceUrl + "?date=" + self.latestDate);
And here is the web api method that I call from cilent:
[HttpGet]
public HttpResponseMessage GetByDate(DateTime date){}
But each time I call for web api method above, I get this error on cilent:
<Error>
<Message>The request is invalid.</Message>
<MessageDetail>
The parameters dictionary contains a null entry for parameter 'date' of non-nullable type 'System.DateTime' for method 'System.Net.Http.HttpResponseMessage GetByDate(System.DateTime)' in 'SensorObservation.Web.SensorsDataController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
</MessageDetail>
</Error>
Any idea why I get the error above?
First, doing this is a really bad idea:
$http.get(serviceUrl + "?date=" + self.latestDate);
A URL is a structured text format; it has formatting rules that must be followed. When you dump unstructured text into a structured format by using simple string concatenation, you are likely to be breaking some of those rules. I would recommend using the jQuery param function for this.
Second, you are serializing the date to a string using the default format, which is the one you see in the client watch. This may or may not work on the server. A better bet is to serialize using a well known format such as ISO 8601. I would recommend using the JavaScript date toISOString function for this.
Applying these changes, your API call code would look something like this:
var query = jQuery.param({ date: self.latestDate.toISOString() });
$http.get(serviceUrl + "?" + query);
Update
I ran a quick test since I was in my WebAPI code already, and you can create and use an endpoint with a DateTime parameter as long as the URL is formatted correctly.
My test endpoint looks like this:
[HttpGet]
[Route("test/datetest")]
public HttpResponseMessage DateTest(DateTime d)
{
HttpResponseMessage response = new HttpResponseMessage();
response.Content = new StringContent(d.ToString(), Encoding.UTF8, "text/plain");
return response;
}
It echoes the date back as expected.

Resources