Javascript: Date Issue while validating in JavaScript function - javascript

In Javascript function:
if (Tim2Val > Tim3Val && Tim2Val < Tim4Val)
return true;
else
return false;
IF I have Variables like
Tim1Val= 8:00;
Tim2Val= 23:00;
Tim3Val= 01:00;
Tim4Val= 05:00
It is returning true. (It should return false. Can you please tell me how we can solve this?)
IF I have Variables like
Tim1Val= 8:00;
Tim2Val= 23:00;
Tim3Val= 02:00;
Tim4Val= 05:00;
It is returning false.
function fn_ConvTo24Format(MsTimeVal)
{
if(MsTimeVal=='')
{
return -1;
}
var A = MsTimeVal.split(/\D+/);
var locAMPos = MsTimeVal.indexOf('AM');
var locPMPos = MsTimeVal.indexOf('PM');
if(locAMPos ==-1 && locPMPos ==-1)
{
return MsTimeVal;
}
if(locAMPos!= -1 && A[0] + '.' + A[1]=='12.00' )
{
return 0;
}
if(locPMPos!= -1 && A[0] + '.' + A[1]=='12.00' )
{
return 12;
}
if(locAMPos!= -1 && A[0] + '.' + A[1]=='12.00' )
{
return 0;
}
if(locAMPos!= -1)
{
return A[0] + '.' + A[1];
}
if(locPMPos!= -1)
{
return (parseFloat(A[0]) + 12) + '.' + A[1];
}
return MsTimeVal;
}

Perhaps not ever using Tim1Val is part of the problem?

I suppose these values come in as string. If you compare the two, Javascript converts them to numbers, effectively changing their value.
"8:00" becomes 8 and minutes are ignored.
Maybe convert your hours and minutes in to just minutes:
function toMinutes (value) {
var parts = value.split(":");
return Number(value[0]) * 60 + Number(value[1]);
}
var Tim1Val = "8:00";
var Tim2Val = "23:00";
var Tim3Val = "2:00";
var Tim4Val = "5:00";
if (toMinutes(Tim1Val) > toMinutes(Tim3Val) && toMinutes(Tim2Val) < toMinutes(Tim4Val))
Oh and as Peter Wilkinson says, you never use Tim1Val.

Your function returns data of several types: string and numbers.
Use one type make
...
if(locAMPos!= -1)
{
return parseFloat(A[0] + '.' + A[1]);
}
....
I think it's not good way to make time comparation.
Will be better get Date class exemplar and work with it.

Related

Regex to detect numbers but not decimal

I am creating a formatter, which formats pricing. The idea is that if a user types 'between 45 and 50', it should return 'between $45.00 and $50.00'. Or if a user types 'between 45.58 to 38.91', it should return 'between $45.58 to $38.91'
This is what I have so far -
function formatPricesInString($str){
var x = $str.match(/\d+/g);
if(x != null){
$.each(x, function(i, v){
$str = $str.replace(v, formatPrice(v));
});
}
return $str;
}
Here formatPrice(v) is another function to which if you pass 45, it will return $45.00.
Now, to my function - formatPricesInString($str),
if I pass 45 - 50, it returns $45.00 - $50.00, which is fine,
but if I pass 45.00 - 50.00 it is returning $45.00.$00.00 - $50.00.$00.00.
Basically, it is taking all the numbers - 45, 00, 50, 00 and formatting them.
How can I handle such scenario that if 45.00 or 45.56 is passed, it should not do anything, but if I just pass normal integer in the string, it should return formatted price.
Any other optimized way is also welcome.
formatPrice(...) method -
function formatPrice(price) {
var symbol = $("#currencySymbolData").attr('data-symbol');
if (typeof symbol === "undefined" || symbol == '') {
symbol = '$';
}
var symbol_loc = $("#currencySymbolData").attr('data-symbol-loc');
if (typeof symbol_loc === "undefined" || symbol_loc == '') {
symbol_loc = 'before';
}
price = precise_round(price, 2).toString().replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,");
if (symbol_loc == 'after') {
return price + symbol;
} else {
return symbol + price;
}
}
EDIT - Answer
With the help of code provided by #RomanPerekhrest this worked -
function formatPricesInString($str){
return $str.replace(/(\$?\d+(\.\d+)?)\b/g, function(m){
m = (m[0] === '$')? m.slice(1) : m;
return formatPrice(m);
});
}
Consider the following solution using String.prototype.replace() function with replacement callback:
var str = 'between 45 and 50 and between 45.58 to $38.91',
formatted = str.replace(/(\$?\d+(\.\d+)?)\b/g, function (m) {
var prefix = (m[0] === '$')? '' : '$';
return prefix + ((m.indexOf('.') === -1)? Number(m).toFixed(2) : m);
});
console.log(formatted);

