Javascript: date obj-date obj - javascript

As example. I want to check if time at t1 to now is more than 10s. How can I check it in angular js. I get now then substract t1. It return a number. How to convert it to second

I like to use moment.js for my Date object. It is a high level library, framework-orgnistic, and match very well with angular template system using angular-moment.
In your case you just should do it like this :
var t1 = moment();
... wait 10 sec ...
if (t1.fromNow('s') >= 10) {
...
}
It make is very easy to maintain in time, BUT cost some ressources if used to much.

Pure Javascript solution:
function checkAgo(t1, agoSecs) {
var timeAgo = new Date((new Date()).valueOf() - 1000 * agoSecs);
return t1 < timeAgo;
}
Call the function this way: checkAgo(t1, 10).

Related

How to correctly calculate the number of minutes from a certain moment?

There is a start date for the process in string form:
'2020-03-02 06:49:05'
And the process completion date:
'2020-03-02 07:05:02'
Question:
What is the most correct way from the point of view of the approach - to calculate the difference (in minutes) between the start and finish of the process?
(if there are any built-in methods for this in vue.js ornuxt.js, it will be very interesting to learn about them as well.)
I think the best way would be to use Javascript Date object,
d1 = '2020-03-02 06:49:05'
d2 = '2020-03-02 07:05:02'
diff_in_millis = Math.abs(new Date(d1) - new Date(d2))
diff_in_minutes = diff/60000
I suggest using momentjs, you can do something like this:
var duration = moment.duration(endTime.diff(startTime));
var minutes = duration.minutes();
More about duration in momentjs can be found here
Create the date from the string using Date.parse(). It return the date in milliseconds, get the difference and convert that to Minutes.
See snippet below.
const startTime= Date.parse('2020-03-02 06:49:05')
const endTime = Date.parse('2020-03-02 07:05:02')
// Difference in Minutes
const durationInMin= (endTime-startTime)/60000;
console.log({ startTime, endTime, durationInMin })
alert(`Process took: ${durationInMin} minutes`)
Note: For human readable dates, I have found date-fns to be the most helpful. Given its lightweight compared to momentjs. And you could complete the same with the following.
import { differenceInMinutes } from 'date-fns';
const startDate = '2020-03-02 06:49:05';
const endDate = '2020-03-02 07:05:02';
const durationInMin = differenceInMinutes( new Date(endDate), new Date(startDate));
console.log(`Duration: ${durationInMin} minutes`);
At the cost of another dependence to the project of course, but if you are handling lots of human readable dates, it's worth it.

How to convert seconds to HH:mm:ss in moment.js

