blog bg

November 14, 2023

JavaScript: Numbers, Dates and Timers

Share what you learn in this blog to prepare for your interview, create your forever-free profile now, and explore how to monetize your valuable knowledge.

In this article, we will be looking into two additional ways of representing data which are numbers and dates. These  might be a bit less important than things like strings, objects and arrays but, still we should know to use them and also we will be looking into internationalization and timers. 

 

Converting and Checking Numbers

In this section, we will be learning how to convert values to number and also how to check if certain values are number or not.

In JavaScript, all numbers are presented internally as floating point numbers. So basically, always as decimals no matter if we actually write them as integers or as decimals. for example,

console.log(60 === 60.00);//true

As you can see 60 is, in fact, the same as 60.00. Also, numbers are represented internally in a 64 base 2 format so that, numbers are always stored in a binary format. However, there are some numbers that are very difficult yo represent in base 2, for example

console.log(0.1 + 0.2);//0.30000000000000004

As you can see that, the result should be 0.3 and not with all of these zeros here. But JavaScript, simply has no better way of representing this number. In some cases, JavaScript does some rounding behind the scenes to try its best to hide these problems but in some cases like above example, simply can't do it. So, just be aware that, we can't do like really precise scientific or financial calculations in JavaScript because eventually, we will run into a problem like this. for example,

console.log((0.1 + 0.2) === 0.3);//false

 

Convert a String to a Number

#Number()

The Number() function will convert the strings to number. If the value can't be converted from string to number, the it will return NaN

For example, 

let str1 = "234  "

let number1 = Number(str1);
console.log(number1);//234
console.log(typeof number1);//number

let str2 = "234px"

let number2 = Number(str2);
console.log(number2);//NaN

 

#Unary Operator(+)

The (+) Operator works exactly same like Number() function.

For example, 

let str1 = "234  "

let number1 = +str1;
console.log(number1);//234
console.log(typeof number1);//number

let str2 = "234px"

let number2 = +str2;
console.log(number2);//NaN

console.log(+" ");//0

 

#parseInt()

The parseInt() method convert a string to a number. However, unlike Number()/+ Operator, this method accept symbols and also allows spaces and then JavaScript automatically try to figure out the number from the string. However, this method has some limitations which are,

  • If we pass decimal numbers, then it will be rounded off to the nearest integers
  • It will return only the first number from the string
  • If the string not start with number then It will return NaN. So, the string should start with number
For example,
console.log(parseInt("234px"));//234
console.log(parseInt("234.30"));//234
console.log(parseInt("23ad4"));//23
console.log(parseInt("as23ad4"));//NaN

 

#parseFloat()

The parseFloat() works exactly same like parseInt() function, but the difference is that this function will return the decimal if the string has decimal. In other words, this function will not ignore the decimals,

Key points,

  • If we pass decimal numbers, then it will return the decimals,
  • It will return only the first number from the string
  • If the string not start with number then It will return NaNSo, the string should start with number
For example,
console.log(parseFloat("234px"));//234
console.log(parseFloat("234.30"));//234.3
console.log(parseFloat("23ad4"));//23
console.log(parseFloat("as23ad4"));//NaN

 

Check if the value is a number

#isNaN()

This function allows us to check if the given value is a Number or not. If the function returns true, the the given value is not a number and if it returns false, then the given value is a number. Also, this function will convert the value to a number if necessary before determine if the value is a number or not.

For example,

console.log(isNaN(20));//false
console.log(isNaN('20'));//false
console.log(isNaN('20x'));//true

 

#isFinite()

This function allows us to check if the given value is a Finite or not. If the function returns true, the the given value is  a finite number and if it returns false, then the given value is not a finite number. Also, this function will convert the value to a number if necessary before determine if the value is a finite number or not.

For example,

console.log(isFinite(20));//true
console.log(isFinite('20'));//true
console.log(isFinite('20x'));//false
console.log(isFinite(20 / 0));//false


 #Number.isInteger()