Evaluate string giving boolean expression in JavaScript

I have a string that contains Boolean logic something like:
var test = "(true)&&(false)&&!(true||true)"
What is a good way to evaluate this string in JavaScript to get the boolean value of false in this case
I know we could use eval() or new Function().. - but is that a safe approach?
I am guessing the other option would be to write a custom parser. Being a fairly new person to JS, would that be a lot of effort? I could not find any examples of parsers for Boolean logic expressions
Any other alternatives?
As long as you can guarantee it to be safe, I think you could use eval.
Maybe by treating it before doing an eval?
var test = "(true)&&(false)&&!(true||true)"
var safe = test.replace(/true/ig, "1").replace(/false/ig, "0");
var match = safe.match(/[0-9&!|()]*/ig);
if(match) {
var result = !!eval(match[0]);
}
Javascript has a ternary operator you could use:
var i = result ? 1 : 0;
Here, result is Boolean value either True or False.
So, Your question will be something like that after this operation.
(1)&(0)&!(1||1)
I hope you can better evaluate now this Boolean logic.
you can use eval,
Eg: eval("(true)&&(false)&&!(true||true)");
Try this code
function processExpression(expr)
{
while (expr.indexOf("(" ) != -1 )
{
expr = expr.replace(/\([\w|]+\)/g, function(matched){ return processBrace(matched)});
}
return expr = processBrace( "(" + expr + ")" );
}
function processBrace(str)
{
return str.substring(1).slice(0,-1).split(/(?=&|\|)/).map(function(value,index,arr){
if ( index != 0 && index%2 == 0 ) { return arr[index-1] + value } else if(index==0){return value;} else {return ""}
}).filter(function(val){return val.length > 0}).reduce(function(prev,current){
var first = Boolean(prev);
var operator = current.substring(0,2);
var operand = current.substring(2);
while ( operand.indexOf("!") != -1 )
{
var boolval = operand.match(/\w+/)[0] == "false"; //flip the value by comparing it with false
var negations = operand.match(/\W+/)[0];
operand = negations.substring(1) + boolval;
}
var second = operand == "true";
var output = operator == "&&" ? (first && second) : (first || second);
return output;
});
}
DEMO
function processExpression(expr)
{
while (expr.indexOf("(" ) != -1 )
{
expr = expr.replace(/\([\w|]+\)/g, function(matched){ return processBrace(matched)});
}
return expr = processBrace( "(" + expr + ")" );
}
function processBrace(str)
{
return str.substring(1).slice(0,-1).split(/(?=&|\|)/).map(function(value,index,arr){
if ( index != 0 && index%2 == 0 ) { return arr[index-1] + value } else if(index==0){return value;} else {return ""}
}).filter(function(val){return val.length > 0}).reduce(function(prev,current){
var first = Boolean(prev);
var operator = current.substring(0,2);
var operand = current.substring(2);
while ( operand.indexOf("!") != -1 )
{
var boolval = operand.match(/\w+/)[0] == "false"; //flip the value by comparing it with false
var negations = operand.match(/\W+/)[0];
operand = negations.substring(1) + boolval;
}
var second = operand == "true";
var output = operator == "&&" ? (first && second) : (first || second);
return output;
});
}
var example1 = "(true)&&(false)&&!(true||true)";
document.body.innerHTML += example1 + " -- " + processExpression(example1);
Try using "".match() in ternary operator condition
"(true)&&(true)&&!(true||true)".match(/false/ig)?false:true

Function call using a for loop to cycle through array not working, Help please

