Chapter 8
IN THIS CHAPTER
Manipulating strings
Working with dates and times
Performing math calculations
First learn computer science and all the theory. Next develop a programming style. Then forget all that and just hack.
— GEORGE CARRETTE
Although your JavaScript code will spend much of its time dealing with web page knickknacks such as HTML tags and CSS properties, it will also perform lots of behind-the-scenes chores that require manipulating strings, dealing with dates and times, and performing mathematical calculations. To help you through these tasks, in this chapter you explore three of JavaScript’s built-in objects: the String object, the Date object, and the Math object. You investigate the most important properties of each object, master the most used methods, and see lots of useful examples along the way.
I’ve used dozens of examples of strings so far in this book. These have included not only string literals (such as "Web Coding and Development for Dummies"
), but also methods that return strings (such as the prompt()
method). So it should be clear by now that strings play a major role in all JavaScript programming, and it will be a rare script that doesn't have to deal with strings in some fashion.
For this reason, it pays to become proficient at manipulating strings, which includes locating text within a string and extracting text from a string. You learn all of that and more in this section.
Any string you work with — whether it’s a string literal or the result of a method or function that returns a string — is a String
object. So, for example, the following two statements are equivalent:
var bookName = new String("Web Coding and Development for Dummies");
var bookName = "Web Coding and Development for Dummies";
This means that you have quite a bit of flexibility when applying the properties and methods of String
objects. For example, the String
object has a length
property that I describe in the next section. The following are all legal JavaScript expressions that use this property:
bookName.length;
"Web Coding and Development for Dummies".length;
prompt("Enter the book name:").length;
myFunction().length;
The last example assumes that myFunction()
returns a string value.
The most basic property of a String
object is its length
, which tells you how many characters are in the string:
string.length
All characters within the string — including spaces and punctuation marks — are counted toward the length. The only exceptions are escape sequences (such as
), which always count as one character. The following code grabs the length property value for various String object types.
function myFunction() {
return "filename.htm";
}
var bookName = "Web Coding and Development for Dummies";
length1 = myFunction().length; // Returns 12
length2 = bookName.length; // Returns 38
length3 = "123
5678".length; // Returns 8
What the String
object lacks in properties it more than makes up for in methods. There are over two dozen, and they enable your code to perform many useful tasks, from converting between uppercase and lowercase letters, to finding text within a string, to extracting parts of a string.
A substring is a portion of an existing string. For example, substrings of the string "JavaScript"
would be "Java"
, "Script"
, "vaSc"
, and "v"
. When working with strings in your scripts, you'll often have to determine whether a given string contains a given substring. For example, if you’re validating a user’s email address, you should check that it contains an @ symbol.
Table 8-1 lists the two String
object methods that find substrings within a larger string.
TABLE 8-1 String Object Methods for Finding Substrings
Method |
What It Does |
|
Searches |
|
Searches |
You'll use both of these methods quite often in your scripts, so I take a closer look at each one.
When you want to find the first instance of a substring, or if all you want to know is whether a string contains a particular substring, use the indexOf()
method; if you need to find the last instance of a substring, use the lastIndexOf()
method:
string.indexOf(substring, start)
string.lastIndexOf(substring, start)
string
: The string in which you want to search.substring
: The substring that you want to search for in string
.start
: An optional character position from which the search begins. If you omit this argument, JavaScript starts the search from the beginning of the string.Here are some notes you should keep in mind when using indexOf()
or lastIndexOf()
:
B
, neither method will find any instances of b
.substring
, they return the index position of the first character of substring
.substring
, they return -1.The following code tries out these methods in a few different situations.
HTML:
<pre>
Web Coding and Development for Dummies
01234567890123456789012345678901234567
</pre>
<div id="output"></div>
JavaScript:
var bookName = "Web Coding and Development for Dummies";
var str = ""C" is at index " + bookName.indexOf("C") + "<br>";
str += ""v" is at index " + bookName.indexOf("v") + "<br>";
str += "The first space is at index " + bookName.indexOf(" ") + "<br>";
str += "The first "D" is at index " + bookName.indexOf("D") + "<br>";
str += "The last "D" is at index " + bookName.lastIndexOf("D") + "<br>";
str += "The first "e" after index 2 is at index " + bookName.indexOf("e", 2) + "<br>";
str += "The substring "Develop" begins at index " + bookName.indexOf("Develop");
document.getElementById("output").innerHTML = str;
As you can see in Figure 8-1, the numbers show you the index positions of each character in the script.
On a more practical note, the following code presents a simple validation script that uses indexOf()
.
var emailAddress = "";
do {
emailAddress = prompt("Enter a valid email address:");
}
while (emailAddress.indexOf("@") === -1);
The script prompts the user for a valid email address, which is stored in the emailAddress
variable. Any valid address will contain the @ symbol, so the while()
portion of a do…while()
loop checks to see if the entered string contains @:
while (emailAddress.indexOf("@") === -1);
If not (that is, if emailAddress.indexOf(
"@
")
returns -1), the loop continues and the user is prompted again.
Finding a substring is one thing, but you'll often have to extract a substring, as well. For example, if the user enters an email address, you might need to extract just the username (the part to the left of the @ sign) or the domain name (the part to the right of @). For these kinds of operations, JavaScript offers six methods, listed in Table 8-2.
TABLE 8-2 String Object Methods for Extracting Substrings
Method |
What It Does |
|
Returns the character in |
|
Returns the code of the character in |
|
Returns the substring in |
|
Returns an array where each item is a substring in |
|
Returns the substring in |
|
Returns the substring in |
You use the charAt()
method to return a single character that resides at a specified position within a string:
string.charAt(index)
string
: The string that contains the characterindex
: The position within string
of the character you wantHere are some notes about this method:
string
, use the following:
string.charAt(0)
string
, use this:
string.charAt(string.length - 1)
index
value is negative or if it's greater than or equal to string.
length
, JavaScript returns the empty string (""
).The following code presents an example.
HTML:
<div id="output"></div>
JavaScript:
// Set up an array of test strings
var stringArray = new Array(4);
stringArray[0] = "Not this one.";
stringArray[1] = "Not this one, either.";
stringArray[2] = "1. Step one.";
stringArray[3] = "Shouldn't get this far.";
var firstChar;
// Loop through the array
for (var i = 0; i < 4; i++) {
// Get the first character of the string;
firstChar = stringArray[i].charAt(0);
// If it's a number, break because that's the one we want
if (!isNaN(firstChar)) { break }
}
document.getElementById("output").innerHTML = "Here's the one: "" + stringArray[i] + """;
The idea here is to examine a collection of strings and find the one that starts with a number. The collection is stored in the array named stringArray
, and a for()
loop is set up to run through each item in the array. The charAt()
method is applied to each array item to return the first character, which is stored in the firstChar
variable. In the if()
test, the logical expression !isNaN(firstChar)
returns true
if the first character is a number, at which point the loop breaks and the correct string is displayed in the web page.
Use the slice()
method to carve out a piece of a string:
string.
slice(
start, end
)
string
: The string you want to work with.start
: The position within string
of the first character you want to extract.end
: An optional position within string
immediately after the last character you want to extract. If you leave out this argument, JavaScript extracts the substring that runs from start
to the end of the string. Also, this argument can be negative, in which case it specifies an offset from the end of the string.To be clear, slice()
extracts a substring that runs from the character at start
up to, but not including, the character at end
.
The following code runs through a few examples (see Figure 8-2).
HTML:
<pre>
Web Coding and Development for Dummies
01234567890123456789012345678901234567
</pre>
<div id="output"></div>
JavaScript:
var bookName = "Web Coding and Development for Dummies";
var str = "slice(0, 3) = " + bookName.slice(0, 3) + "<br>";
str += "slice(4, 10) = " + bookName.slice(4, 10) + "<br>";
str += "slice(15) = " + bookName.slice(15) + "<br>";
str += "slice(0, -12) = " + bookName.slice(0, -12);
document.getElementById("output").innerHTML = str;
The split()
method breaks up a string and stores the pieces inside an array:
string.split(separator, limit)
string
: The string you want to work with.separator
: The character used to mark the positions at which string
is split. For example, if separator
is a comma, the splits will occur at each comma in string
.limit
: An optional value that sets the maximum number of items to store in the array. For example, if limit
is 5, split()
stores the first 5 pieces in the array and then ignores the rest of the string.The split()
method is useful for those times when you have a “well-structured” string. This means that the string contains a character that acts as a delimiter between each string piece that you want set up as an array item. For example, it's fairly common to have to deal with comma-delimited strings:
string1 = "Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday";
As you can see, each day in the string is separated by a comma. This makes using the split()
method a no-brainer:
var string1Array = string1.split(",");
When you run this statement, string1Array[0]
will contain "Sunday"
, string1Array[1]
will contain "Monday"
, and so on. Note, too, that JavaScript sets up the array for you automatically. You don't have to declare the array using new Array()
.
The following code tries out split()
with a couple of example strings.
HTML:
<div id="output"></div>
JavaScript:
var string1 = "Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday";
var string2 = "ABCDEF";
var str = "";
var string1Array = string1.split(",");
for (var i = 0; i < string1Array.length; i++) {
str += "string1Array[" + i + "] = " + string1Array[i] + "<br>";
}
var string2Array = string2.split("", 4);
for (i = 0; i < string2Array.length; i++) {
str += "string2Array[" + i + "] = " + string2Array[i] + "<br>";
}
document.getElementById("output").innerHTML = str;
After string1
is split into string1Array
, a for()
loop runs through the array and writes the items to the web page. For string2
, the empty string is used as the separator and a limit of 4 is placed on the size of the string2Array
. Again, a for()
writes the array values to the page. Figure 8-3 shows what happens.
If you want to extract a substring and you know how long you want that substring to be, then the substr()
method is often the best approach:
string.
substr(
index
,
length
)
string
: The string you want to work with.index
: The position within string
of the first character you want to extract.length
: An optional value that specifies the length of the substring. If you omit this argument, JavaScript extracts all the way to the end of the string.The following code runs substr()
through some examples; the results appear in Figure 8-4.
HTML:
<pre>
Web Coding and Development for Dummies
01234567890123456789012345678901234567
</pre>
<div id="output"></div>
JavaScript:
var bookName = "Web Coding and Development for Dummies";
var str = "substr(0, 10) = " + bookName.substr(0, 10)+"<br>";
str += "substr(15, 11) = " + bookName.substr(15, 11) + "<br>";
str += "substr(27) = " + bookName.substr(27);
document.getElementById("output").innerHTML = str;
Use the substring()
method to extract a substring from a string:
string.
substring(
start, end
)
string
: The string you want to work with.start
: The position within string
of the first character you want to extract.end
: An optional value that specifies the position within string
immediately after the last character you want to extract. If you leave out this argument, JavaScript extracts the substring that runs from start
to the end of the string.The following code gives the substring()
method a whirl, and the results are shown in Figure 8-5.
HTML:
<pre>
Web Coding and Development for Dummies
01234567890123456789012345678901234567
</pre>
<div id="output"></div>
JavaScript:
var bookName = "Web Coding and Development for Dummies";
var str = "substring(0, 10) = " + bookName.substring(0, 10) + "<br>";
str += "substring(11, 14) = " + bookName.substring(11, 14) + "<br>";
str += "substring(31) = " + bookName.substring(31);
document.getElementById("output").innerHTML = str;
The splice()
, substr()
, and substring()
methods are very similar and are often confused by even experienced JavaScript programmers. Here are some notes to help you understand the differences between these three string extraction methods:
splice()
and substring()
methods perform the same task. The only difference is that splice()
enables you to use a negative value for the end
argument. This is handy if you want to leave out a certain number of characters from the end of the original string. For example, if you want to extract everything but the last three characters, you'd use this:
string.splice(0, -3)
splice()
or substring()
when you're not sure how long the extracted string will be. This usually means that you’ll use the indexOf()
and lastIndexOf()
methods to find particular characters that mark the starting and ending points of the substring you want. You then use those values as the start
and end
arguments of splice()
or substring()
. For example, suppose you have a string of the form www.domain.com
and you want to extract just the domain
part. Here's a short routine that will do it:
var hostName = "www.domain.com";
var firstDot = hostName.indexOf(".");
var lastDot = hostName.lastIndexOf(".");
var domainName = hostName.substring(firstDot + 1, lastDot);
substr()
method.Dates and times seem like the kind of things that ought to be straightforward programming propositions. After all, there are only 12 months in a year, 28 to 31 days in a month, seven days in a week, 24 hours in a day, 60 minutes in an hour, and 60 seconds in a minute. Surely something so set in stone couldn’t get even the least bit weird, could it?
You’d be surprised. Dates and times can get strange, but they get much easier to deal with if you always keep three crucial points in mind:
Before getting to the nitty-gritty of the Date
object and its associated methods, I'll take a second to run through the various arguments that JavaScript requires for many date-related features. This will save me from repeating these arguments tediously later on. Table 8-3 has the details.
TABLE 8-3 Arguments Associated with the Date Object
Argument |
What It Represents |
Possible Values |
|
A variable name |
A |
|
The year |
Four-digit integers |
|
The year |
Two-digit integers |
|
The month |
The full month name from |
|
The month |
Integers from 0 (January) to 11 (December) |
|
The day of the month |
Integers from 1 to 31 |
|
The hour of the day |
Integers from 0 (midnight) to 23 (11:00 PM) |
|
The minute of the hour |
Integers from 0 to 59 |
|
The second of the minute |
Integers from 0 to 59 |
|
The milliseconds of the second |
Integers from 0 to 999 |
Whenever you work with dates and times in JavaScript, you work with an instance of the Date
object. More to the point, when you deal with a Date
object in JavaScript, you deal with a specific moment in time, down to the millisecond. A Date
object can never be a block of time, and it's not a kind of clock that ticks along while your script runs. Instead, the Date
object is a temporal snapshot that you use to extract the specifics of the time it was taken: the year, month, date, hour, and so on.
The most common use of the Date
object is to store the current date and time. You do that by invoking the Date()
function, which is the constructor function for creating a new Date
object. Here's the general format:
var dateToday = new Date();
If you need to work with a specific date or time, you need to use the Date()
function’s arguments. There are five versions of the Date()
function syntax (see the list of arguments near the beginning of this chapter):
var date = new Date("month dd, yyyy hh:mm:ss");
var date = new Date("month dd, yyyy");
var date = new Date(yyyy, mth, dd, hh, mm, ss);
var date = new Date(yyyy, mth, dd);
var date = new Date(ms);
The following statements give you an example for each syntax:
var myDate = new Date("August 23, 2018 3:02:01");
var myDate = new Date("August 23, 2018");
var myDate = new Date(2018, 8, 23, 3, 2, 1);
var myDate = new Date(2018, 8, 23);
var myDate = new Date(1408777321000);
When your script just coughs up whatever Date
object value you stored in the variable, the results aren't particularly appealing. If you want to display dates in a more attractive format, or if you want to perform arithmetic operations on a date, then you need to dig a little deeper into the Date
object to extract specific information such as the month, year, hour, and so on. You do that by using the Date
object methods listed in Table 8-4.
TABLE 8-4 Date Object Methods That Extract Date Values
Method Syntax |
What It Returns |
|
The year as a four-digit number (1999, 2000, and so on) |
|
The month of the year; from 0 (January) to 11 (December) |
|
The date in the month; from 1 to 31 |
|
The day of the week; from 0 (Sunday) to 6 (Saturday) |
|
The hour of the day; from 0 (midnight) to 23 (11:00 PM) |
|
The minute of the hour; from 0 to 59 |
|
The second of the minute; from 0 to 59 |
|
The milliseconds of the second; from 0 to 999 |
|
The milliseconds since January 1, 1970 GMT |
One of the ways you can take advantage of these methods is to display the time or date to the user using any format you want. Here's an example:
HTML:
<div id="output"></div>
JavaScript:
var timeNow = new Date();
var hoursNow = timeNow.getHours();
var minutesNow = timeNow.getMinutes();
var message = "It's ";
var hoursText;
if (minutesNow <= 30) {
message += minutesNow + " minutes past ";
hoursText = hoursNow;
} else {
message += (60 - minutesNow) + " minutes before ";
hoursText = hoursNow + 1;
}
if (hoursNow == 0 && minutesNow <= 30) {
message += "midnight.";
} else if (hoursNow == 11 && minutesNow > 30) {
message += "noon.";
} else if (hoursNow < 12) {
message += hoursText + " in the morning.";
} else if (hoursNow == 12 && minutesNow <= 30) {
message += "noon.";
} else if (hoursNow < 18) {
message += parseInt(hoursText - 12) + " in the afternoon.";
} else if (hoursNow == 23 && minutesNow > 30) {
message += "midnight.";
} else {
message += parseInt(hoursText - 12) + " in the evening.";
}
document.getElementById("output").innerHTML = message;
This script begins by storing the user’s local time in the timeNow
variable. Then the current hour is extracted using getHours()
and stored in the hoursNow
variable, and the current minute is extracted using getMinutes()
and stored in the minutesNow
variable. A variable named message
is initialized and will be used to store the message that's displayed in the web page. The variable hoursText
will hold the non-military hour (for example, 4 instead of 16).
Then the value of minutesNow
is checked to see if it's less than or equal to 30, because this determines the first part of the message, as well as the value of hoursText
. Here are two examples of what the message will look like:
It's 20 minutes past 10 // minutesNow is less than or equal to 30 (10:20)
It's 20 minutes to 11 // minutesNow is greater than 30 (10:40)
Then the script checks the value of hoursNow
:
minutesNow
is less than or equal to 30, then the string midnight
is added to the message.minutesNow
is greater than 30, then the string noon
is added to the message.hoursText
and the string in the morning
are added to the message.minutesNow
is less than or equal to 30, then the string noon
is added to the message.hoursText - 12
and the string in the afternoon
are added.minutesNow
is greater than 30, then the string midnight
is added to the message.hoursText - 12
and the string in the evening
are added.Finally, the result is written to the page, as shown in Figure 8-6.
If you want to use the month in a nicer format than the standard Date
object display, there's one problem: The getMonth()
method returns a number instead of the actual name of the month: 0 for January, 1 for February, and so on. If you prefer to use the name, you need some way to convert the number returned by getMonth()
.
There are two ways you can go about this: an array or a function. The following code shows the array route:
HTML:
<div id="output"></div>
JavaScript:
var monthNames = ["January","February","March","April","May","June","July","August","September","October","November","December"];
var dateNow = new Date();
var monthNow = dateNow.getMonth();
document.getElementById("output").innerHTML = "getMonth() is " + monthNow + "; the name is " + monthNames[monthNow];
The script declares a 12-item array named monthNames
that stores the names of the months. The key here is that the array index matches the return value of getMonth()
. For example, getMonth()
returns 0 for January, so the array index 0 is assigned the string "January"
. Then the current date is stored in dateNow
, and the month is stored in monthNow
. Finally, in the getElementById()
statement, the month name is displayed by using the monthNow
value as the array index: monthNames[monthNow]
.
The following code shows how to do it using a function.
HTML:
<div id="output"></div>
JavaScript:
function monthName(monthValue) {
switch (monthValue) {
case 0 : return "January";
case 1 : return "February";
case 2 : return "March";
case 3 : return "April";
case 4 : return "May";
case 5 : return "June";
case 6 : return "July";
case 7 : return "August";
case 8 : return "September";
case 9 : return "October";
case 10 : return "November";
case 11 : return "December";
}
}
var dateNow = new Date();
var monthNow = dateNow.getMonth();
document.getElementById("output").innerHTML = "getMonth() is " + monthNow + "; the name is " + monthName(monthNow);
With this technique, you pass the getMonth()
value as an argument to the monthName()
function, which then uses a switch()
statement to test the value and return the appropriate string.
So which method should you use? Neither one has any glaringly obvious benefits over the other. The array method is a bit quicker to set up and it probably executes a bit faster than the function, so it's probably the (slightly) better choice.
You face a similar problem with getDay()
as you do with getMonth()
: converting the returned number into a “friendly” name such as, in this case, Sunday for 0, Monday for 1, and so on. The solution, as you can imagine, is also similar. The following code shows how to return a day name from a getDay()
value using an array.
HTML:
<div id="output"></div>
JavaScript:
var dayNames = ["Sunday","Monday","Tuesday",
"Wednesday","Thursday","Friday","Saturday"];
var dateNow = new Date();
var dayNow = dateNow.getDay();
document.getElementById("output").innerHTML = "getDay() is " + dayNow + "; the name is "+dayNames[dayNow];
This time, the script declares a seven-item array named dayNames
and initializes each item to a name of a day (again, making sure each array index corresponds with the return value of getDay()
).
A function to return the day name from a getDay()
value would be almost identical to the one I listed earlier for month names, so I'll leave that as an exercise.
When you perform date arithmetic, you often have to change the value of an existing Date
object. For example, an ecommerce script might have to calculate a date that is 90 days from the date that a sale occurs. It’s usually easiest to create a Date
object and then use an expression or literal value to change the year, month, or some other component of the date. You do that by using the Date
object methods listed in Table 8-5.
TABLE 8-5 Date Object Methods That Set Date Values
Method Syntax |
What It Sets |
|
The year as a four-digit number (1999, 2000, and so on) |
|
The month of the year; from 0 (January) to 11 (December) |
|
The date in the month; from 1 to 31 |
|
The hour of the day; from 0 (midnight) to 23 (11:00 PM) |
|
The minute of the hour; from 0 to 59 |
|
The second of the minute; from 0 to 59 |
|
The milliseconds of the second; from 0 to 999 |
|
The milliseconds since January 1, 1970 GMT |
To try out some of these methods, the following code presents a script that specifies a date (year, month, and day in the month) and then displays what day of the week it was, is, or will be.
HTML:
<div id="output"></div>
JavaScript:
var monthNames = ["January","February","March","April","May","June","July","August","September","October","November","December"];
var dayNames = ["Sunday","Monday","Tuesday",
"Wednesday","Thursday","Friday","Saturday"];
// Set the year, month, and day
var userYear = 2018;
var userMonth = 11;
var userDay = 31;
// Make a date object then use the data to change the date
var userDate = new Date();
userDate.setFullYear(userYear);
userDate.setMonth(userMonth);
userDate.setDate(userDay);
// Convert the numbers into names
var dayName = dayNames[userDate.getDay()];
var monthName = monthNames[userDate.getMonth()];
// Display the message
document.getElementById("output").innerHTML = "The date you entered was: "
monthName + " " + userDay + ", " + userYear + "<br>The day of the week is: " + dayName;
The script opens by declaring and initializing the arrays for converting the values returned by getMonth()
and getDate()
. Then three variables are declared to store the year, month (as a number), and day.
The next four statements are the keys to this example. A new Date
object is stored in the userDate
variable. It begins with the current date, but, as you'll see, this doesn’t matter. Then the script runs the setFullYear()
, setMonth()
, and setDate()
methods.
At this point, the userDate
variable contains a new date that corresponds to the supplied date. This means you can apply any of the “get” methods to that date. In particular, you can figure out which day of the week corresponds to the new date by running the getDay()
method — userDate.getDay()
. So the next two statements in the script use getDay()
and getMonth
to return the day and month values, and the arrays are used to convert them into names. Once that's done, the script displays the date and the day of the week that it corresponds to (see Figure 8-7).
newDate = new Date(userDate.SetFullYear(userYear));
Many of your date-related scripts will need to make arithmetic calculations. For example, you might need to figure out the number of days between two dates, or you might need to calculate the date that is six weeks from today. The methods you’ve seen so far and the way JavaScript represents dates internally serve to make most date calculations straightforward.
The simplest calculations are those that involve whole numbers of the basic JavaScript date and time units: years, months, days, hours, minutes, and seconds. For example, suppose you need to calculate a date that’s five years from the current date. Here’s a code snippet that will do it:
var myDate = new Date();
var myYear = myDate.getFullYear() + 5;
myDate.setFullYear(myYear);
You use getFullYear()
to get the year, add 5 to it, and then use setFullYear()
to change the date.
As a practical example, the following code presents a script that calculates a person’s age.
HTML:
<div id="output"></div>
JavaScript:
var userAge;
// Set the birth date: year, month, and day
var userYear = 1990;
var userMonth = 7;
var userDay = 23;
// Make a Date object and change it
// to the user's birthday this year
var birthdayDate = new Date();
birthdayDate.setMonth(userMonth);
birthdayDate.setDate(userDay);
// Store the current date
var currentDate = new Date();
var currentYear = currentDate.getFullYear();
// Check to see if the birthday has yet to occur this year
if (currentDate < birthdayDate) {
userAge = currentYear - userYear - 1;
} else {
userAge = currentYear - userYear;
}
document.getElementById("output").innerHTML = "You are " + userAge + " years old.";
The script prompts the user for the year, month, and day of her birth date. Then it creates a new Date object and stores it in birthdayDate
. The date is changed using setMonth()
and setDate()
, but not setFullYear()
. This gives you the user's birthday for this year. Then the current date is stored in currentDate
and the year is stored in currentYear
.
Now the script compares currentDate
and birthdayDate
: If currentDate
is less, it means the user's birthday hasn’t happened, so her age is the difference between currentYear
and userYear
(the year she was born), minus one. Otherwise, her age is the difference between currentYear
and userYear
.
Other date calculations are more complex. For example, you might need to calculate the number of days between two dates. For this kind of calculation, you need to take advantage of the fact that JavaScript stores dates internally as millisecond values. They're stored, in other words, as numbers, and once you’re dealing with numeric values, you can use numeric expressions to perform calculations on those values.
The key here is converting the basic date units — seconds, minutes, hours, days, and weeks — into milliseconds. Here’s some code that will do it:
var ONESECOND = 1000;
var ONEMINUTE = ONESECOND * 60;
var ONEHOUR = ONEMINUTE * 60;
var ONEDAY = ONEHOUR * 24;
var ONEWEEK = ONEDAY * 7;
Because one second equals 1,000 milliseconds, the ONESECOND
variable is given the value 1000; because one minute equals 60 seconds, the ONEMINUTE
variable is given the value ONESECOND * 60
, or 60,000 milliseconds. The other values are derived similarly.
A common date calculation involves figuring out the number of days between any two dates. The following code presents a function that performs this calculation.
function daysBetween(date1, date2) {
// The number of milliseconds in one day
var ONEDAY = 1000 * 60 * 60 * 24;
// Convert both dates to milliseconds
var date1Ms = date1.getTime();
var date2Ms = date2.getTime();
// Calculate the difference in milliseconds
var differenceMs = Math.abs(date1Ms - date2Ms);
// Convert to days and return
return Math.round(differenceMs/ONEDAY);
}
This function accepts two Date
object arguments — date1
and date2
. Note that it doesn't matter which date is earlier or later because this function calculates the absolute value of the difference between them. The constant ONEDAY
stores the number of milliseconds in a day, and then the two dates are converted into milliseconds using the getTime()
method. The results are stored in the variables date1Ms
and date2Ms
.
Next, the following statement calculates the absolute value, in milliseconds, of the difference between the two dates:
var differenceMs = Math.abs(date1Ms - date2Ms);
This difference is then converted into days by dividing it by the ONEDAY
constant. Math.round()
(which I discuss in the next section) ensures an integer result.
It's a rare JavaScript programmer who never has to deal with numbers. Most of us have to cobble together scripts that process order totals, generate sales taxes and shipping charges, calculate mortgage payments, and perform other number-crunching duties. To that end, it must be said that JavaScript’s numeric tools aren’t the greatest in the programming world, but there are plenty of features to keep most scripters happy. This section tells you about those features, with special emphasis on the Math
object.
The first thing you need to know is that JavaScript likes to keep things simple, particularly when it comes to numbers. For example, JavaScript is limited to dealing with just two numeric data types: integers — numbers without a fractional or decimal part, such as 1, 759, and -50 — and floating-point numbers — values that have a fractional or decimal part, such as 2.14, 0.01, and -25.3333.
When you’re working with numeric expressions in JavaScript, it’s important to make sure that all your operands are numeric values. For example, if you prompt the user for a value, you need to check the result to make sure it’s not a letter or undefined
(the default prompt()
value). If you try to use the latter, for example, JavaScript will report that its value is NaN
(not a number).
Similarly, if you have a value that you know is a string representation of a number, then you need some way of converting that string into its numerical equivalent.
For these situations, JavaScript offers several techniques that ensure your operands are numeric.
I begin with the parseInt()
function, which you use to convert a string into an integer:
parseInt(string, base);
string
: The string value you want to convert.base
: An optional base used by the number in string
. If you omit this value, JavaScript uses base 10.Note that if the string
argument contains a string representation of a floating-point value, parseInt()
returns only the integer portion. Also, if the string begins with a number followed by some text, parseInt()
returns the number (or, at least, its integer portion). The following table shows you the parseInt()
results for various string
values.
|
parseInt( |
"5" |
5 |
"5.1" |
5 |
"5.9" |
5 |
"5 feet" |
5 |
"take 5" |
|
"five" |
|
The parseFloat()
function is similar to parseInt()
, but you use it to convert a string into a floating-point value:
parseFloat(string);
Note that if the string
argument contains a string representation of a integer value, parseInt()
displays just an integer. Also, like parseInt()
, if the string begins with a number followed by some text, parseInt()
returns the number. The following table shows you the parseFloat()
results for some string
values.
|
parseFloat( |
"5" |
5 |
"5.1" |
5.1 |
"5.9" |
5.9 |
"5.2 feet" |
5.2 |
"take 5.0" |
|
"five-point-one" |
|
For quick conversions from a string to a number, I most often use the +
operator, which tells JavaScript to treat a string that contains a number as a true numeric value. For example, consider the following code:
var numOfShoes = '2';
var numOfSocks = 4;
var totalItems = +numOfShoes + numOfSocks;
By adding +
in front of the numOfShoes
variable, I force JavaScript to set that variable's value to the number 2, and the result of the addition will be 6.
The Math
object is a bit different than most of the other objects you come across in this book. That’s because you never create an instance of the Math
object that gets stored in a variable. Instead, the Math
object is a built-in JavaScript object that you use as-is. The rest of this chapter explores some properties and methods associated with the Math
object.
The Math
object's properties are all constants that are commonly used in mathematical operations. Table 8-6 lists all the available Math
object properties.
TABLE 8-6 Some Properties of the Math Object
Property Syntax |
What It Represents |
Approximate Value |
|
Euler's constant |
2.718281828459045 |
|
The natural logarithm of 2 |
0.6931471805599453 |
|
The natural logarithm of 10 |
2.302585092994046 |
|
Base 2 logarithm of |
1.4426950408889633 |
|
Base 10 logarithm of |
0.4342944819032518 |
|
The constant pi |
3.141592653589793 |
|
The square root of 1/2 |
0.7071067811865476 |
|
The square root of 2 |
1.4142135623730951 |
The Math
object's methods enable you to perform mathematical operations such as square roots, powers, rounding, trigonometry, and more. Many of the Math
object’s methods are summarized in Table 8-7.
TABLE 8-7 Some Methods of the Math Object
Method Syntax |
What It Returns |
|
The absolute value of |
|
The smallest integer greater than or equal to |
|
The cosine of |
|
|
|
The largest integer that is less than or equal to |
|
The natural logarithm (base |
|
The larger of |
|
The smaller of |
|
|
|
A random number between 0 and 1 |
|
The integer closest to |
|
The sine of |
|
The square root of |
|
The tangent of |
3.143.168.172