This function allows us to check if the given value is an Integer. If the function returns true, the the given value is an Integer and if it returns false, then the given value is not  an Integer

For example,

console.log(Number.isInteger(20));//true
console.log(Number.isInteger(20.23));//false
console.log(Number.isInteger('20'));//false
console.log(Number.isInteger(20 / 0));//false

 


Math and Rounding

#Math.sqrt()

This function returns the square root of the number

For example,

console.log(Math.sqrt(4));//2
console.log(Math.sqrt(25));//5


 #Math.max()

This function returns the largest number of the numbers passes as input parameters. 

For example,

console.log(Math.max(4,25,18,67));//67
const numbers = [34,768,54,678]
console.log(Math.max(...numbers));//768

console.log(Math.max(4,25,18,"67"));//67
console.log(Math.max(4,25,18,"67px"));//NaN


 #Math.min()

This function returns the smallest number of the numbers passes as input parameters. 

For example,

console.log(Math.min(4,25,18,67));//4
const numbers = [34,768,54,678]
console.log(Math.min(...numbers));//34

console.log(Math.min("4",25,18,67));//4
console.log(Math.min("4px",25,18,67));//NaN


 #Math.PI

This function is actually a constant data property that gives us the ratio of the circumference of the circle(3.14). 

For example,

const calculateCircumference = (radius) => 2 * Math.PI * radius;

console.log(calculateCircumference(5));//31.41592653589793


 #Math.random()

This function will give us a random number between 0 and 1

For example,

console.log(Math.random());//0.7403075925361469
console.log(Math.random());//0.3673234727403376


 #Math.trunc()

This function will remove the decimal part and returns the integer part

For example,

console.log(Math.trunc(22.23343434));//22
console.log(Math.trunc(Math.random() * 6));//5

 

Exercise,

Let's create a function where we will pass a minimum and maximum number and then we want to return a random number between this range, 

const randomInt = (min , max) => Math.trunc(Math.random() * (max - min) + 1) + min

console.log(randomInt(10,20));//14
console.log(randomInt(10,20));//13
console.log(randomInt(10,20));//11


 

Rounding Integers

#Math.round()

This function will always round the number to the nearest integer

For example,

console.log(Math.round(23.51));//24
console.log(Math.round(23.49));//23
console.log(Math.round(-23.51));//-24
console.log(Math.round(-23.49));//-23


 #Math.ceil()

This function will always round the number and returns the smallest integer that is greater than or equals to the given number . In other words, it always round up the number. 

For example,

console.log(Math.ceil(23.51));//24
console.log(Math.ceil(23.49));//24
console.log(Math.ceil(-23.51));//-23
console.log(Math.ceil(-23.49));//-23


 #Math.floor()

This function will always round the number and returns the largest integer that is less than than or equals to the given number. In other words, it always round down the number to the nearest number. 

For example,

console.log(Math.floor(23.51));//23
console.log(Math.floor(23.49));//23
console.log(Math.floor(-23.51));//-24
console.log(Math.floor(-23.49));//-24

NOTE: We might think that Math.floor() and Math.trunc() are very similar. They are actually working same if we are dealing with positive numbers but when we are working with negative numbers, they are not working same. For example,

//positive numbers
console.log(Math.floor(23.51));//23
console.log(Math.trunc(23.51));//23
console.log(Math.floor(23.49));//23
console.log(Math.trunc(23.49));//23

//negative numbers
console.log(Math.floor(-23.51));//-24
console.log(Math.trunc(-23.51));//-23
console.log(Math.floor(-23.49));//-24
console.log(Math.trunc(-23.49));//-23


 

Rounding floating point numbers(decimals)

#toFixed()

This function formats the number using fixed-point notation and returns a string representing the given number using fixed-point notation. This function will accept one parameter where we will specify the number of digits to appear after the decimal point. Since this parameter is optional, the default value is 0. For example,

let formattedNumber = (20.4645654).toFixed(2)
console.log(formattedNumber);//20.46
console.log(typeof formattedNumber);//string

We can then use parseFloat()/Number()/+ to convert the string that is generated from toFixed() into floating number.

