I'm probably just tired and not thinking clearly, but can someone give a concise way of getting the number of milliseconds passed since the last minute using javascript?
Something like Date.getSeconds(), but that would return milliseconds.
Although I could just do (Date.getSeconds()*1000) + Date.getMilliseconds(), this just seems really awkward and like there has to be a better way.
Thanks!
Depends what you're trying to do.
The difference between now and 1 minute ago in milliseconds should always be 60000 milliseconds. o_O
As Jan said Date.now() will return the current timestamp in milliseconds.
But it seems you might be looking for the getTime method, e.g.:
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getTime
// note the keyword "new" below
var date_instance = new Date();
// separate example in case you're managing Date()'s and not the method,
// who knows, just an example
var timestamp = date_instance.getTime();
var minute_before_timestamp = function(ts){
return ts - 60000;
};
console.log(minute_before_timestamp(timestamp));
console.log(minute_before_timestamp(date_instance.getTime()); // always same as above!
// or use the current time
console.log(minute_before_timestamp(Date.now()));
console.log(minute_before_timestamp(new Date().getTime()));
(another useful link: http://www.epochconverter.com/)
What about…
Date.now() % 60000
Date.now returns the current UNIX timestamp in ms.
To clarify what's happening there, the % operator is called modulo and what it does is that it gives you the remainder from dividing the first number by the other one.
An example can be:
20 % 7 === 6
13 % 7 === 6
6 % 7 === 6
…because…
20 / 7 = 2 + 6 / 7
13 / 7 = 1 + 6 / 7
6 / 7 = 0 + 6 / 7
(note the remainder 6)
Related
Any help is greatly appreciated. I've been struggling to find a solution for this question:
Using Moment library, what is the correct syntax to convert minutes into days hours and minutes that also formats for singular vs plural?
expected: 2009 minutes would become: 1 day 9 hours 29 minutes
here is the incorrect code:
function durationFormatter(minutes): string {
const ms = minutes * 60000;
const days = Math.floor(ms / 8.64e7);
const msOnLastDay = ms - days * 8.64e7;
return moment.utc(msOnLastDay)
.format("D [days] H [hours] M [minutes]");
}
console.log('durationFormatter -->', durationFormatter(2009));
The above outputs:
1 days 9 hours 1 minutes which is wrong
I also tried this other moment package moment-duration-format with this syntax: (per docs = https://github.com/jsmreese/moment-duration-format#basics)
import momentDurationFormatSetup from 'moment-duration-format';
function durationFormatter(minutes): string {
momentDurationFormatSetup();
return moment.duration(minutes, "minutes").format();
}
But I get this error:
Property 'format' does not exist on type 'Duration'
How would I use this with the package?
You can use the excellent library humanizeDuration, simply passing:
humanizeDuration(2009 * 60 * 1000, { delimiter: ' '})
will output what you wanted - 1 day 9 hours 29 minute.
Note - you pass milliseconds, so you need to multiple the minutes parameter by 60,000 before passing to humanizeDuration
This question already has an answer here:
How to use moment.js to get remaining hours, minutes, and seconds from a unix timestamp?
(1 answer)
Closed 2 years ago.
I am trying to convert seconds to DD:HH:mm:ss format or other formats like (YYYYMMDD)
function secToFormat(seconds, format){
return moment.utc(seconds * 1000).format(format);
}
// works well.
console.log(secToFormat(40,"HH:mm:ss"));
console.log(secToFormat(100,"HH:mm:ss"));
console.log(secToFormat(1800,"HH:mm:ss"));
console.log(secToFormat(18800,"HH:mm:ss"));
console.log(secToFormat(86300,"HH:mm:ss"));
// doesn't work I expected.
console.log(secToFormat(40,"DD:HH:mm:ss")); //it returns 01:00:00:40 but I expect 00:00:00:40
console.log(secToFormat(100,"DD:HH:mm:ss")); //it returns 01:00:01:40 but I expect 00:00:01:40
console.log(secToFormat(86300,"DD:HH:mm:ss")); //it returns 01:23:58:20 but I expect 00:23:58:20
console.log(secToFormat(86400*2,"DD:HH:mm:ss")); //it returns 03:00:00:00 but I expect 02:00:00:00
// it also doesn't work with another format.
console.log(secToFormat(40, "MM:DD:HH:mm:ss")); // I want to get 00:00:00:00:40
console.log(secToFormat(100, "MM:DD:HH:mm:ss")); // I want to get 00:00:00:01:40
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.26.0/moment.min.js"></script>
I understand why it happens because it starts at 1970-01-01 00:00:00.
but I want to edit it what I expect.
How can I achieve it?
You can use moment.js' durations, however they don't have much in the way of formatting, e.g.
let seconds = 28763827;
let duration = moment.duration(seconds, 'seconds');
console.log('Default ISO: ' + duration); // "PT7989H57M7S"
console.log('Moment humanized: ' + duration.humanize()); // a year
console.log('Moment days: ' + duration.asDays()); // 332.91466435185185
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.26.0/moment.min.js"></script>
Consider writing your own function to convert to a format like d.HH:mm:ss, e.g.
function secsToTime(secs) {
let d = secs / 8.64e4 | 0;
let H = (secs % 8.64e4) / 3.6e3 | 0;
let m = (secs % 3.6e3) / 60 | 0;
let s = secs % 60;
let z = n=> (n < 10? '0' : '') + n;
return `${d}.${z(H)}:${z(m)}:${z(s)}`
}
let seconds = 28763827;
console.log(secsToTime(seconds));
Using moment-duration-format to implement.
It is actually the "officially referenced" way (by momentjs author in both issues and docs). Explanation and examples here in my other answer:
How to use moment.js to get remaining hours, minutes, and seconds from a unix timestamp?
#RobG's answer is a great base for rolling your own, and I am tempted to edit it into my answer in above link. But note that moment-duration-format already exists and is the sanctioned way to do it, as well as being an actively updated library, and really satisfies most any use case I can think of (eg: drop-in one statement replacement in OP's example code).
It is also possible to extract the data directly from duration's internal variable _data. Though, I really don't recommend doing that. I have a rough demo of that in the other answer.
function secToFormat(seconds, format){
return moment.duration(seconds,'seconds').format(format, {trim: false});
// trim: false so it doesn't trim off 0 values
// (so last one would be 01:40 instead of 00:00:00:01:40 if trim: true)
}
// works well.
console.log(secToFormat(40,"HH:mm:ss"));
console.log(secToFormat(100,"HH:mm:ss"));
console.log(secToFormat(1800,"HH:mm:ss"));
console.log(secToFormat(18800,"HH:mm:ss"));
console.log(secToFormat(86300,"HH:mm:ss"));
// doesn't work I expected.
console.log(secToFormat(40,"DD:HH:mm:ss")); //it returns 01:00:00:40 but I expect 00:00:00:40
console.log(secToFormat(100,"DD:HH:mm:ss")); //it returns 01:00:01:40 but I expect 00:00:01:40
console.log(secToFormat(86300,"DD:HH:mm:ss")); //it returns 01:23:58:20 but I expect 00:23:58:20
console.log(secToFormat(86400*2,"DD:HH:mm:ss")); //it returns 03:00:00:00 but I expect 02:00:00:00
// it also doesn't work with another format.
console.log(secToFormat(40, "MM:DD:HH:mm:ss")); // I want to get 00:00:00:00:40
console.log(secToFormat(100, "MM:DD:HH:mm:ss")); // I want to get 00:00:00:01:40
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.26.0/moment.min.js"></script>
<!-- moment-duration-format plugin -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-duration-format/2.3.1/moment-duration-format.min.js"></script>
I'm trying to get a timer to count down to a date by days and I don't know why this isn't working it just says NaN
function daysUntil24thApril2016() {
var april2016 = new Date(24, 4, 2016);
var difference = april2016.getMilliseconds - Date.now().getMilliseconds;
return difference / 1000 / 60 / 60 / 24;
}
$(document).ready(function() {
console.log("asdasd")
$('#dateTime').text(daysUntil24thApril2016());
});
There are several mistakes you made in your script, I'll try to explain each to help you understand it and finally give you a corrected script the way you wrote it:
new Date() wants the year first, then month - 1 and finally the days. So to get the 24.04.2016, you have to do new Date(2016, 3, 24)
For a Date there is a getMilliseconds function, but it returns the milliseconds part of that date, not the unix timestamp you wanted
.getTime() is the function to get the unix timestamp in milliseconds from this date
Date.now() already returns the unix timestamp (a number), there is no getMilliseconds() for that and therefore it returned undefined
Even if there were a getMilliseconds function, the way you wrote it without the braces () would not have called it anyway but returned the function. They way you wrote it resulted in var difference = function - undefined which is NaN: "Not a number".
Therefore difference was no number in your example (it was Nan) and you cannot do any math with it obviously, it stays NaN
Using Math.floor will give you full days
See below for a version of your script where the points above are corrected.
function daysUntil24thApril2016() {
var april2016 = new Date(2016, 3, 24);
var difference = april2016.getTime() - Date.now();
return Math.floor(difference / 1000 / 60 / 60 / 24);
}
$(document).ready(function() {
$('#dateTime').text(daysUntil24thApril2016());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="dateTime"></div>
Something like this will solve your problem:
function daysUntil24thApril2016() {
var april2016 = new Date("2015-04-24");
var difference = Date.now()-april2016;
return Math.floor((difference) / (1000*60*60*24))
}
$(document).ready(function() {
console.log(daysUntil24thApril2016());
});
When you subtract one Date object from another you will get the time difference in milliseconds. Using Math.floor() will return a whole (integer) number of days.
I need help writing a little Regular Expression to replace integers into a time format string in a text input field.
In my form: I have a text input field where I'm supposed to write numbers. And when I write a number: I want a piece of JavaScript to convert it to a human-friendly, readable time when the input field loses focus. The thing that makes this "Clever" is that I want to be able to write as little as absolutely possible: And have it transform to the most appropriate time corresponding to my number.
Let me give you a few examples. If I write:
7 it would resolve to 07:00
15 it would resolve to 15:00
93 it would resolve to 09:30
1945 it would resolve to 19:45
143 it would resolve to 14:30
... And so on ...
I want it to do this replacement after the input field loses focus (onblur-event)
Also. I want to have a 0 prefix for night hours. Like this:
015 = 00:15
03 = 00:30
012 = 00:12
... And so on ...
I begun writing if statements to do this, but I stopped dead in my tracks because I realized it would take so many if statements, and would not be very reliable. I feel like Regular Expressions would be much smarter since it compacts my script and makes loading time quicker. I grasp the basics of Regular Expressions, but I don't know how to write a clever one for this purpose.
This is what my code got to before I decided to drop it:
var elem = document.getElementById("incidentHourStart-" + row);
if (elem.value.length === 1) {
// Must be a whole hour (0-9)
} else if (elem.value.length === 2) {
// Can be either two digits hour (10-23) or hour + whole minute (73: 07:30)
if (parseInt(elem.value) >= 10 && parseInt(elem.value) <= 23) {
// Two digits, whole hour (10-23)
} else {
// First digit is hour, and last one is whole minute (10, 20, 30, 40, 50)
}
} else if (elem.value.length === 3) {
// First digit must be an hour value, middle digit is also hour if it is lower than 23, last digit is then always whole minutes
if (parseInt(elem.value) >= 10 && parseInt(elem.value) <= 23) {
// Two digits, whole hour (10-23)
} else {
// First digit is hour, and last one is whole minute (10, 20, 30, 40, 50)
}
} else if (elem.value.length === 4) {
// First two digits must be an hour value, last digits is then fine selected minutes
}
As you can see: It looks very ugly!
UPDATE:
As stated in the comments: People have found my rules a little confusing. So here is the pseudo code of rules I want it to follow. If this can be put into a Regex in a clever way: Then awesome! If not: I will write out the if/else blocks, or split the Regex up into parts as suggested.
If text-length is equal to 1
Resolve as whole hour between 0-9
Examples:
2 = 02:00
8 = 08:00
5 = 05:00
If text-length is equal to 2 AND number is between 10 and 23
Resolve as whole hour between 10-23
Examples:
15 = 15:00
11 = 11:00
22 = 22:00
If text-length is equal to 2 AND number is NOT between 10 and 23
Resolve as whole hour and minutes incremented by 10's (10, 20, 30, 40, 50)
Examples:
73 = 07:30
24 = 02:40
95 = 09:50
If text-length is equal to 3 AND first two numbers are between 10 and 23
Resolve two first digits as hours and last digit as minutes incremented by 10's (10, 20, 30, 40, 50)
Examples:
133 = 13:30
195 = 19:50
111 = 11:10
162 = 16:20
If text-length is equal to 3 AND first two numbers are NOT between 10 and 23
Resolve first digit as whole hour, and last two as minutes.
Examples:
225 = 02:25
922 = 09:22
557 = 05:57
451 = 04:51
If text-length is equal to 1 AND first digit is equal to 0
Resolve as mid-night
Example:
0 = 00:00
If text-length is equal to 2 AND first digit is equal to 0
Resolve as mid-night + minutes incremented by 10's (10, 20, 30, 40, 50)
Examples:
02 = 00:20
05 = 00:50
03 = 00:30
If text-length is equal to 3 AND first digit is equal to 0
Resolve as mid-night + full minutes.
Examples:
024 = 00:24
011 = 00:11
056 = 00:56
If text-length is equal to 4
Resolve as regular minutes and hours without the colon (:)
Examples:
1524 = 15:24
2211 = 22:11
Don't make it harder on yourself than you need. Simply put; don't do this in one regular expression. Also don't forget to trim your input before using RegEx.
First of all check the zero-prefixed one, something like:
^0(\d+)$
Then if that doesn't match, do the check for the normal numbering and split it with the capture groups however you want:
^([^0]\d{1,3})$ // Can do negative lookbehind here, but I left it simple in this case
Regular expressions are often misused to solve a bigger problem in one pattern. It's much better to split logic if the situation asks for it. Don't overcomplicate code. It will break whoever needs to read it later's brain.
I have found a solution and had it deployed for about 1.5 months now. And so far: It works great. My co-workers love this functionality, and really saves up a lot of time! So far: No faults have been reported to me.
So here is what I did:
I bascially re-wrote my pseudo-code into actual JavaScript code using if/else blocks as suggested in the question's comments. I stuck it all into a function that I call from an onblur event on the input fields. Like this:
<input type="text" id="incidentHourStart-1" onblur="resolveTimeField(1);">
So the formatting occurs as soon as the input field loses focus.
Here is what my function looks like:
function resolveTimeField(row) {
var elem = document.getElementById("incidentHourStart-" + row);
if (elem.value.length === 1) {
// Must be a whole hour (0-9)
elem.value = "0" + elem.value + ":00";
} else if (elem.value.length === 2) {
// Can be either two digits hour (10-23) or hour + whole minute (73: 07:30)
if (parseInt(elem.value) >= 10 && parseInt(elem.value) <= 23) {
// Two digits, whole hour (10-23)
elem.value = elem.value + ":00";
} else {
// First digit is hour, and last one is whole minute (10, 20, 30, 40, 50)
var hours = elem.value.substring(0, 1);
var minutes = elem.value.substring(1, 2);
elem.value = "0" + hours + ":" + minutes + "0";
}
} else if (elem.value.length === 3) {
// First digit must be an hour value, middle digit is also hour if it is lower than 23, last digit is then always whole minutes
var firstDigits = elem.value.substring(0, 2);
if (parseInt(firstDigits) >= 10 && parseInt(firstDigits) <= 23) {
// 3 digits, first two are hours, and last digit is minutes incremented by 10's
var hours = elem.value.substring(0, 2);
var minutes = elem.value.substring(2, 3);
elem.value = hours + ":" + minutes + "0";
} else {
// First digit is hour, and last two is full minutes
var hours = elem.value.substring(0, 1);
var minutes = elem.value.substring(1, 3);
elem.value = "0" + hours + ":" + minutes;
}
} else if (elem.value.length === 4) {
// First two digits must be an hour value, last digits is then fine selected minutes
var hours = elem.value.substring(0, 2);
var minutes = elem.value.substring(2, 4);
elem.value = hours + ":" + minutes;
}
}
Here is a JSFiddle if you want to test out the code for yourself
My function takes one parameter referenced as row. This is because the fields I am working with lays within a dynamic table that lets my co-workers register more data in one go.
Currently it does not have any forms of input validation that checks if the inserted value is valid. So you could write something like 999 into the field and have it resolve to 09:99. This is not a critical feature for our environment, but I can imagine it would be fairly easy to implement shall it be required. I will update this post if I ever implement such a validation feature in the future.
I have a validator that checks if an user is at least 18 years old.
This is the check:
var res = /^([1-2]\d{3})\-(0[1-9]|1[012])\-(0[1-9]|[12][0-9]|3[01])\-([0-9]{4})$/.exec(str);
var todays_date = new Date();
var birth_date = null;
if (res != null) {
birth_date = new Date(res[1], res[2], res[3]);
if (todays_date - birth_date > 565633905872) {
565633905872 is 18 years in milliseconds but how do I convert it to years before so I can just do:
if (todays_date - birth_date => 18) {
The number you have quoted is not the number of milliseconds in 18 years. It's too small even if you pretend there are no leap years.
The simplest way to test if somebody is at least 18 years old is to initialise a date object to their birthday, then use .getFullYear() and .setFullYear() to directly set the year 18 years forward. Then compare that with the current date.
Note also that in JS dates the month is zero-based, so you probably want to use res[2] - 1 when creating the date object.
birth_date = new Date(res[1], res[2] - 1, res[3]);
birth_date.setFullYear(birth_date.getFullYear() + 18);
if (birth_date <= new Date()) {
Or given you are constructing the birth_date from individual year, month and day you could just do:
birthPlus18 = new Date(+res[1] + 18, res[2] - 1, res[3]);
if (birthPlus18 <= new Date()) {
(The leading + in +res[1] + 18 is not a typo, it converts the string extracted by your regex into a number so that you can add 18 to it. You don't need to do the same thing for res[2] - 1 because - automatically converts both operands.)
Note also that your regex will happily allow dates that specify a day that is too high for the month, e.g., Feb 30 or Jun 31.
There are better ways of checking this (see the answer of "nnnnnn"). But your question wasn't about a better way but, how you could convert to years.
You could write a function that does that, example:
function convertmili( mSeconds )
{
return mSeconds / 31536000000;
}
The output of this function is still far from ideal, because your example would output: 17.9361334941654
So we could clean it up a bit:
function convertmili( mSeconds )
{
var checkYear = Math.floor(mSeconds / 31536000000);
return checkYear;
}
With this function, your example would output 17 and then you can check it the way you wanted.
Divide your millisecond value by 31536000000 you get number of years
http://www.convertunits.com/from/milliseconds/to/year