How can I convert seconds to HH:mm:ss?
At the moment I am using the function below
render: function (data){
return new Date(data*1000).toTimeString().replace(/.*(\d{2}:\d{2}:\d{2}).*/, "$1");;
}
This works on chrome but in firefox for 12 seconds I get 01:00:12
I would like to use moment.js for cross browser compatibility
I tried this but does not work
render: function (data){
return moment(data).format('HH:mm:ss');
}
What am I doing wrong?
EDIT
I managed to find a solution without moment.js which is as follow
return (new Date(data * 1000)).toUTCString().match(/(\d\d:\d\d:\d\d)/)[0];
Still curious on how I can do it in moment.js
This is similar to the answer mplungjan referenced from another post, but more concise:
const secs = 456;
const formatted = moment.utc(secs*1000).format('HH:mm:ss');
document.write(formatted);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
It suffers from the same caveats, e.g. if seconds exceed one day (86400), you'll not get what you expect.
From this post I would try this to avoid leap issues
moment("2015-01-01").startOf('day')
.seconds(s)
.format('H:mm:ss');
I did not run jsPerf, but I would think this is faster than creating new date objects a million times
function pad(num) {
return ("0"+num).slice(-2);
}
function hhmmss(secs) {
var minutes = Math.floor(secs / 60);
secs = secs%60;
var hours = Math.floor(minutes/60)
minutes = minutes%60;
return `${pad(hours)}:${pad(minutes)}:${pad(secs)}`;
// return pad(hours)+":"+pad(minutes)+":"+pad(secs); for old browsers
}
function pad(num) {
return ("0"+num).slice(-2);
}
function hhmmss(secs) {
var minutes = Math.floor(secs / 60);
secs = secs%60;
var hours = Math.floor(minutes/60)
minutes = minutes%60;
return `${pad(hours)}:${pad(minutes)}:${pad(secs)}`;
// return pad(hours)+":"+pad(minutes)+":"+pad(secs); for old browsers
}
for (var i=60;i<=60*60*5;i++) {
document.write(hhmmss(i)+'<br/>');
}
/*
function show(s) {
var d = new Date();
var d1 = new Date(d.getTime()+s*1000);
var hms = hhmmss(s);
return (s+"s = "+ hms + " - "+ Math.floor((d1-d)/1000)+"\n"+d.toString().split("GMT")[0]+"\n"+d1.toString().split("GMT")[0]);
}
*/
You can use moment-duration-format plugin:
var seconds = 3820;
var duration = moment.duration(seconds, 'seconds');
var formatted = duration.format("hh:mm:ss");
console.log(formatted); // 01:03:40
<!-- Moment.js library -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
<!-- moment-duration-format plugin -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-duration-format/1.3.0/moment-duration-format.min.js"></script>
See also this Fiddle
Upd: To avoid trimming for values less than 60-sec use { trim: false }:
var formatted = duration.format("hh:mm:ss", { trim: false }); // "00:00:05"
var seconds = 2000 ; // or "2000"
seconds = parseInt(seconds) //because moment js dont know to handle number in string format
var format = Math.floor(moment.duration(seconds,'seconds').asHours()) + ':' + moment.duration(seconds,'seconds').minutes() + ':' + moment.duration(seconds,'seconds').seconds();
My solution for changing seconds (number) to string format (for example: 'mm:ss'):
const formattedSeconds = moment().startOf('day').seconds(S).format('mm:ss');
Write your seconds instead 'S' in example.
And just use the 'formattedSeconds' where you need.
In a better way to utiliza moments.js; you can convert the number of seconds to human-readable words like ( a few seconds, 2 minutes, an hour).
Example below should convert 30 seconds to "a few seconds"
moment.duration({"seconds": 30}).humanize()
Other useful features: "minutes", "hours"
The above examples may work for someone but none did for me, so I figure out a much simpler approach
var formatted = moment.utc(seconds*1000).format("mm:ss");
console.log(formatted);
Until 24 hrs.
As Duration.format is deprecated, with moment#2.23.0
const seconds = 123;
moment.utc(moment.duration(seconds,'seconds').as('milliseconds')).format('HH:mm:ss');
How to correctly use moment.js durations?
|
Use moment.duration() in codes
First, you need to import moment and moment-duration-format.
import moment from 'moment';
import 'moment-duration-format';
Then, use duration function. Let us apply the above example: 28800 = 8 am.
moment.duration(28800, "seconds").format("h:mm a");
🎉Well, you do not have above type error. 🤔Do you get a right value 8:00 am ? No…, the value you get is 8:00 a. Moment.js format is not working as it is supposed to.
💡The solution is to transform seconds to milliseconds and use UTC time.
moment.utc(moment.duration(value, 'seconds').asMilliseconds()).format('h:mm a')
All right we get 8:00 am now. If you want 8 am instead of 8:00 am for integral time, we need to do RegExp
const time = moment.utc(moment.duration(value, 'seconds').asMilliseconds()).format('h:mm a');
time.replace(/:00/g, '')
To display number of days along with hours, mins and seconds, you can do something like this:
const totalSec = 126102;
const remainingMillies= (totalSec % 86400) * 1000;
const formatted = `${Math.floor(totalSec / 86400)} day(s) and ${moment.utc(remainingMillies).format('hh:mm:ss')}`;
console.log(formatted );
will output :
1 day(s) and 11:01:42
In 2022 no need for any new plugin just do this
Literally all you need in 2022 prints out duration in hh:mm:ss from two different date strings
<Moment format='hh:mm:ss' duration={startTime} date={endTime} />
I think there's no need to use 3rd part libray/pluggin to get this task done
when using momentJS version 2.29.4 :
private getFormatedDuration(start: Date, end: Date): string {
// parse 'normal' Date values to momentJS values
const startDate = moment(start);
const endDate = moment(end);
// calculate and convert to momentJS duration
const duration = moment.duration(endDate.diff(startDate));
// retrieve wanted values from duration
const hours = duration.asHours().toString().split('.')[0];
const minutes = duration.minutes();
// voilà ! without using any 3rd library ..
return `${hours} h ${minutes} min`;
}
supports also 24h format
PS : you can test and calculate by yourself using a 'decimal to time' calculator at CalculatorSoup

