I have a field in my database which states the timezone of the user. It is an integer field so anything > 0 is a + hour.
I need to display two separate times on the users screen
e.g.
Your time is: "just get the current computer time"
The other users time is: "get the current computer time then either add or subtract hours based on the database record"
I can do the database side of things I just need help with the Javascript element. For demonstration purposes I am happy for you to hard code the offset
The time must update automatically every 60 seconds to reflect the new minute and hour
Thanks
You can just set the hours on the date object in JavaScript. For example:
var date = new Date();
date.setHours((new Date()).getHours() - 5);
It will also try and be clever and make adjustments for you, as MDN says:
If a parameter you specify is outside of the expected range, setHours
attempts to update the date information in the Date object
accordingly. For example, if you use 100 for secondsValue, the minutes
will be incremented by 1 (min + 1), and 40 will be used for seconds.
You can use setInterval to perform the update. Here's a more complete example:
setInterval(function() {
var local = new Date();
var remote = new Date();
remote.setHours(local.getHours() - 5);
$('#time-local').html(local.toGMTString());
$('#time-ny').html(remote.toGMTString());
},1000);
Related
I'm working on a program that takes input from a user for a time. The program will take the information and automatically generate a Unix Timestamp using the current date as the date in the timestamp.
For example:
Daniel wants to generate a Unix Timestamp for 8:30 AM on Christmas
Day. He runs a command /unix 8:30, and the console prints out
1640421000.
What's the best way to achieve this? I understand how to generate a Unix Timestamp, but how do I edit just the time to the user input. Any help would be greatly appreciated.
You can create a Date for the current date, set the time as required, then generate a time value in seconds.
If the user will always enter H:mm and you don't need to validate the input, then the following will do:
let time = '8:30';
let tv = new Date().setHours(...(time.split(/\D/)), 0) / 1000 | 0;
// Check value
console.log(new Date(tv * 1000).toString());
However, the input should be validated (e.g. hours 0-23, minutes 0-59).
I just went with the following:
const time = interaction.options.getString('time');
const date = new Date().toISOString().slice(0, 10);
console.log(Math.round(new Date(`${date} ${time}:00`).getTime()/1000));
Seems to work for me.
I want to run a query in mongo which will get data till 7:00 am, then 7 am to 11 am and then 12 pm to 4 pm of particular that day only. Now these time are stored in different timezone. So I want to know how get data from mongo.
I tried using momentJs to get the the time range but not able to get correct timezone.
var dayStart = moment().zone(timezone).startOf('day');
var now = moment().zone(timezone);
var duration = moment.duration(now - dayEnd);
and my mongo query is
db.CollectionName.find({"created_at": {
'$gte': dayStart,
'$lt': now
}});
I want the three result seperately that is till 7am, 7am-11am & 12pm-4pm. Any help please.
I would still advise against using moment().zone() - at the very least use moment().utcOffset() as it more clearly communicates the approach of the function. However, since you are using .zone() now I will share an example to get you started.
We assume the following:
when a record is saved to your database, the created_at value defaults to UTC
you are the only user of concern
you are located in the Kolkata timezone and when you say 7am, you expect it to be relative to that location on earth
Using the zone feature, you would then need to a value of -330 to translate from UTC to Kolkata. (Since Kolkata is UTC+5:30, we must convert to minutes and then subtract that value 5 * 60 + 30 = 330.)
Given all of that, your values will be as follows:
var dayStart = moment().utc().zone(-330).startOf('day');
var now = moment().utc().zone(-330);
var duration = moment.duration(now.diff(dayStart)).as('minutes');
you had a few typos in your example: dayEnd was an undefined variable, I assumed you meant to use dayStart. also, duration needs to use diff and an argument to format the output, I have used minutes for this example.
You can test further and play around with this example:
https://jsfiddle.net/dusthaines/48wubezy/5/
I'm trying to get from a time formatted Cell (hh:mm:ss) the hour value, the values can be bigger 24:00:00 for example 20000:00:00 should give 20000:
Table:
if your read the Value of E1:
var total = sheet.getRange("E1").getValue();
Logger.log(total);
The result is:
Sat Apr 12 07:09:21 GMT+00:09 1902
Now I've tried to convert it to a Date object and get the Unix time stamp of it:
var date = new Date(total);
var milsec = date.getTime();
Logger.log(Utilities.formatString("%11.6f",milsec));
var hours = milsec / 1000 / 60 / 60;
Logger.log(hours)
1374127872020.000000
381702.1866722222
The question is how to get the correct value of 20000 ?
Expanding on what Serge did, I wrote some functions that should be a bit easier to read and take into account timezone differences between the spreadsheet and the script.
function getValueAsSeconds(range) {
var value = range.getValue();
// Get the date value in the spreadsheet's timezone.
var spreadsheetTimezone = range.getSheet().getParent().getSpreadsheetTimeZone();
var dateString = Utilities.formatDate(value, spreadsheetTimezone,
'EEE, d MMM yyyy HH:mm:ss');
var date = new Date(dateString);
// Initialize the date of the epoch.
var epoch = new Date('Dec 30, 1899 00:00:00');
// Calculate the number of milliseconds between the epoch and the value.
var diff = date.getTime() - epoch.getTime();
// Convert the milliseconds to seconds and return.
return Math.round(diff / 1000);
}
function getValueAsMinutes(range) {
return getValueAsSeconds(range) / 60;
}
function getValueAsHours(range) {
return getValueAsMinutes(range) / 60;
}
You can use these functions like so:
var range = SpreadsheetApp.getActiveSheet().getRange('A1');
Logger.log(getValueAsHours(range));
Needless to say, this is a lot of work to get the number of hours from a range. Please star Issue 402 which is a feature request to have the ability to get the literal string value from a cell.
There are two new functions getDisplayValue() and getDisplayValues() that returns the datetime or anything exactly the way it looks to you on a Spreadsheet. Check out the documentation here
The value you see (Sat Apr 12 07:09:21 GMT+00:09 1902) is the equivalent date in Javascript standard time that is 20000 hours later than ref date.
you should simply remove the spreadsheet reference value from your result to get what you want.
This code does the trick :
function getHours(){
var sh = SpreadsheetApp.getActiveSpreadsheet();
var cellValue = sh.getRange('E1').getValue();
var eqDate = new Date(cellValue);// this is the date object corresponding to your cell value in JS standard
Logger.log('Cell Date in JS format '+eqDate)
Logger.log('ref date in JS '+new Date(0,0,0,0,0,0));
var testOnZero = eqDate.getTime();Logger.log('Use this with a cell value = 0 to check the value to use in the next line of code '+testOnZero);
var hours = (eqDate.getTime()+ 2.2091616E12 )/3600000 ; // getTime retrieves the value in milliseconds, 2.2091616E12 is the difference between javascript ref and spreadsheet ref.
Logger.log('Value in hours with offset correction : '+hours); // show result in hours (obtained by dividing by 3600000)
}
note : this code gets only hours , if your going to have minutes and/or seconds then it should be developped to handle that too... let us know if you need it.
EDIT : a word of explanation...
Spreadsheets use a reference date of 12/30/1899 while Javascript is using 01/01/1970, that means there is a difference of 25568 days between both references. All this assuming we use the same time zone in both systems. When we convert a date value in a spreadsheet to a javascript date object the GAS engine automatically adds the difference to keep consistency between dates.
In this case we don't want to know the real date of something but rather an absolute hours value, ie a "duration", so we need to remove the 25568 day offset. This is done using the getTime() method that returns milliseconds counted from the JS reference date, the only thing we have to know is the value in milliseconds of the spreadsheet reference date and substract this value from the actual date object. Then a bit of maths to get hours instead of milliseconds and we're done.
I know this seems a bit complicated and I'm not sure my attempt to explain will really clarify the question but it's always worth trying isn't it ?
Anyway the result is what we needed as long as (as stated in the comments) one adjust the offset value according to the time zone settings of the spreadsheet. It would of course be possible to let the script handle that automatically but it would have make the script more complex, not sure it's really necessary.
For simple spreadsheets you may be able to change your spreadsheet timezone to GMT without daylight saving and use this short conversion function:
function durationToSeconds(value) {
var timezoneName = SpreadsheetApp.getActive().getSpreadsheetTimeZone();
if (timezoneName != "Etc/GMT") {
throw new Error("Timezone must be GMT to handle time durations, found " + timezoneName);
}
return (Number(value) + 2209161600000) / 1000;
}
Eric Koleda's answer is in many ways more general. I wrote this while trying to understand how it handles the corner cases with the spreadsheet timezone, browser timezone and the timezone changes in 1900 in Alaska and Stockholm.
Make a cell somewhere with a duration value of "00:00:00". This cell will be used as a reference. Could be a hidden cell, or a cell in a different sheet with config values. E.g. as below:
then write a function with two parameters - 1) value you want to process, and 2) reference value of "00:00:00". E.g.:
function gethours(val, ref) {
let dv = new Date(val)
let dr = new Date(ref)
return (dv.getTime() - dr.getTime())/(1000*60*60)
}
Since whatever Sheets are doing with the Duration type is exactly the same for both, we can now convert them to Dates and subtract, which gives correct value. In the code example above I used .getTime() which gives number of milliseconds since Jan 1, 1970, ... .
If we tried to compute what is exactly happening to the value, and make corrections, code gets too complicated.
One caveat: if the number of hours is very large say 200,000:00:00 there is substantial fractional value showing up since days/years are not exactly 24hrs/365days (? speculating here). Specifically, 200000:00:00 gives 200,000.16 as a result.
I am running into an issue where CRM doesn't appear to be treating the DateTime correctly with OData. Specifically, we are trying to create a custom record called new_vod with a start and end time (and a few other attributes that I have removed from here for simplicity) using a JavaScript call to the CrmRestKit. When the user performing this function is not in the same time zone as the server, the time is incorrect by whatever the offset between the server and the user happens to be.
For example, if my CRM user is in Mountain Time and the Server is in Eastern Time, the Start Time will be 2 hours from now (even though it should be now) when looking at the newly created record in CRM. The user's computer's timezone doesn't seem to have any impact on the result. (I'm comparing the "new_starttime" against the "Created On" time to confirm I'm not just viewing the data wrong, and the created on time is 2 hours before the start time in this scenario).
Here is the relevant snippet:
var startTime = new Date();
//Add 90 minutes to the current date/time
var endTime = new Date();
endTime.setMinutes(startTime.getMinutes() + 90);
//Create a cvt_VOD record
var newVOD = {
'new_starttime': startTime,
'new_endtime': endTime
};
var createdVOD = CrmRestKit.Create('new_vod', newVOD)
...
I noticed that when I debug the create of the new_vod record in a pre-stage plugin, the "conversion" to UTC has already occurred incorrectly, so it leads me to believe that the Rest Call itself isn't right.
Can anyone shed any light on why this would be happening?
FYI, We're on CRM 2015 on-premise.
Try this working solution by Somesh:
https://community.dynamics.com/crm/b/dynamicscrmbestpractices/archive/2014/12/04/crm-timezone-issue-using-javascript
I have tried to save a specific time into my mongodb database
with the javascript date object like:
var currenttime = new Date();
currenttime.setHours(14);
currenttime.setMinutes(37);
db.test.insert({time: currenttime});
however I have noticed that not only are the hours and minutes saved,
but also the date. I am searching for a way to only save the hours and
minutes, but in a way that I can still do less than greater than operations
on it. Is there a way to do this?
MongoDb Date is only 64bits, on the other hand if you will store your time as just 2 32 bit integers (hours and minutes) you will be already using these 64 bits. If you will save them as a 4 letters string, it will be even more.
So you can not gain space advantage. But you will lose advantage of querying your data. It will be harder to find all elements that are bigger than particular time with 2 numbers format and even harder with strings.
So I would save them as dates. If you really need only time - and need to query by this time, you can do the following trick: make all dates the same. For example:
var a = new Date(); // gives current date and time (note it is UTC datetime)
a.setYear(2000);
a.setMonth(0);
a.setDate(1);
db.test.insert({time: currenttime});
This way all the elements will have the same date and different time. In such a way you sort them properly. Also if you need to find all the elements where time is smaller than a particular time, you can quickly create a date object with year/month/day (2000/0/1) and query your data properly.
You can consider to save number of minutes as an integer field.
For example, 8:30 will be converted as 8 hour * 60 minutes + 30 minutes = 510 minutes. Save 510 as an number in MongoDB.
Basically you can try these two options to save time:
Save time as type: String
const userInput = '05:20';
const hours = userInput.slice(0, 2);
const minutes = userInput.slice(3);
Save date time in type: Date
But in second option you have to create Date object and set hours and minutes:
const date = new Date(dateString);
date.setHours(hours, minutes);