let floatingNumber = parseFloat(formattedNumber);
console.log(floatingNumber);//20.46
console.log(typeof floatingNumber);//number

NOTE:- From the above example, we called the toFixed() method on 20.4645654 and this is actually a primitive. As we learned earlier, primitives actually don't have methods. So, behind the scenes, JavaScript will do boxing, which is to transform this to a number object, then call the method on that object and then once the operation is finished, it will convert it back to a primitive.

 

#Remainder(%)

The remainder operator, simply returns the remainder of a division

For example,

console.log(13 % 5);//3 => 5 * 2 + 3
console.log(10 % 2);//0 => 5 * 2 + 0

The most used cases of remainder operator is to check if the given number is even or odd.

const isEven = num => num % 2 === 0 ? "It is an even number" : "It is a odd number";
console.log(isEven(8));//It is an even number
console.log(isEven(37));//It is a odd number
console.log(isEven(14));//It is an even number


 

Numeric Separators

This feature allows us to format numbers in a way that is easier for us or others to read and to understand. Let's say, we wanted to represent a really large number. for example, 

const amount = 28000000

As you can see, it's really difficult to read and to understand it as there is just too many zeros. Generally, when we write a large number, we usually use a thousand separator like the comma. Fortunately, we can do the same thing in JavaScript using the numeric separators. Numeric separators are simply underscores(_) that we can place anywhere that we want in numbers, which will make it really easy to understand. 

For example,

const amount = 28_000_000
console.log(amount);//28000000

When we log amount to the console, we can see that, the engine basically ignores these underscores. So, these numeric separators, it simply sees the number itself

NOTE: We are not allowed to put underscore at the beginning of a number or at the end and all of these are illegal.

const amount = 1500_
console.log(amount);//ERROR: SyntaxError: Numeric separators are not allowed at the end of numeric literals

const amount1 = _1500
console.log(amount1);//ERROR

 

Working with BigInt

It's actually one of the primitive data types and special types of integers that was introduced in 2020. The numbers are represented internally as 64 bits, means that, there are exactly 64 ones or zeros to represent any given number. In these 64 bits, only 53 are used to actually store the digits themselves. The rest are for storing the position of the decimal point and the sign. Now, if there are only 53 bits to store the number, that means, there is a limit of how big numbers can be and we can calculate that number and that's two elevated to 53 and then minus one( 2 ** 53  -1), because the numbers starts at zero. So, this is essentially the biggest number that JavaScript can safely represent.

console.log(Number.MAX_SAFE_INTEGER);//9007199254740991
console.log(2 ** 53 - 1);//9007199254740991

As you can see, that number is even stored into the number namespace as MAX_SAFE_INTEGER. So, any integer that is larger than this, it is not safe that means, it can't be represented accurately. 

For example, 

console.log(2 ** 53);//9007199254740992
console.log(2 ** 53 + 1);//9007199254740992

As you can see that, both are giving the same numbers, meaning that JavaScript can simply not represent these numbers accurately and if we do calculations with these numbers that are bigger than MAX_SAFE_INTEGER, then we might lose precision. However, in some numbers it does actually work for some reason, that's because JavaScript behind the scenes uses some tricks to still represent some of the unsafe numbers. But, sometime it works and sometime it does not, that's why we call these as unsafe numbers. 

For example,

console.log(2 ** 53 - 1);//9007199254740991
console.log(2 ** 53 + 1);//9007199254740992
console.log(2 ** 53 + 2);//9007199254740994
console.log(2 ** 53 + 3);//9007199254740996
console.log(2 ** 53 + 4);//9007199254740996

However, in some situations, we might need really big numbers, for example, database IDs. How can we store these numbers in JavaScript?. Well, to handle these numbers a new primitive was added that called BigInt, which stands for big integer and it can be used to store numbers as large as we want. 

For example,

console.log(23423543534542331242353425423423423543534);//2.342354353454233e+40
console.log(23423543534542331242353425423423423543534n);//23423543534542331242353425423423423543534n

