I am trying to fetch the date value from a mysql server but when i printed the result;System gives an error.
In the code I can fetch the date value but when i printed it;It does not get printed correctly.(I tried to fetch a row with the value 2003-10-20 but i get 2003-10-19T21 when i printed it).
var dob_fetcher = "SELECT DOB_value FROM users WHERE Name_value='resname'";
var dob_fetcher_2 = dob_fetcher.replace("resname", req.session.name_session);
server.query(dob_fetcher_2, function (error, dob_result, fields) {
if (error) {
throw error;
} else {
var dob_value = JSON.stringify(dob_result[0]);
console.log(dob_result[0]);
}
});
JavaScript is adjusting for your local time zone which appears to be 3 hours behind UTC.
You can access the non time zone shifted values with the getUTC methods:
getUTCDate()
getUTCDay()
getUTCFullYear()
getUTCMonth()
Finally, you may want to consider a date library like Luxon which has a lot more options for handling time zones and formatting dates than what is built into JavaScript.
Related
I am spotting some weird behavior in my Google Sheets / Apps Script. May be someone has already encountered this and have a solution?
I already checked my Spreadsheet Locale and Timezone setting to ensure that this setting is the same as timeZone setting in Google Apps Script.
appsscript.json file:
{
"timeZone": "Asia/Ho_Chi_Minh",
"dependencies": {},
"exceptionLogging": "STACKDRIVER",
"runtimeVersion": "V8",
"webapp": {
"executeAs": "USER_DEPLOYING",
"access": "ANYONE_ANONYMOUS"
}
}
I am pulling data from sheet log and use this data for a GET Endpoint from Apps Script.
A
B
1
Date
Some data
2
16/07/2022
2.34
3
17/07/2022
1.18
4
18/07/2022
4.16
My script:
function doGet(e) {
try {
const sh = SpreadsheetApp.getActive().getSheetByName('log')
const data = sh.getDataRange().getValues()
return ContentService
.createTextOutput(JSON.stringify({ success: true, data }))
.setMimeType(ContentService.MimeType.JSON)
} catch (e) {
return ContentService
.createTextOutput(JSON.stringify({ success: false }))
.setMimeType(ContentService.MimeType.JSON)
}
}
This script will be deployed as a Webapp then Google will provide me with a link. When I do a GET request to this Webapp link, this is what I received:
{
"success": true,
"data": [
[
"Date",
"Some data"
],
[
"2022-07-15T17:00:00.000Z",
2.34
],
[
"2022-07-16T17:00:00.000Z",
1.18
],
[
"2022-07-17T17:00:00.000Z",
4.16
]
]
}
When I read data from cell A2 on sheet log with
function test() {
const sh = SpreadsheetApp.getActive().getSheetByName('log')
const data = sh.getRange('A2').getValue()
Logger.log(data)
}
The result is:
Sat Jul 16 00:00:00 GMT+07:00 2022
I expect the date return from Apps Script Endpoint should be the same as date on sheet, but it is different. Am I missing something here?
I am currently using getDisplayValues to "pin down" the date as displayed on sheet and receive this date as string.
Updates:
Thank you all for your valuable time and information on this subject. With this information, I am able to switch from using getDislayValues() to getValues() to retain the underlying date value. And then after that in my internal system, I will process to local time accordingly. Example code in Python using arrow package:
import arrow
s = '2022-07-15T17:00:00.000Z'
arrow.get(s, 'YYYY-MM-DDTHH:mm:ss.SSSZ').to('local').format('DD/MM/YYYY')
or in JavaScript:
const s = '2022-07-15T17:00:00.000Z'
new Date(s).toLocaleDateString('vi-VN')
Sat Jul 16 00:00:00 GMT+07:00 2022 and 2022-07-15T17:00:00.000Z are the same date in different timezone. JSON doesn't support timezones or date formats and they use Z zero offset ISO8601 format to format them as strings. MDN says
The instances of Date implement the toJSON() function by returning a string (the same as date.toISOString()). Thus, they are treated as strings.
The timezone is always zero UTC offset, as denoted by the suffix "Z".
Yes, you are missing something.
Logger.log doesn't parse as string a Date object the same way that JSON.stringify does. Considering this, in order to make it easier to compare the output of your first script with the second, instead of
function test() {
const sh = SpreadsheetApp.getActive().getSheetByName('log')
const data = sh.getRange('A2').getValue()
Logger.log(data)
}
use
function test() {
const sh = SpreadsheetApp.getActive().getSheetByName('log')
const data = sh.getRange('A2').getValue()
Logger.log(JSON.stringify(data)) // Edited
}
In order to log the same value that is displayed on a Google Sheets cell, the easier way is, when reading the cell value(s), instead of using getValue / getValues use getDisplayValue / getDisplayValues.
Date objects are tricky beasts. As far as I can tell in this case the dates you're taking from the sheet have internally GMT+0 timezone always. If you want to show them somewhere with another timezone you have to do it directly: to get the wanted timezone (from the curren Spreadsheet, for example) and convert the date object into a string with this timezone. Something like this:
function get_date() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh = ss.getActiveSheet();
var tz = ss.getSpreadsheetTimeZone();
var date_obj = sh.getRange('a2').getValue();
var date_str = Utilities.formatDate(date_obj, tz, 'YYYY-MM-dd');
Logger.log(date_str);
}
For anyone who doesn't want to deal with JS / timezone complexities and want to keep as much of the problem on the Google Sheet, here is a simple trick.
Imagine that on one cell you have the date. As the cell knows it is a date, when you click on it a calendar will appear.
Somewhere else you format that date as you wish (this could be done in the initial cell as well, but on my case I need it with 2 formats, so 2 cells).
Now here is the trick. If on the cell that your App Script will read you specify
Format > Number > Plain Text
When App Script reads that cell it will read text and not a date. So you App Script data will have exactly what you expect, that is, what you see on the sheet.
Note: The cell in orange has the formula =TEXT(D5;"yyyy-mm-dd")
I query a dateTime object from PostgreSQL DB using an AJAX call which returns the following format:
2019-12-13T22:59:59Z // print type of: `undefined`
I now want to compare the timestamp of that object with the current time now and fire a function if the timestamp is not older than 5 seconds compared to the current time.
My idea is to calculate the difference in seconds and check the result for <> 5.
But how can I convert the database fetched dateTime object into a moment object to be able to compare them?
Edit:
Due to the conclusions from the comments provided, I changed my logic and end up with the following problem:
I have a timestamp in SQL which changes secondly. I fetch this timestamp with AJAX and would like to fire a function if the new timestamp is not older than 5 seconds than the previous one.
I set up moment.js objects to calculate the difference. Now my problem is that on the first iteration latestTick is not defined.
How can i design the loop that it compares both timestamps and always updates the latestTick with the lastTick for the next iteration (and also won't error on the first iteration)?
Javascript:
Ajax call...
[...]
lastTick = response[0].fields.account_lastTick.toString()
lastTick1 = lastTick.slice(0, 10)
lastTick2 = lastTick.slice(11, 19)
lastTick = lastTick1 + ' ' + lastTick2
lastTick = moment(lastTick, 'YYYY-MM-DD hh:mm:ss')
if ((lastTick.diff(latestTick, 'seconds')) != 0) {
console.log('not Zero')
} else {
console.log('Zero')
}
latestTick = moment(lastTick, 'YYYY-MM-DD hh:mm:ss')
[...]
To give you an idea on how to compare time in Moment.js. you can do this
import moment from "moment"
const dateTimeStr = "2019-12-13T22:59:59Z" // your DB already includes timezone in the response (UTC+00:00)
const dateTimeMoment = moment(dateTimeStr)
const next5MinsMoment = moment().add(5, 'minutes')
if(dateTimeMoment.isBefore(next5MinsMoment)) {
// fire function call
}
On my Node.js project I need to give query Date parameter which should be startOf current hour in local time. for example, if current local time is 2019-11-13T16:34:43.000, I should give date parameter as 2019-11-13T16:00:00.000.
For the reason I can't figure out, query accepts date only and only with New Date() function. No moment() or nothing else. I'm creating the date with moment() and then update it's hour by startOf('hour') and by format functions. The issue I live here is that, when I give this date to New Date() function inside query, New Date() function converts it to UTC time. I need my date in query to be executed as local time(Turkey Time - GMT+03:00).
const DriverPlan = analysisDB.collection('driverplans');
const nowDate = moment().startOf('hour');
console.log('nowDate: ', nowDate);
console.log('Unformatted: ', nowDate.valueOf());
const localDate = moment(nowDate).format('YYYY-MM-DDTHH:mm:ss.SSS');
console.log('localDate: ', localDate);
const courierPlans = new Promise((resolve, reject) => {
driverPlan.find({ startDateL: new Date(localDate) }).toArray((err, result) => {
if (err) {
return reject(err);
}
resolve(result);
});
});
and here is my console after the code block executed.
nowDate: moment("2019-11-13T16:00:00.000")
Unformatted: 1573650000000
localDate: 2019-11-13T16:00:00.000
So when I pass this localDate variable (which is my local time) to New Date() function inside query, Date function converts it to UTC.
In your case, I assume that all your date are given in utc because the process is running on a utc timezone machine.
I would look at https://momentjs.com/timezone/
This is useful because it accounts for the day-light saving.
var moment = require('moment-timezone');
// Create a moment with the current date
const now = moment();
//Convert to wanted timezone
now.tz('Europe/Istanbul').startOf('hour').toDate()
I would suggest using moment().toDate() instead of new Date(). This will ensure that you are using the same moment object. Unfortunately, the date object will always display in the timezone of the process.
It is possible to set the timezone via an env variable
process.env.TZ. This can be fragile depending on the usage.
Currently I have an app that's making a rest call to the SharePoint api that gives me the last modified date, and then I am comparing that date to a date that I currently have stored as a tag in content control inside a word doc. Currently I am using the New Date() method to try and compare the two dates, however I am getting two different times. Both these date times are in UTC but formatted different.
The DateTime that I am getting from SharePoint is in this format: 2016-08-27T17:40:09Z
The DateTime stored in a Content Controls tag: 8/27/2016 5:40:09 PM
Current Code:
for (var x = 0; x < contentControls.items.length; x++) {
itemUrl = "https://*tenant*.sharepoint.com/sites/*site*/_api/web/Lists/GetByTitle('*list*')/items?select=Title,Title&$filter=Title eq '" + contentControls.items[x].title + "'";
$.ajax({
type: "GET",
async: false,
url: itemUrl,
headers: {
"Authorization": "Bearer " + sharepointToken,
"accept": "application/json;odata=verbose"
},
success: function (data) {
var sharepointDateTime = data.d.results[0].Modified;
var contentControlDateTime = contentControls.items[0].tag;
var test1 = new Date(sharepointDateTime);
var test2 = new Date(contentControlDateTime);
if (test1 != test2) {
// custom code
}
},
error: function (error) {
console.log("Fetching list from SharePoint failed.");
}
})
}
Desired Result
I would like to be able to compare two dates in my condition statement, and if they are different I am going I am going to do something inside my statement. VERY Important this can not be dependent on the users current time Zone. I am comparing UTC Time
Update
I have solved this by altering the api which is stamping the content controls. I am working in a time crunch so I could not really dwell much on this. What I saw was that the content control tags were not stamped with the time zone so it was comparing apples and oranges. However, I would like to leave this question open to see if some one can find a client side solution instead.
You are comparing object references of two date objects with each other using !=, not points of time. While the objects may represent the same point of time, the condition will always be true.
Instead you could compare the timestamps of the two dates as number values, which you can retrieve using valueOf():
test1.valueOf() != test2.valueOf()
Also note that the second date does not contain any time zone information, so it will be interpreted in the local time zone of the environment the code is executed in. This may lead to unexpected results.
You may want to look into Moment.js, which is the de-facto standard library for date handling in JavaScript and which offers a much more consistent and intuitive API for your use case.
I'm dealing with two entities, Appointments and Expenses. My goal is for a new Expense record to auto populate some its fields when the date of the expense is specified, onChange. It triggers a query that's supposed to return records that have the same date and owning user.
Here is my code:
function bringData()
{
var date = Xrm.Page.getAttribute("new_tripDate").getValue();
var owner = Xrm.Page.getAttribute("ownerid").getValue();
if (owner != null)
{
var ownerID = owner[0].id;
var ownerName = owner[0].name;
}
var fetchXml="<fetch mapping='logical'>"+"<entity name='appointment'>"+"<attribute name='regardingobjectid'/>"+"<filter>"+"<condition attribute = 'ownerid' operator='eq' value='"+ownerID+"' />"+"<condition attribute='scheduledstart' operator='on' value='"+date+"' />"+"</filter>"+"</entity>"+"</fetch>";
var retrievedAppointments = XrmServiceToolkit.Soap.Fetch(fetchXml);
if (retrievedAppointments.length == 0)
{
alert("No matching records were found.");
return;
}
else
{
console.log(retrievedAppointments);
}
}
It gets the date from the current Expense page and uses it for the query. However, the function gives me an error on change saying that the date "is invalid, or outside the supported range". I removed the date condition from the query and it returns records based on the owning user no problem. I figured the problem was that there is a specified time in the Appointment entity and not on the Expense date but I thought using the "on" condition operator would fix that issue. I'm at a loss.
Thanks
The date time format returned by Xrm.Page.getAttribute("new_tripDate").getValue() is something that fetch cannot handle, you need to convert it to an ISO Format at the bare minimum.
Change the date formatting by using ISOFormat method, or use a library like moment.js or come up with your own little helper function to return a properly formatted date string.
Replace your date variable with the following:
var date = new Date(Xrm.Page.getAttribute("new_tripDate").getValue()).toISOString();