Javascript calculation not correct - javascript

i have a weird problem in my javascript, take a look at my code below:
dateParts = document.getElementById('date').value.split('/');
newDays = 14;
year = dateParts[2];
month = parseInt(dateParts[1]) - 1;
day = parseInt(dateParts[0]) + parseInt(newDays);
alert(dateParts[0]+" + "+newDays+" = "+day);
and assume document.getElementById('date') = 07/01/2013
the calculation will give a correct result = 07 + 14 = 21
the calculation work fine at all date, except for 08/01/2013 / 09/01/2013
which the result is 08 + 14 = 14, any idea whats wrong here?

Your numbers are treated as octals, since you haven't used radix within parseInt()s. You need to adjust your parseInt()s like this:
month = parseInt(dateParts[1], 10) - 1;
day = parseInt(dateParts[0], 10) + parseInt(newDays, 10);

The leading 0 in 08 and 09 is causing JavaScript to assume the number is octal. Since those are not valid octal values, it treats them as 0. See this question for more details.
You should always use a radix when calling parseInt to avoid this problem.

the function is The parseInt(str, redix), if the value in the parseInt start with 0, it is assumed the radix is 8 so '09', '08' is invalid and the function returns 0. You need to call the function like parseInt('08', 10) to get the correct value.

Related

how to convert "05:30" String value into integer using javascript

I tried to convert the string into integer using parseInt and parseFloat. But my string value is "+05:30" while using parseInt or parseFloat it converts it into 5, but I need exact conversion to 5.30. How could I do this?
My sample code is:
User.findAll({attributes: ['UTC offset'],
where: {
Timezone: { $like: '%'+address }
}
}).then(TimeZoneData => {
if(TimeZoneData.length != 0) {
var offset = parseFloat(TimeZoneData[0].dataValues['UTC DST offset']), // it return 5 only
}
Let's say the time zone offsets are valid, they are in hours and minutes always separated by a colon (':') and preceded by a '+' or '-'.
So
var utcOffset = "+05:30";
var a = uctOffset.split(':');
var hour = +a[0];
var minute = +a[1];
What you do with the hour and minute values is up to you - but if the hour is negative, the minutes might need to be made negative too. I suggest you use isNaN to check the minute is valid if it may be absent:
if( isNaN( minute)
minute = 0;

Clever time formatting with JavaScript

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.

Convert milliseconds to years

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

wrong date created with Javascript

I have a problem that seems so senseless that I'm sure I'm missing something really stupid.
I have the following Javascript function that validates a date:
function validateDate(date){
var re = /\b\d{1,2}[\/-]\d{1,2}[\/-]\d{4}\b/;
if(!re.test(date))
return false;
var separator = (date.indexOf("/") != -1) ? "/" : "-";
var aux = date.split(separator);
var day = parseInt(aux[0]);
var month = parseInt(aux[1]);
var year = parseInt(aux[2]);
alert(aux[0]+" "+aux[1]+" "+aux[2]);
var dateTest = new Date(year,month-1,day);
alert(dateTest); //2nd alert
if(dateTest.getDate() != day)
return false;
if(dateTest.getMonth()+1!= month)
return false;
if(dateTest.getFullYear() != year)
return false;
return true;
}
the first alert always shows the correct values.
if the incoming date is for example 05/07/2011, everything works fine. The second alert shows "Tue Jul 5 00:00:00 UTC+0200 2011" which is right.
but now, if i change the date month to august or september, the created date is wrong. for example, with date 05/08/2011, the second alert will show "Sun Dec 5 00:00:00 UTC+0100 2010".
anyone knows what could be happening??
Make sure you supply a radix to parseInt. If you don't, it will "guess" based on the string. In this case, your 08 is being parsed as an octal value because of the prefixed zero and you get 0 back.
var day = parseInt(aux[0], 10);
var month = parseInt(aux[1], 10);
var year = parseInt(aux[2], 10);
Supplying a base ten number will get you the correct result.
//Parsing numbers:
parseInt("06"); // 6, valid octal
parseInt("07"); // 7, valid octal
parseInt("08"); // 0, invalid octal
parseInt("09"); // 0, invalid octal
parseInt("10"); // 10, parsed as decimal
parseInt("11"); // 11, parsed as decimal
parseInt("12"); // 12, parsed as decimal

Simple Javascript date conversion

I have this - Tue, 03 Apr 2012 05:00:33 GMT
Need this - 20120323111106
Google has failed me, I think I just don't know exactly what im searching for so I kept it simple here with the question.
EDIT: The dates do not match obviously, just looking to get it in that format.
Good answer (later edited):
I think this is what you are looking for :
function addZero(val){
if (parseInt(val) < 10) return "0" + val;
return val;
}
var dt = new Date("Tue, 03 Apr 2012 05:00:33 GMT");
console.log(dt.getFullYear() + addZero(dt.getMonth()) + addZero(dt.getDay()) + addZero(dt.getHours()) + addZero(dt.getMinutes()) + addZero(dt.getSeconds()))
Initial wrong answer :
var dt = new Date("Tue, 03 Apr 2012 05:00:33 GMT")
var miliseconds = dt.getTime();
I've tested it and my computer converted it automatically to GMT +3 (my timezone), you can play with that according to your timezone.
Writing a function to parse a string should work for you. By the looks of it, any date string that you currently have will be the same length. If this is the case this should be relatively easy. Just make sure your strings are in this format before you pass them in as arguments.
function parse(string) {
var out = "yyyymmddhhmmss"
out.charAt(0) = string.charAt(13);
out.charAt(1) = string.charAt(14);
out.charAt(2) = string.charAt(15);
out.charAt(3) = string.charAt(16);
//if else statements for each month converting to numbers
if (string.substring(9,12).equals("Apr")) {
out.charAt(4) = '0';
out.charAt(5) = '4';
}
out.charAt(6) = string.charAt(18);
out.charAt(7) = string.charAt(19);
...etc for the remaining values
return out
}
My numbers for character indices may be off, but if you use this idea, it should set you straight. Define a function and pass in the dates in the format you have, and out will come the dates in the format you want.

Categories

Resources