As you can see that, if we use n at the end of the big numbers, it will transform a regular number into a BigInt number. However, when you see the result, it also looks different, but now JavaScript has a way of finally displaying the large number accurately.

We can also create BigInt by using BigInt() function. 

For example,

console.log(23423543534542331242353425423423423543534);//2.342354353454233e+40
console.log(BigInt(23423543534542331242353425423423423543534));//23423543534542331242353425423423423543534n

NOTE: All the operators still work the some on BigInt numbers, but it is not possible to mix BigInt with regular numbers except logical operators and string concatenations

console.log(10000n + 10000n);//20000n
console.log(2324324342342342n * 3423423423423n);//7957146397207033484287476666n

// console.log(34234234234n * 12);//Error
console.log(34234234234n * BigInt(12));//410810810808n

console.log(20n > 15);//true
console.log(20n == 20);//true
console.log(20n === 20);//false => === will check the data type as well
console.log(typeof 20n);//bigint
console.log(typeof 20);//number

console.log(34234234234n + " this is test");//34234234234 this is test
console.log(Math.sqrt(16n));//ERROR

Finally, let's take a look at what happens with divisions because BigInt is indeed an integer. So, we devide BigInt numbers, it simply basically cuts the decimal part off

For example,

console.log(11n / 3n);//3n
console.log(28n / 5n);//5n


 

Working with Dates

#Create Dates using Date() constructor

const now = new Date();
console.log(now);//2023-10-19T15:08:55.269Z
console.log(now.toString());//Thu Oct 19 2023 15:12:03 GMT+0000 (Coordinated Universal Time)

console.log(new Date("Oct 19 2023 01:30:50"));//2023-10-19T01:30:50.000Z

console.log(new Date("December 24, 2023"));//2023-12-24T00:00:00.000Z

console.log(new Date("2023-10-19T01:30:50.000Z"));//2023-10-19T01:30:50.000Z
console.log(new Date("2023-10-19T01:30:50.000Z").toString());//Thu Oct 19 2023 01:30:50 GMT+0000 (Coordinated Universal Time)

console.log(new Date(2023, 10, 22, 15, 23, 21));//2023-11-22T15:23:21.000Z

//JavaScript will auto correct the date
console.log(new Date(2023, 10, 32));//2023-12-02T00:00:00.000Z

//passing milliseconds
console.log(new Date(0));//1970-01-01T00:00:00.000Z
console.log(new Date(10 * 24 * 60 *60 * 1000));//1970-01-11T00:00:00.000Z

 

consider following date

const now = new Date();
console.log(now);//2023-10-19T15:23:18.438Z
  • Get Year from the Date
console.log(now.getFullYear());//2023
  • Get Month index from the Date
console.log(now.getMonth());//9
  • Get Date of the month from the Date
console.log(now.getDate());//19
  • Get Hours from the Date
console.log(now.getHours());//15
  • Get Minutes from the Date
console.log(now.getMinutes());//23
  • Get Seconds from the Date
console.log(now.getSeconds());//18
  • Get Milliseconds from the Date
console.log(now.getMilliseconds());//438
  • Get Day of the week from the Date
console.log(now.getDay());//4
  • Get ISO String of the Date
console.log(now.toISOString());//2023-10-19T15:23:18.438Z
  • Get the timestamp for the Date
console.log(now.getTime());//1697729455102

If you are interested in  even more methods, then check out the documentation in MDN


 #Internationalizing Dates(INTL)

In this section, we are going to see to format the date and time. The Intl.DateTimeFormat object allows us to format the date and time  in JavaScript.

Using Locales

In order to get the format of the language used in the user interface of your application, make sure to specify the languages using the locales argument. For example,

const today = new Date();

//US uses month-day-year order
console.log("US: "+new Intl.DateTimeFormat('us-US').format(today));//US: 10/20/2023

//German uses day-month-year order
console.log("Germany: "+new Intl.DateTimeFormat('de-DE').format(today));//Germany: 20.10.2023

