Adding time (sec and min) to a js var - javascript

i've a question: in a JS file i have a variable (returned from an ajax call) that contains a time formatted in hh:mm:ss.
My question is: how can i add X minutes and X seconds to that time?
i tried in this mode:
var lastop = moment(data['lastOp']); //10:04:00
var summa = lastop.add(data['sessionLease'],'minutes');
But in consolle i receive this:
Deprecation warning: moment construction falls back to js Date. This is discouraged and will be removed in upcoming major release. Please refer to https://github.com/moment/moment/issues/1407 for more info.
Arguments: [object Object]
Error
at Function.createFromInputFallback
How can i solve my problem?
Many thanks

Use moment with a format string, as the issue that error message pointed you to told you to:
var lastop = moment(data['lastOp'], "HH:mm:ss");
...then add the minute and second:
lastop.add(1, "minute");
lastop.add(1, "second");
Example:
var data = {
lastOp: "10:04:00"
};
var lastop = moment(data['lastOp'], "HH:mm:ss");
lastop.add(1, "minute");
lastop.add(1, "second");
console.log(lastop.format("HH:mm:ss"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.13.0/moment.min.js"></script>

It works perfctly!
Now i need to subtract actual time to a time variable (formatted in hh:mm:ss), for ex:
var time1 = 13:40:00
var time 2 = time1 - now time // How can i do?

Related

Moment not adding minutes to object created from javascript Date

I have a method that accepts a javascript date with time as input, and determines if the current date and time is within -30 mins. However, when I debug this at runtime, moment.add doesn't seem to be working with minutes as expected.
function isWithinRange(myDate: Date){
// convert to Moment obj
let myMoment = moment(myDate);
let todayMoment = moment(new Date());
let myMomentOk = myMoment.isValid();
let todayOk = todayMoment.isValid();
// create range values
let preTime = myMoment.subtract('m', 30);
let postTime = myMoment.add('m', 30);
//check values are as expected
let localeTime = myDate.toLocaleString();]
let preLocale = preTime.toLocaleString();
let postLocale = postTime.toLocaleString();
let result = todayMoment.isBetween(preTime, postTime);
return result;
}
But when I inspect the localeTime, preLocale and postLocale times at run time, all three values are the same, "Tue Jun 26 2018 09:58:00 GMT-0400". The add and subtract minutes statements had no impact.
What am I missing or doing wrong here?
Please note that both add() and subtract mutate the original moment.
add():
Mutates the original moment by adding time.
subtract:
Mutates the original moment by subtracting time.
so you have to use clone()
Moreover, in the recent version of moment, the first argument is the amount of time to add/subtract and the second argument is the string that represent the key of what time you want to add
add and subtract takes the amount of time first, and then what type of time, as documented here. Also make sure to create a new moment object for each calculation, as it mutates the moment object.
let preTime = moment(myMoment).subtract(30, 'm');
let postTime = moment(myMoment).add(30, 'm');
You're working on the same moment object all the time, because of this you have the original moment object at the time you're doing let localeTime = myDate.toLocaleString().
You just need to create a new moment object so you don't revert your changes.
...
// create range values
let preTime = moment(myMoment).subtract('m', 30);
let postTime = moment(myMoment).add('m', 30);
...
I think what you need to use is https://momentjs.com/docs/#/query/is-between/ isBetween method from the moment.
const testDate = moment()
testDate.isBetween(moment().subtract(30, 'm'), moment().add(30, 'm'))
// true
const testDate = moment().add(2, 'h');
testDate.isBetween(moment().subtract(30, 'm'), moment().add(30, 'm'))
// false
I think this should help.

Google Form on Submit get values and format the time

I am using Google Apps Script with a Google form. When the user submits the Google Form I get a value from a question. I then take that value and make it a date object, from what I saw on this post about daylight savings I use that to determine the timezone. I run the date object through Utilities.formatDate and want to get the correctly formatted date.
example: 9:00 AM
But instead I am getting a completely different time than expected.
My question is: Can someone help me understand why the below code is outputting a time that is 3 hours different?
function onSubmit(e) {
var values = e.values;
Logger.log(values);
try {
var start1 = new Date(values[3]);
var startN = new Date(start1).toString().substr(25,6)+"00";
var startT = Utilities.formatDate(start1, startN, "h:mm a");
Logger.log(startT);
} catch(error) {
Logger.log(error);
}
}
The assumption that Utilities formatDate does not support GMT... parameter is not true.
The post you mentioned in reference is used to get calendar events and is a useful way to get the right value when you get events from another daylight saving period (getting the TZ info from the calendar event itself), for example events for next month will be in "summer time" while we are still in "winter time"...
Your issue might come from different sources depending on time zone settings of your script vs timezone of the source. Could you describe the exact configuration in which you use this script ?
In the mean time, here is a small code that demonstrates how the code is working + the logger results :
function testOnSubmit() {
var eventInfo = {};
var values = {};
values['3'] = new Date();
eventInfo['values'] = values;
Logger.log('eventInfo = '+JSON.stringify(eventInfo)+'\n\n');
onSubmit(eventInfo);
}
function onSubmit(e) {
var values = e.values;
try {
var start1 = new Date(values[3]);
Logger.log('onSubmit log results : \n');
Logger.log('start1 = '+start1)
var startN = new Date(start1).toString().substr(25,6)+"00";
Logger.log('startN = '+startN);
var startT = Utilities.formatDate(start1, startN, "h:mm a");
Logger.log('result in timeZone = '+startT);
} catch(error) {
Logger.log(error);
}
}
EDIT : additionally, about the 30 and 45' offset, this can easily be solved by changing the substring length like this :
var startN = new Date(start1).toString().substr(25,8);
the result is the same, I had to use the other version a couple of years ago because Google changed the Utilities.formatDate method at some moment (issue 2204) but this has been fixed.
EDIT 2 : on the same subject, both methods actually return the same result, the GMT string has only the advantage that you don't have to know the exact timezone name... there is also the Session.getScriptTimeZone() method. Below is a demo script that shows the resulst for 2 dates in January and July along with the log results :
function testOnSubmit() {
var eventInfo = {};
var values = {};
values['3'] = new Date(2014,0,1,8,0,0,0);
eventInfo['values'] = values;
Logger.log('eventInfo = '+JSON.stringify(eventInfo)+'\n\n');
onSubmit(eventInfo);
values['3'] = new Date(2014,6,1,8,0,0,0);
eventInfo['values'] = values;
Logger.log('eventInfo = '+JSON.stringify(eventInfo)+'\n');
onSubmit(eventInfo);
}
function onSubmit(e) {
var values = e.values;
var start1 = new Date(values[3]);
Logger.log('onSubmit log results : ');
Logger.log('start1 = '+start1)
var startN = new Date(start1).toString().substr(25,8);
Logger.log('startN = '+startN);
Logger.log('result in timeZone using GMT string = '+Utilities.formatDate(start1, startN, "MMM,d h:mm a"));
Logger.log('result in timeZone using Joda.org string = '+Utilities.formatDate(start1, 'Europe/Brussels', "MMM,d h:mm a"));
Logger.log('result in timeZone using Session.getScriptTimeZone() = '+Utilities.formatDate(start1, Session.getScriptTimeZone(), "MMM,d h:mm a")+'\n');
}
Note also that the Logger has its own way to show the date object value ! it uses ISO 8601 time format which is UTC value.
Try this instead:
var timeZone = Session.getScriptTimeZone();
var startT = Utilities.formatDate(start1, timeZone, "h:mm a");
The Utilities.formatDate function expects a time zone that is a valid IANA time zone (such as America/Los_Angeles), not a GMT offset like GMT+0700.
I am making the assumption that Session.getScriptTimeZone() returns the appropriate zone. If not, then you might need to hard-code a specific zone, or use a different function to determine it.
Additionally, the +"00" in the script you had was assuming that all time zones use whole-hour offsets. In reality, there are several that have 30-minute or 45-minute offsets.

How to get time difference between two date time in javascript?

I want time duration between two date time. I have the start date, start time, end date and end time. Now I have to find the difference between them.
Actually I have tried with this following code, but I got the alert like 'invalidate date'.
function myfunction()
{
var start_dt = '2013-10-29 10:10:00';
var end_dt = '2013-10-30 10:10:00';
var new_st_dt=new Date(start_dt);
var new_end_dt=new Date(end_dt);
alert('new_st_dt:'+new_st_dt);
alert('new_end_dt:'+new_end_dt);
var duration=new_end_dt - new_st_dt;
alert('duration:'+duration);
}
the alert msg like as follows:
new_st_dt:invalid date
new_end_dt: invalid date
duration:NaN
when I run in android simulator I got these alert messages.
Please help me how to get it? How to implement this?
You're passing an invalid ISO date string to that Date() constructor. It needs a form like
YYYY-MM-DDThh:mm:ss
for instance
2013-10-29T10:10:00
So you basically forgot the T to separate date and time. But even if the browser reads in the ISO string now, you would not have an unix timestamp to calculate with. You either can call
Date.parse( '2013-10-29T10:10:00' ); // returns a timestamp
or you need to explicitly parse the Date object, like
var duration=(+new_end_dt) - (+new_st_dt);
Further read: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse
Try formatting you timestamps as isoformat so javascript recognizes them. (you put a "T" between the date and time). An example: '2013-10-29T10:10:00'
function dateDiff(){
var start_dt = '2013-10-29 10:10:00';
var end_dt = '2013-10-30 10:10:00';
var d1= start_dt ;
d1.split("-");
var d2= end_dt ;
d2.split("-");
var t1 = new Date(d2[0],d2[1],d2[2]);
var t2 = new Date(d1[0],d1[1],d1[2]);
var dif = t1.getTime() - t2.getTime();
var Seconds_from_T1_to_T2 = dif / 1000;
return Math.abs(Seconds_from_T1_to_T2);
}

Make a date/time value called from an API tick very second. (JavaScript)

I'm calling a date and time through an API, which looks like this:
<?php $xml = simplexml_load_file("https://api.eveonline.com/server/ServerStatus.xml.aspx/"); ?>
<div class="server-time">
<?php echo $xml->currentTime; ?>
</div>
This will show a date and time like this on the page:
2013-10-16 08:15:36
Now I want this clock to tick every second and the time and even date (in case it's just seconds before midnight when the user visits the site) values to change accordingly, just like you would expect a digital clock to work.
I know this is possible with JavaScript but since I am a total rookie at it I don't know how to do this - at all.
Help would be highly appriciated!
There are many javascript clocks out there, you don't even have to use an API to get the time and date!
function clock(id) {
//Create a new Date object.
oDate = new Date();
//Get year (4 digits)
var year = oDate.getFullYear();
//Get month (0 - 11) - NOTE this is using indexes, so 0 = January.
var month = oDate.getMonth();
//Get day (1 - 31) - not using indexes.
var day = oDate.getDate();
//Get hours
var hours = oDate.getHours();
//Get minutes
var minutes = oDate.getMinutes();
//Get seconds
var seconds = oDate.getSeconds();
//Maybe create a function that adds leading zero's here
var dateStr = '';
dateStr += year+' - '+month+' - '+day+' '+hours+':'+minutes+':'+seconds;
//Append dateStr to some element.
document.getElementById(id).innerHTML = dateStr;
//Repeat the function every 1000 miliseconds aka 1 second
setTimeout(function() {
clock(id);
}, 1000);
}
The usage would be
<div id="yourID">clock input will go here</div>
clock('yourID');
NOTE
This function has to be called after the DOM is loaded, otherwise this would result in error.
This can be achieved by placing the script tag with your JS at the bottom of the page (not using jQuery that is).
Otherwise if using jQuery, call the $(function() {}) (equivelant to $(document).ready(function() {});
The function is quite self-explanatory, but maybe you would want to read up on the functions to see exactly what they do.
a quick google search should do the trick.
Anyways hope this helps, good luck :)
I'm not sure if you want it to fetch the time from the api every second or, if you want it to just increase every second, starting from the given api time. In the latter case, you should use setInterval:
function updateTime() {
// assuming you are using jquery for DOM manipulation:
var timestamp = $('.server-time').text();
var date = new Date(timestamp);
date.setSeconds(date.getSeconds() + 1);
$('.server-time').text(date.toString());
}
setInterval(updateTime, 1000);
If you are not using jquery, just use document.getElementById or something like that:
change your element to:
<div id="server-time">
and use the following snippet:
function updateTime() {
// assuming you are using jquery for DOM manipulation:
var timestamp = document.getElementById('server-time').innerHTML;
var date = new Date(timestamp);
date.setSeconds(date.getSeconds() + 1);
document.getElementById('server-time').innerHTML = date.toString();
}

apps-script: copying a spreadsheet cell to a table, with formatting

I'm writing a script which opens an external Google spreadsheet via a URL. The script needs to copy cells into a FlexTable, and display them.
The problem is that the spreadsheet cells have a custom display format, to show them as elapsed times (m:ss.SS). If I just load up the table element with table.setWidget(x, y, app.createLabel(z)), the label just displays a date in 1899. Any idea how I can copy over the formatting?
Thanks.
EDIT
This nearly does it:
date = new Date(z); // 'z' from 'getValues'
elapsed = Utilities.formatDate(date, "GMT", "m:ss.SS");
table.setWidget(x, y, app.createLabel(elapsed));
Unfortunately, "m:ss.SS"doesn't work; it always displays the milliseconds as 0. Any ideas?
ANOTHER EDIT
apps-script seems to have completely messed this up. This code:
date = new Date();
elapsed = Utilities.formatDate(date, "GMT", "m:ss.SS");
table.setWidget(x, y, app.createLabel(elapsed));
Correctly shows the minutes and seconds portion of the current time, but there are 3 decimal places shown, not 2. This code:
date = new Date(z); // 'z' from 'getValues'
Doesn't work. When z is displayed in the spreadsheet with a non-zero number of milliseconds, this constructor always sets the number of ms to 0 (getMilliseconds returns 0).
Anyone have a work-around? I need apps-script to handle athletics event times, which are generally seconds to 2 decimal places, and possibly a few minutes.
I've noticed that these correspond to dates on December 30, 1899. This is odd - shouldn't this date have a negative time value? The GWT source code for formatDate handles negative values as a special case, and it's difficult to see what it's doing.
There are multiple related and unfixed bugs in this area; see here, for example. It's a bad, bad, idea to let Google sheets handle elapsed times. My eventual solution was to use "integers" to hold the times, and do all the required formatting and processing in GAS (carefully, because they're actually inexact floats, of course). This is pretty easy, and is much better than battling with Date. The only complication is if you need to import Dates from Excel. I had to modify the Excel spreadsheet to convert the dates to ms, and import those instead.
here is a possible workaround to show time the way you want : testsheet (please don't modify)
I used an Ui to define the time value but converted it to a date object in the script to verify how it works with a "real" date object.
EDIT : following the different answers to this post and this other by AdamL, I finally get something that allows displaying and calculating with short time values in hundreds of seconds with help of a UI and custom formatting.
function onOpen() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var menuEntries = [ {name: "Change cell format", functionName: "EditFormat"},
{name: "Reset format to default", functionName: "ResetFormat"},
{name: "show UI test", functionName: "sportChrono"},
]
ss.addMenu("Custom Format", menuEntries);
}
function EditFormat() {
var oldname = SpreadsheetApp.getActiveRange().getNumberFormat();
var name = Browser.inputBox("Current format (blank = no change):\r\n"+ oldname);
SpreadsheetApp.getActiveRange().setNumberFormat((name=="")?oldname:name);
}
function ResetFormat() {
SpreadsheetApp.getActiveRange().setNumberFormat("0.###############");
}
function sportChrono() {
var app = UiApp.createApplication().setTitle('Show Time in mm:ss.SS');
var main = app.createGrid(3, 4).setWidth('100');
var button = app.createButton('validate')
var btn2 = app.createButton('send to Cell').setId('btn2').setVisible(false)
var time = app.createTextBox().setId('time').setName('time')
var cellist = app.createListBox().addItem('A1').addItem('A2').addItem('A3').addItem('A4').addItem('A5').setVisible(false).setId('cellist').setName('cellist')
var min = app.createTextBox().setName('min');
var sec = app.createTextBox().setName('sec');
var Msec = app.createTextBox().setName('Msec');
main.setText(0,0,'minutes').setText(0,1,'secs').setText(0,2,'millisecs')
main.setWidget(1,0,min).setWidget(1,1,sec).setWidget(1,2,Msec);
main.setWidget(1,3,button).setWidget(2,0,time).setWidget(2,1,cellist).setWidget(2,2,btn2)
var handler = app.createServerHandler('show').addCallbackElement(main)
button.addClickHandler(handler)
var handler2 = app.createServerHandler('writeToSheet').addCallbackElement(main)
btn2.addClickHandler(handler2)
app.add(main)
ss=SpreadsheetApp.getActive()
ss.show(app)
}
function show(e){
var ss=SpreadsheetApp.getActive();
var app = UiApp.getActiveApplication();
var min = e.parameter.min
var sec = e.parameter.sec
var Msec = e.parameter.Msec
var time = new Date()
time.setHours(0,min,sec,Msec)
var nmin = digit(time.getMinutes())
var nsec = digit(time.getSeconds())
var nMsec = digit(time.getMilliseconds())
app.getElementById('time').setText(nmin+':'+nsec+'.'+nMsec)
var btn2 = app.getElementById('btn2').setVisible(true)
var cellist = app.getElementById('cellist').setVisible(true)
return app
}
function writeToSheet(e){
var range = e.parameter.cellist
var val = e.parameter.time
var ss=SpreadsheetApp.getActive();
ss.getRange(range).setFormula('=value("0:'+val+'")');
}
function digit(val){
var str
if(val<10){
str='0'+val}
else if(val>9&&val<99){
str=val.toString()}
else{
str=Math.round(val/10).toString()
}
return str
}

Categories

Resources