I'm very new to Javascript but I have a problem which I have spent all day trying to research and solve, like to do it myself but i'm very stuck.
My code is simple, I have created 5 functions, 1 tests for letters, one tests for numbers, 1 for an open bracket and 1 for a closed bracket, and the fifth spots a full stop. These functions return true.
I then created a function to call all of these functions when required to produce a numerical output depending on what is found in a text string.
Back to the top, I have a string, I created an array using split to place each of the characters in the string into the separate addresses in the array. The idea is that I use a for loop to scroll through the array and output the type into identity, which is then outputted in a list.
The issue is it will do the loop once then crash, and i can't find the problem, the issue lies in the line:
identity = isWhat(ModCompound[x],ModCompound[y]);
removing it with // and the for loop runs fine.
I would like to know why? what is the mistake?
code: (raw FORM)
<!DOCTYPE html>
<!--
Sjb 19/03/2015
-->
<html>
<head>
<title></title>
</head>
<body>
Chemicals
</br>
Compound: <input id="compound" value="NaCl.2(H20)">
<script>
var identity;
var x;
Compound = document.getElementById('compound').value;
ModCompound = Compound;
ModCompound = ModCompound.split('');
for (i = 0; i < Compound.length; i++){
x = i;
y = i;
document.write(i);
identity = isWhat(ModCompound[x],ModCompound[y]);
document.write(Math.random() + " : " + identity + "</p>");
}
ModCompound= ModCompound.join('');
// Custom Functions
function isWhat(n1,c1) //OUTPUT 1,2,9,0,8
{
if (isLetter(n1,c1) === true) {
return isWhat = 1;
//document.write = "L";
} //OUTPUT 1
if (isNumber(n1,c1) === true) {
return isWhat = 2;
//document.write = "N";
} //OUTPUT 2
if (isOpenBracket(n1,c1) === true){
return isWhat = 9;
//document.write("OB");
} //OUTPUT 9
if (isClosedBracket(n1,c1) === true) {
return isWhat = 0;
//document.write = "CB";
} //OUTPUT 0
if (isFullStop(n1,c1) === true) {
return isWhat = 8;
//document.write = "FS";
} //OUTPUT 8
}
function isNumber(n, c) //OUTPUT(s) TRUE
{
if (n >= 0 || n <= 9 ) {
//document.write(n + " N " + c + "</p>");
return isNumber = true;
}
}
function isLetter(n, c)
{
n = n.charCodeAt(0);
if (((n >= 65) && (n <= 90)) || ((n >= 97) && (n <= 122))) {
//document.write(n + " L " + c + "</p>");
return isLetter = true;
}
}
function isOpenBracket(n,c)
{
if (n === "(") {
//document.write(n + " OB " + c + "</p>");
return isOpenBracket = true;
}
}
function isClosedBracket(n,c)
{
if (n === ")") {
//document.write(n + " CB " + c + "</p>");
return isClosedBracket = true;
}
}
function isFullStop(n,c)
{
if (n === ".") {
//document.write(n + " F " + c + "</p>");
return isFullStop = true;
}
}
</script>
</body>
</html>
Your return statements should just be like this:
return 1;
You're writing this:
return isWhat = 1;
That's setting the variable isWhat to 1, then returning it. isWhat is a function, though, so setting it to 1 makes is so you can't call it (because now it's a number, not a function). Also, there's no need to type var===true, because if the variable is true, then var will evaluate to true and the if statement will run.

How to prepend a zero in front of any number below 10 in Javascript using Regexp

Good day,
Is there a Regex that I could use to prepend a 0 before any number that is below 10?
I am not looking for a date parsing library, ternary or if/else solutions. (hopefully)
var currentDate = new Date(),
stringDate = currentDate.getFullYear() + "-" + currentDate.getMonth() + "-" + currentDate.getDate() + " " + currentDate.getHours() + ":" + currentDate.getMinutes() + ":" + currentDate.getSeconds();
alert( stringDate ); //2011-10-17 10:3:7
I would like a RegExp that I could apply to stringDate to get 2011-10-17 10:03:07
Thank you very much!
Just add the leading 0 every time, then use slice(-2) to get the last two characters, like so:
('0' + currentDate.getHours()).slice(-2)
The following function will allow you to declare a minimum length for a number along or within a string and will pad it with zeros to make it the appropriate length.
var PrependZeros = function (str, len, seperator) {
if(typeof str === 'number' || Number(str)){
str = str.toString();
return (len - str.length > 0) ? new Array(len + 1 - str.length).join('0') + str: str;
}
else{
for(var i = 0,spl = str.split(seperator || ' '); i < spl.length; spl[i] = (Number(spl[i])&& spl[i].length < len)?PrependZeros(spl[i],len):spl[i],str = (i == spl.length -1)?spl.join(seperator || ' '):str,i++);
return str;
}
};
For those wanting a less cryptic version
var PrependZeros = function (str, len, seperator) {
if (typeof str === 'number' || Number(str)) {
str = str.toString();
return (len - str.length > 0) ? new Array(len + 1 - str.length).join('0') + str : str;
}
else {
var spl = str.split(seperator || ' ')
for (var i = 0 ; i < spl.length; i++) {
if (Number(spl[i]) && spl[i].length < len) {
spl[i] = PrependZeros(spl[i], len)
}
}
return spl.join(seperator || ' ');
}
};
Examples:
PrependZeros("1:2:3",2,":"); // "01:02:03"
PrependZeros(1,2); // "01"
PrependZeros(123,2); // "123"
PrependZeros("1 2 3",3); // "001 002 003"
PrependZeros("5-10-2012",2,"-"); //"05-10-2012"
You don't need regex for that. You can make a simple pad function yourself:
function pad(n) {
if (n < 10)
return "0" + n;
return n;
}
alert(pad(8));
alert(pad(11));
http://jsfiddle.net/DwnNG/
I now this is old, but I just saw this simple and clean solution used on the w3c and just had to share it somewhere.
var hours = currentDate.getHours();
(hours < 10 ? '0' : '') + hours;
How about:
x.replace(/^(\d)$/, "0$1");
I prefer Alex's way, but if you really want the regex way, you can try:
"2011-10-10 10:2:27".replace(/:(?=[^0](?::|$))/g, ":0");
That should do the work (it has an ternary operator in it, but also an regex^^)
stringDate.replace(/\d+/g, function(m) {
return parseInt(m, 10) < 10 ? "0" + m : m;
});
Are you ready for your one-liner do-it-all regex solution?
Pass in your entire string... and this will match single-digits and pad them with a 0.
"2011-10-17 10:3:7"
.replace(/(^|[^0-9])([0-9])(?=($|[^0-9]))/ig, function ($0, $1) {
return $0[0] + '0' + $0[1];
});
//returns "2011-10-17 10:03:07"
This would be made so much easier if JavaScript supported lookbehind-assertions.
%0{length} => %05 => 1=00001, 2=00002,... 55=00055,...

Add commas or spaces to group every three digits

I have a function to add commas to numbers:
function commafy( num ) {
num.toString().replace( /\B(?=(?:\d{3})+)$/g, "," );
}
Unfortunately, it doesn't like decimals very well. Given the following usage examples, what is the best way to extend my function?
commafy( "123" ) // "123"
commafy( "1234" ) // "1234"
// Don't add commas until 5 integer digits
commafy( "12345" ) // "12,345"
commafy( "1234567" ) // "1,234,567"
commafy( "12345.2" ) // "12,345.2"
commafy( "12345.6789" ) // "12,345.6789"
// Again, nothing until 5
commafy( ".123456" ) // ".123 456"
// Group with spaces (no leading digit)
commafy( "12345.6789012345678" ) // "12,345.678 901 234 567 8"
Presumably the easiest way is to first split on the decimal point (if there is one). Where best to go from there?
Just split into two parts with '.' and format them individually.
function commafy( num ) {
var str = num.toString().split('.');
if (str[0].length >= 5) {
str[0] = str[0].replace(/(\d)(?=(\d{3})+$)/g, '$1,');
}
if (str[1] && str[1].length >= 5) {
str[1] = str[1].replace(/(\d{3})/g, '$1 ');
}
return str.join('.');
}
Simple as that:
var theNumber = 3500;
theNumber.toLocaleString();
Here are two concise ways I think maybe useful:
Number.prototype.toLocaleString
This method can convert a number to a string with a language-sensitive representation. It allows two parameters, which is locales & options. Those parameters may be a bit confusing, for more detail see that doc from MDN above.
In a word, you could simply use is as below:
console.log(
Number(1234567890.12).toLocaleString()
)
// log -> "1,234,567,890.12"
If you see different with me that because we ignore both two parameters and it will return a string base on your operation system.
Use regex to match a string then replace to a new string.
Why we consider this? The toLocaleString() is a bit confusing and not all browser supported, also toLocaleString() will round the decimal, so we can do it in another way.
// The steps we follow are:
// 1. Converts a number(integer) to a string.
// 2. Reverses the string.
// 3. Replace the reversed string to a new string with the Regex
// 4. Reverses the new string to get what we want.
// This method is use to reverse a string.
function reverseString(str) {
return str.split("").reverse().join("");
}
/**
* #param {string | number}
*/
function groupDigital(num) {
const emptyStr = '';
const group_regex = /\d{3}/g;
// delete extra comma by regex replace.
const trimComma = str => str.replace(/^[,]+|[,]+$/g, emptyStr)
const str = num + emptyStr;
const [integer, decimal] = str.split('.')
const conversed = reverseString(integer);
const grouped = trimComma(reverseString(
conversed.replace(/\d{3}/g, match => `${match},`)
));
return !decimal ? grouped : `${grouped}.${decimal}`;
}
console.log(groupDigital(1234567890.1234)) // 1,234,567,890.1234
console.log(groupDigital(123456)) // 123,456
console.log(groupDigital("12.000000001")) // 12.000000001
Easiest way:
1
var num = 1234567890,
result = num.toLocaleString() ;// result will equal to "1 234 567 890"
2
var num = 1234567.890,
result = num.toLocaleString() + num.toString().slice(num.toString().indexOf('.')) // will equal to 1 234 567.890
3
var num = 1234567.890123,
result = Number(num.toFixed(0)).toLocaleString() + '.' + Number(num.toString().slice(num.toString().indexOf('.')+1)).toLocaleString()
//will equal to 1 234 567.890 123
4
If you want ',' instead of ' ':
var num = 1234567.890123,
result = Number(num.toFixed(0)).toLocaleString().split(/\s/).join(',') + '.' + Number(num.toString().slice(num.toString().indexOf('.')+1)).toLocaleString()
//will equal to 1,234,567.890 123
If not working, set the parameter like: "toLocaleString('ru-RU')"
parameter "en-EN", will split number by the ',' instead of ' '
All function used in my code are native JS functions. You'll find them in GOOGLE or in any JS Tutorial/Book
If you are happy with the integer part (I haven't looked at it closly), then:
function formatDecimal(n) {
n = n.split('.');
return commafy(n[0]) + '.' + n[1];
}
Of course you may want to do some testing of n first to make sure it's ok, but that's the logic of it.
Edit
Ooops! missed the bit about spaces! You can use the same regular exprssion as commafy except with spaces instead of commas, then reverse the result.
Here's a function based on vol7ron's and not using reverse:
function formatNum(n) {
var n = ('' + n).split('.');
var num = n[0];
var dec = n[1];
var r, s, t;
if (num.length > 3) {
s = num.length % 3;
if (s) {
t = num.substring(0,s);
num = t + num.substring(s).replace(/(\d{3})/g, ",$1");
} else {
num = num.substring(s).replace(/(\d{3})/g, ",$1").substring(1);
}
}
if (dec && dec.length > 3) {
dec = dec.replace(/(\d{3})/g, "$1 ");
}
return num + (dec? '.' + dec : '');
}
I have extended #RobG's answer a bit more and made a sample jsfiddle
function formatNum(n, prec, currSign) {
if(prec==null) prec=2;
var n = ('' + parseFloat(n).toFixed(prec).toString()).split('.');
var num = n[0];
var dec = n[1];
var r, s, t;
if (num.length > 3) {
s = num.length % 3;
if (s) {
t = num.substring(0,s);
num = t + num.substring(s).replace(/(\d{3})/g, ",$1");
} else {
num = num.substring(s).replace(/(\d{3})/g, ",$1").substring(1);
}
}
return (currSign == null ? "": currSign +" ") + num + (dec? '.' + dec : '');
}
alert(formatNum(123545.3434));
alert(formatNum(123545.3434,2));
alert(formatNum(123545.3434,2,'€'));
and extended same way the #Ghostoy's answer
function commafy( num, prec, currSign ) {
if(prec==null) prec=2;
var str = parseFloat(num).toFixed(prec).toString().split('.');
if (str[0].length >= 5) {
str[0] = str[0].replace(/(\d)(?=(\d{3})+$)/g, '$1,');
}
if (str[1] && str[1].length >= 5) {
str[1] = str[1].replace(/(\d{3})/g, '$1 ');
}
return (currSign == null ? "": currSign +" ") + str.join('.');
}
alert(commafy(123545.3434));
Here you go edited after reading your comments.
function commafy( arg ) {
arg += ''; // stringify
var num = arg.split('.'); // incase decimals
if (typeof num[0] !== 'undefined'){
var int = num[0]; // integer part
if (int.length > 4){
int = int.split('').reverse().join(''); // reverse
int = int.replace(/(\d{3})/g, "$1,"); // add commas
int = int.split('').reverse().join(''); // unreverse
}
}
if (typeof num[1] !== 'undefined'){
var dec = num[1]; // float part
if (dec.length > 4){
dec = dec.replace(/(\d{3})/g, "$1 "); // add spaces
}
}
return (typeof num[0] !== 'undefined'?int:'')
+ (typeof num[1] !== 'undefined'?'.'+dec:'');
}
This worked for me:
function commafy(inVal){
var arrWhole = inVal.split(".");
var arrTheNumber = arrWhole[0].split("").reverse();
var newNum = Array();
for(var i=0; i<arrTheNumber.length; i++){
newNum[newNum.length] = ((i%3===2) && (i<arrTheNumber.length-1)) ? "," + arrTheNumber[i]: arrTheNumber[i];
}
var returnNum = newNum.reverse().join("");
if(arrWhole[1]){
returnNum += "." + arrWhole[1];
}
return returnNum;
}
Assuming your usage examples are not representative of already-working code but instead desired behavior, and you are looking for help with the algorithm, I think you are already on the right track with splitting on any decimals.
Once split, apply the existing regex to the left side, a similiar regex adding the spaces instead of commas to the right, and then rejoin the the two into a single string before returning.
Unless, of course, there are other considerations or I have misunderstood your question.
This is basically the same as the solution from Ghostoy, but it fixes an issue where numbers in the thousands are not handled properly. Changed '5' to '4':
export function commafy(num) {
const str = num.toString().split('.');
if (str[0].length >= 4) {
str[0] = str[0].replace(/(\d)(?=(\d{3})+$)/g, '$1,');
}
if (str[1] && str[1].length >= 4) {
str[1] = str[1].replace(/(\d{3})/g, '$1 ');
}
return str.join('.');
}
//Code in Java
private static String formatNumber(String myNum) {
char[] str = myNum.toCharArray();
int numCommas = str.length / 3;
char[] formattedStr = new char[str.length + numCommas];
for(int i = str.length - 1, j = formattedStr.length - 1, cnt = 0; i >= 0 && j >=0 ;) {
if(cnt != 0 && cnt % 3 == 0 && j > 0) {
formattedStr[j] = ',';
j--;
}
formattedStr[j] = str[i];
i--;
j--;
cnt++;
}
return String.valueOf(formattedStr);
}
You can do it mathematically, depending on how many digits you want to separate, you can start from one digit with 10 to 100 for 2, and so on.
function splitDigits(num) {
num=Math.ceil(num);
let newNum = '';
while (num > 1000){
let remain = num % 1000;
num = Math.floor(num / 1000);
newNum = remain + ',' + newNum;
}
return num + ',' + newNum.slice(0,newNum.length-1);
}
At first you should select the input with querySelector like:
let field = document.querySelector("input");
and then
field.addEventListener("keyup", () => {
for (let i = 1 ; i <= field.value.length; i++) {
field.value = field.value.replace(",", "");
}
let counter=0;
for (let i = 1 ; i <= field.value.length; i++) {
if ( i % ((3 * (counter+1) ) + counter) ===0){
let tempVal =field.value
field.value = addStr(tempVal,field.value.length - i,",")
counter++;
console.log(field.value);
}
}
// field.value = parseInt(field.value.replace(/\D/g, ''), 10);
// var n = parseInt(e.target.value.replace(/\D/g,''),10);
// e.target.value = n.toLocaleString();
});

Categories

Resources