//UK uses day-month-year order
console.log("UK: "+new Intl.DateTimeFormat('en-GB').format(today));//UK: 20/10/2023

NOTE: The locale is usually the language and then dash(-) the country. Click here to find the list of ISO language codes and you can find codes to experiment


 We can actually take it to the next level by adding some options to customize the date and time a little bit

For example,

const today = new Date();

const options = {
  hour:'numeric',
  minute:"numeric"
}

//US uses month-day-year order
console.log("US: "+new Intl.DateTimeFormat('us-US',options).format(today));//US: 9:48 AM

//German uses day-month-year order
console.log("Germany: "+new Intl.DateTimeFormat('de-DE',options).format(today));//Germany: 09:48

//UK uses day-month-year order
console.log("UK: "+new Intl.DateTimeFormat('en-GB',options).format(today));//UK: 09:48

As you can see that,  now we will get the time from the date as we specified only hour, minute in the option. We can also specify properties for each weekdays, year, month ,day and more.

For example,

const today = new Date();

const options = {
  hour:'numeric',
  minute:"numeric",
  day: "numeric"
}

//US uses month-day-year order
console.log("US: "+new Intl.DateTimeFormat('us-US',options).format(today));//US: 20, 9:52 AM

Month

const today = new Date();

const options = {
  hour:'numeric',
  minute:"numeric",
  day: "numeric",
  month:"numeric"
}

//US uses month-day-year order
console.log("US: "+new Intl.DateTimeFormat('us-US',options).format(today));//US: 10/20, 9:53 AM
const today = new Date();

const options = {
  hour:'numeric',
  minute:"numeric",
  day: "numeric",
  month:"long"
}

//US uses month-day-year order
console.log("US: "+new Intl.DateTimeFormat('us-US',options).format(today));//US: October 20, 9:56 AM

Year and Weekday

const today = new Date();

const options = {
  hour:'numeric',
  minute:"numeric",
  day: "numeric",
  month:"long",
  year:"numeric",
  weekday:"long"
}

//US uses month-day-year order
console.log("US: "+new Intl.DateTimeFormat('us-US',options).format(today));//US: Friday, October 20, 2023, 9:57 AM
If you are interested in  even more properties, then check out the documentation in MDN

 

#Internationalizing Numbers(INTL)

In this section, we are going to see to format the regular numbers. The Intl.NumberFormat object allows us to format the numbers in JavaScript

Using Locales

In order to get the format of the language used in the user interface of your application, make sure to specify the languages using the locales argument. For example,

const num = 324324234.23;

//US uses comma for thousands and period for decimal sepeator
console.log("US: "+new Intl.NumberFormat('us-US').format(num));//324,324,234.23

//German uses comma as decimal sepeator and period for thousands
console.log("Germany: "+new Intl.NumberFormat('de-DE').format(num));//324.324.234,23

// Arabic in most Arabic speaking countries uses real Arabic digits
console.log("Arabic: "+new Intl.NumberFormat('ar-EG').format(num));//ÃÆââ

We can also define options for the number formatting. In this option, we can specify,

  • Style: The formatting style to use
    • decimal: This is the default value and used for plain number formatting
    • currency: This is used to format the currency
    • percent: This is used to format the percent
    • unit: This is used to format unit like mile-per-hour

Let's see some examples with units,

When we set unit style, then web need to specify the unit type. 

const num = 324324234.23;

const options = {
  style: "unit",
  unit:"mile-per-hour"
}
console.log("US: "+new Intl.NumberFormat('us-US',options).format(num));//US: 324,324,234.23 mph
console.log("Germany: "+new Intl.NumberFormat('de-DE',options).format(num));//Germany: 324.324.234,23 mi/h
console.log("Arabic: "+new Intl.NumberFormat('ar-EG',options).format(num));//Arabic: ÃÆââ

As you can see we get the unit with numbers, and it changed based on the locale.

Let's try this example for temperature,

const num = 324324234.23;