How do I compare the speed of two Javascript functions?

I have some Javascript that is reading in some XML. There is an older function which was used to create a JSON object from that data, and I've written a new function that I hope will create that JSON object faster.
What is the easiest and best way to determine which function is performing faster? It's a decent amount of data, so it's somewhat important to know.
Thanks.
You could use console.time("ID"); and console.timeEnd("ID"); (info here), and look the results in the Chrome Developer Tools or Firebug like so:
console.time("oldFunc");
//oldfunc();
console.timeEnd("oldFunc");
console.time("newfunc");
//newfunc();
console.timeEnd("newfunc");
Also, you could use jsperf
Some info on this and code sample here
var startDate = new Date();
// execute your tasks here
var endDate = new Date();
var timeTaken = endDate.getTime() - startDate.getTime();
alert('Time take to execute the script is '+timeTaken+' milliseconds');
(new Date).getTime();
This is how you get current time in milliseconds. Do that before and after execution of code, subtract and you have execution time in miliseconds.
Sample:
var start=(new Date).getTime();
//call your code
alert('Code took '+((new Date).getTime()-start)+'ms');
If your code organisation allows, you can make your call in a for loop, repeating n (let's say 1000) times and divide the time by n at the end.
This way you get the average speed, which is especially helpful if you function varies a lot (like network calls).
I like John Resigs way of testing the performance of a function:
function runTest(name, test, next){
var runs = [], r = 0;
setTimeout(function(){
var start = Date.now(), diff = 0;
for ( var n = 0; diff < 1000; n++ ) {
test();
diff = Date.now() - start;
}
runs.push( n );
if ( r++ < 4 )
setTimeout( arguments.callee, 0 );
else {
done(name, runs);
if ( next )
setTimeout( next, 0 );
}
}, 0);
}
Is this in the browser or server-side?
If it's server-side, I'd recommend using your shell scripting tool of choice to do the benchmarking (linux has time, windows has...whatever windows has).
If it's in the browser, then you can always wrap a certain number of iterations (10,000 is usually enough) in:
var start = new Date.getTime();
var runs = 10000;
while (runs) {
// do stuff here
runs--;
}
console.log('Finished in ' + (new Date.getTime() - start) + ' ms.');
var d1 = new Date();
function1();
var d2 = new Date();
console.log("Function 1 : ", d2.getTime() - d1.getTime());
function2();
var d3 = new Date();
console.log("Function 2 : ", d3.getTime() - d2.getTime());

Why doesn't this method for getting the difference between two dates work?

I am trying to test whether certain time has elapsed. I use javascript.
Both examples use this variable:
var delete_after = 2 /*minutes*/ * 60 /*seconds*/ * 1000/*miliseconds*/; // [miliseconds]
This works:
var now = new Date();
var now_t = now.getTime();
var then = new Date(x.time); // x.time is string with a time
var then_t = then.getTime();//).getTime();
if (now_t - then_t > delete_after) {
alert("deleted");
}
This does not:
if (Date().getTime() - Date(x.time).getTime() > delete_after) {
alert("deleted");
}
I belived them to be equivalent, but they are not. I checked precedence, in the end it appears I have to call new to create a variable. It seems to impossible to call (new Date().getTime()). Please, would You be so kind to explain why it can not be written the second way?
Date().getTime()
is not the same as
(new Date()).getTime()
Date(x.time).getTime()
is not the same as
(new Date(x.time)).getTime()
Well, if you want to do it in short, just do it like this:
if ((new Date()).getTime() - (new Date(x.time)).getTime() > delete_after) {
alert("deleted");
}
Your example didn't work because object has to be instantiated before you perform any function call on it.
getTime is a function of date objects, not of the Date() function, so you have to call Date() to get a date object, and then call getTime on it.
https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date
This would do it all in one go, but it's a bit confusing
(new Date()).getTime()

Generate an RFC 3339 timestamp similar to Google Tasks API?

I am in the process of building an app that syncs with Google Tasks. As part part of the syncing, I want to compare the local task and the API task, and see which one has been changed more recently.
Each task from Google's API contains an updated property, which looks like this:
2011-08-30T13:22:53.108Z
Now I would like to generate a timestamp similar to that, so that every time I update a task on my app it sets a new updated value. To generate the RFC 3339 timestamp I am using - http://cbas.pandion.im/2009/10/generating-rfc-3339-timestamps-in.html which generates something like this:
2011-08-30T09:30:16.768-04:00
The issue is, the API date is always coming back as "greater" than the local date, even when the local date is newer. I'm guessing it has something to do with the different formatting between the two.
Here are two dates, the top is from the Google Tasks API (from about 10 minutes ago), and the bottom one was generated locally a minute ago. When compared which is greater, it's telling me the top one is.
2011-08-30T13:22:53.108Z
2011-08-30T09:41:00.735-04:00
Is my formatting wrong? What I am doing wrong here? Any help on this is really appreciated.
It seems like a lot of complicated answers have been given, but this works just fine, does it not?
new Date().toISOString()
The formatting is ISO so new Date().toISOString() will give you that form. Which as I'm reading might need to be shimmed:
/* use a function for the exact format desired... */
function ISODateString(d){
function pad(n){return n<10 ? '0'+n : n}
return d.getUTCFullYear()+'-'
+ pad(d.getUTCMonth()+1)+'-'
+ pad(d.getUTCDate())+'T'
+ pad(d.getUTCHours())+':'
+ pad(d.getUTCMinutes())+':'
+ pad(d.getUTCSeconds())+'Z'}
var d = new Date();
print(ISODateString(d)); // prints something like 2009-09-28T19:03:12Z
Source: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date
I've found the moment.js library nice for working with time in javascript. moment().format() yields a timestamp in the format expected by the Google API for a datetime. Or, to not depend on the default format being correct for your application,
moment().format("YYYY-MM-DDTHH:mm:ssZ")
All the string options (including fractional seconds if that's what you need): http://momentjs.com/docs/#/displaying/format/
If you are using Google Script, another option is to use Utilities.formatDate URL below:
https://developers.google.com/apps-script/reference/utilities/utilities#formatDate(Date,String,String)
Sample code from above URL:
// This formats the date as Greenwich Mean Time in the format
// year-month-dateThour-minute-second.
var formattedDate = Utilities.formatDate(new Date(), "GMT", "yyyy-MM-dd'T'HH:mm:ss'Z'");
Using date-fns, this is very elegant:
import { formatRFC3339 } from 'date-fns'
const result = formatRFC3339(new Date(2019, 8, 18, 19, 0, 52))
//=> '2019-09-18T19:00:52Z'
Source:
try this:
Date.prototype.setRFC3339 = function(dString) {
var utcOffset, offsetSplitChar;
var offsetMultiplier = 1;
var dateTime = dString.split("T");
var date = dateTime[0].split("-");
var time = dateTime[1].split(":");
var offsetField = time[time.length - 1];
var offsetString;
offsetFieldIdentifier = offsetField.charAt(offsetField.length - 1);
if (offsetFieldIdentifier == "Z") {
utcOffset = 0;
time[time.length - 1] = offsetField.substr(0, offsetField.length - 2);
} else {
if (offsetField[offsetField.length - 1].indexOf("+") != -1) {
offsetSplitChar = "+";
offsetMultiplier = 1;
} else {
offsetSplitChar = "-";
offsetMultiplier = -1;
}
offsetString = offsetField.split(offsetSplitChar);
time[time.length - 1] == offsetString[0];
offsetString = offsetString[1].split(":");
utcOffset = (offsetString[0] * 60) + offsetString[1];
utcOffset = utcOffset * 60 * 1000;
}
this.setTime(Date.UTC(date[0], date[1] - 1, date[2], time[0], time[1], time[2]) + (utcOffset * offsetMultiplier));
return this;
};
source: http://blog.toppingdesign.com/2009/08/13/fast-rfc-3339-date-processing-in-javascript/
The Z behind the first date indicates it's UTC (Zulu) time, without the Z it will use the local (computer) time, which could be several time zones off.
See: http://en.wikipedia.org/wiki/UTC
It looks more pretty:
new Date().toISOString().split('.')[0] + 'Z'

Categories