const options = {
  style: "unit",
  unit:"celsius"
}
console.log("US: "+new Intl.NumberFormat('us-US',options).format(num));//US: 324,324,234.23
console.log("Germany: "+new Intl.NumberFormat('de-DE',options).format(num));//Germany: 324.324.234,23 
console.log("Arabic: "+new Intl.NumberFormat('ar-EG',options).format(num));//Arabic:ÃÆââ

 

Let's see some examples with percent,

When we set percent in style, then the unit is completely ignored and we will get the percentage sign with number. 

const num = 324324234.23;

const options = {
  style: "percent"
}
console.log("US: "+new Intl.NumberFormat('us-US',options).format(num));//32,432,423,423%
console.log("Germany: "+new Intl.NumberFormat('de-DE',options).format(num));//32.432.423.423 %

As you can see, there is a space between the percentage sign and the number for Germany. So, it is different in different countries

 

Let's see some examples with currency,

When we set percent in style, then the unit is completely ignored but we will have to define the currency. 

const num = 324324234.23;

const options = {
  style: "currency",
  currency:"EUR"
}
console.log("US: "+ new Intl.NumberFormat('us-US',options).format(num));//US: 324,324,234.23
console.log("Germany: "+ new Intl.NumberFormat('de-DE',options).format(num));//Germany: 324.324.234,23

As you can see, EUR currency sign comes before the number in US and comes after in Germany.

Finally, we can also turn of or on the grouping, meaning that whether to use grouping separators, such as thousands separators.

For example,

const num = 324324234.23;

const options = {
  style: "currency",
  currency:"EUR",
  useGrouping:false
}
console.log("US: "+ new Intl.NumberFormat('us-US',options).format(num));//US: 324324234.23
console.log("Germany: "+ new Intl.NumberFormat('de-DE',options).format(num));//Germany: 324324234,23

When we set useGrouping to false, number is just printed as it is without separators.

If you are interested in  even more properties, then check out the documentation in MDN


 

Timers: SetTimeout and SetInterval

We have two kind of times which are,

  • setTimeOut(): This timer runs just one, after a defined time expires.
  • setInterval(): This timer keeps running basically forever, with a fixed time delay between each call, until we stop it.

 

#setTimeout()

This function receives a callback function and the amount of milliseconds as the second argument. So, the callback function will be executed once the time we specified as the second argument expires. 

For example,

setTimeout(() => {
  console.log("I am here!");
}, 500);

As you can see that, after 500 milliseconds(0.5 second), we get the message "I am here" to the console. So, basically with setTimeout(), we delay calling the function  after a specified time.

When the execution of our code reaches the point where we use setTimeout(), it will simply call the setTimeout function and it will then essentially register this callback function to be called later and then the code execution simply continues, meaning that the code execution does not stop until the callback function is called. This mechanism is called Asynchronous JavaScript. 

For example,

setTimeout(() => {
  console.log("I am inside!");
}, 500);
console.log("I am outside!");

Output:

I am outside!
I am inside!

What if we want to pass some arguments into the callback function?. Because we are not calling the callback function ourselves, therefore, we can not pass in any arguments into the function. Actually we have a solution for that, that is all the arguments we pass after the delay time(second argument) will be the arguments to the callback function. For example,

setTimeout((name,time) => {
  console.log(`Hey! ${name} is coming at ${time} today`);
}, 500,"John","5.30");

Output:

Hey! John is coming at 5.30 today

We can  also assign setTimeout() function, which is essentially the timer to a variable. We can use that variable to clear the timeout and for that, we use clearTimeout()

For example,

let timer;

timer = setTimeout((name,time,timer) => {
  console.log(`Hey! ${name} is coming at ${time} today`);
  clearTime();
}, 500,"John","5.30");

const clearTime = () => {
  clearTimeout(timer)
}


 #setInterval()

setInterval(() => {
  console.log('it will run after evey one second!!');
},1000)

As you can see that, the calllback function will be executed after every one second. We can remove it late by calling clearInterval()

Next ArticleJavaScript: Object-Oriented Programming(OOP)

 

398 views

Please Login to create a Question