Chapter 4. Working with Words, Numbers, and Dates

Storing information in a variable or an array is just the first step in effectively using data in your programs. As you read in the last chapter, you can use data to make decisions in a program (“Is the score 0?”). You’ll also frequently manipulate data by either searching through it (trying to find a particular word in a sentence, for example), manipulating it (rounding a number to a nearest integer), or reformatting it to display properly (formatting a number like 430 to appear in the proper monetary format, like $430.00).

This chapter will show you how to accomplish common tasks when working with strings and numbers. In addition, it’ll introduce the JavaScript Date object, which lets you determine the current date and time on a visitor’s computer.

A Quick Object Lesson

So far in this book, you’ve learned that you can write something to a Web page with the document.write() command, and to determine how many items are in an array, you type the name of the array followed by a period and the word “length,” like so: days.length. You’re probably wondering what those periods are about. You’ve made it through three chapters without learning the particulars of this feature of JavaScript syntax, and it’s time to address them.

You can conceptualize many of the elements of the JavaScript language, as well as elements of a Web page, as objects. The real world, of course, is filled with objects too, such as a dog or a car. Most objects are made up of different parts: a dog has a tail, a head, and four legs; a car has doors, wheels, headlights, a horn, and so on. An object might also do something—a car can transport passengers, a dog can bark. In fact, even a part of an object can do something: for example, a tail can wag, and a horn can honk. Table 4-1 illustrates one way to show the relationships between objects, their parts, and actions.

Table 4-1. A simplified view of the world

Object

Parts

Actions

dog

 

bark

 

tail

wag

car

 

transport

 

horn

honk

The world of JavaScript is also filled with objects: a browser window, a document, an array, a string, and a date are just a few examples. Like real-world objects, JavaScript objects are also made up of different parts. In programming-speak, the parts of an object are called properties. The actions an object can perform are called methods, which are basically functions (like the ones you created in the previous chapter) that are specific to an object (see Table 4-2).

Note

You can always tell a method from a property because methods end in parentheses: write(), for example.

Each object in JavaScript has its own set of properties and methods. For example, the array object has a property named length, and the document object has a method named write(). To access an object’s property or execute one of its methods, you use dot-syntax—those periods! The dot (period) connects the object with its property or method. For example, document.write() means “run the write() method of the document object.” If the real world worked like that, you’d have a dog wag his tail like this: dog.tail.wag() (of course, in the real world, a doggy treat works a lot better).

Table 4-2. Some methods and properties of an array object (see Arrays for more information on arrays)

An array object

Property

Method

['Bob', ‘Jalia', ‘Sonia']

length

 
  

push()

  

pop()

  

shift()

And just as you might own several dogs in the real world, your JavaScript programs can have multiple versions of the same kind of object. For example, say you create two simple variables like this:

var first_name = 'Jack';
var last_name = 'Hearts';

You’ve actually created two different string objects. Strings (as you’ll see in this chapter) have their own set of properties and methods, which are different from the methods and properties of other objects, like arrays. When you create an object (also called creating an instance of that object) you can access all of the properties and methods for that object. You’ve actually been doing that in the last few chapters without even realizing it. For example, you can create an array like this:

var names = ['Jack', 'Queen', 'King'];

The variable names is an instance of an array object. To find out the number of items in that array, you access that array’s length property using dot notation:

names.length

Likewise, you can add an item to the end of that array by using the array object’s push() method like this (see Adding an item to the end of an array for a refresher on array methods):

names.push('Ace');

Whenever you create a new variable and store a value into it, you’re really creating a new instance of a particular type of object. So each of these lines of JavaScript create different types of JavaScript objects:

var first_name = 'Bob'; // a string object
var age = 32; // a number object
var valid = false; // a Boolean object
var data = ['Julia', 22, true]; // an array object composed of other objects

In fact, when you change the type of information stored in a variable, you change the type of object it is as well. For example, if you create a variable named data that stores an array, then store a number in the variable, you’ve changed that variable’s type from an array to a number object:

var data = ['Julia', 22, true]; // an array object composed of other objects
data = 32; //changes to number object

The concepts of objects, properties, methods, and dot-syntax may seem a little weird at first glance. However, since they are a fundamental part of how JavaScript works, you’ll get used to them pretty quickly.

Tip

As you continue reading this book, keep in mind these few facts:

  • The world of JavaScript is populated with lots of different types of objects.

  • Each object has its own properties and methods.

  • You access an object’s property or activate an object’s method using dot-syntax: document.write(), for example.

Strings

Strings are the most common type of data you’ll work with: input from form fields, the path to an image, a URL, and HTML that you wish to replace on a page are all examples of the letters, symbols, and numbers that make up strings. Consequently, JavaScript provides lot of methods for working with and manipulating strings.

Determining the Length of a String

There are times when you want to know how many characters are in a string. For example, say you want to make sure that when someone creates an account on your top secret Web site, they create a new password that’s more than 6 letters but no more than 15. Strings have a length property that gives you just this kind of information. Add a period after the name of the variable, followed by length to get the number of characters in the string: name.length.

For example, to make sure a password has the proper number of characters, you could use a conditional statement to test the password’s length like this:

var password = 'sesame';
if (password.length <= 6) {
  alert('That password is too short.');
} else if (password.length > 15) {
  alert('That password is too long.');
}

Note

In the above example, the password is just directly assigned to the variable var password = ’sesame’. In a real world scenario, you’d get the password from a form field, as described on Selecting Form Elements.

Changing the Case of a String

JavaScript provides two methods to convert strings to all uppercase or all lowercase, so you can change ‘hello’ to ‘HELLO’ or ‘NOT’ to ‘not’. Why, you might ask? Converting letters in a string to the same case makes comparing two strings easier. For example, say you created a Quiz program like the one from last chapter (see Keeping Variables from Colliding) and one of the questions is “Who was the first American to win the Tour De France?” You might have some code like this to check the quiz-taker’s answer:

var correctAnswer = 'Greg LeMond';
var response = prompt('Who was the first American to win the Tour De↵
France?', '');
if (response == correctAnswer) {
  // correct
} else {
  // incorrect
}

The answer is Greg LeMond, but what if the person taking the quiz typed Greg Lemond? The condition would look like this: ‘Greg Lemond’ == ‘Greg LeMond’. Since JavaScript treats uppercase letters as different than lowercase letters, the lowercase ‘m’ in Lemond wouldn’t match the ‘M’ in LeMond, so the quiz-taker would have gotten this question wrong. The same would happen if her key-caps key was down and she typed GREG LEMOND.

To get around this difficulty, you can convert both strings to the same case and then compare them:

if (response.toUpperCase() == correctAnswer.toUpperCase()) {
  // correct
} else {
  // incorrect
}

In this case, the conditional statement converts both the quiz-taker’s answer and the correct answer to uppercase, so ‘Greg Lemond’ becomes ‘GREG LEMOND’ and ‘Greg LeMond’ becomes ‘GREG LEMOND’.

To get the string all lowercase, use the toLowerCase() method like this:

var answer = 'Greg LeMond';
alert(answer.toLowerCase()); // 'greg lemond'

Note that neither of these methods actually alters the original string stored in the variable—they just return that string in either all uppercase or all lowercase. So in the above example, answer still contains ‘Greg LeMond’ even after the alert appears. (In other words, these methods work just like a function that returns some other value as described on Retrieving Information from Functions.)

Searching a String: indexOf() Technique

JavaScript provides several techniques for searching for a word, number, or other series of characters inside a string. Searching can come in handy, for example, if you want to know which Web browser a visitor is using to view your Web site. Every Web browser identifies information about itself in a string containing a lot of different statistics. You can see that string for yourself by adding this bit of JavaScript to a page and previewing it in a Web browser:

<script type="text/javascript">
alert(navigator.userAgent);
</script>

Navigator is one of a Web browser’s objects, and userAgent is a property of the navigator object. The userAgent property contains a long string of information; for example, on Internet Explorer 7 running on Windows XP, the userAgent property is: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1). So, if you want to see if the Web browser was IE 7, you can just search the userAgent string for “MSIE 7”.

One method of searching a string is the indexOf() method. Basically, after the string you add a period, indexOf() and supply the string you’re looking for. The basic structure looks like this:

string.indexOf('string to look for')

The indexOf() method returns a number: if the search string isn’t found, the method returns –1. So if you want to check for Internet Explorer, you can do this:

var browser = navigator.userAgent; // this is a string
if (browser.indexOf('MSIE') != -1) {
  // this is Internet Explorer
}

In this case, if indexOf() doesn’t locate the string ‘MSIE’ in the userAgent string, it will return –1, so the condition tests to see if the result is not (!=) –1.

When the indexOf() method does find the searched for string, it returns a number that’s equal to the starting position of the searched for string. The following example makes things a lot clearer:

var quote = 'To be, or not to be.'
var searchPosition = quote.indexOf('To be'); // returns 0

Here, indexOf() searches for the position of ‘To be’ inside the string ‘To be, or not to be.’ The larger string begins with ‘To be', so indexOf() finds ‘To be’ at the first position. But in the wacky way of programming, the first position is considered 0, the second letter (o) is at position 1, and the third letter (a space in this case) is 2 (as explained on Accessing Items in an Array, arrays are counted in the same way).

The indexOf() method searches from the beginning of the string. You can also search from the end of the string by using the lastIndexOf() method. For example, in the Shakespeare quote, the word ‘be’ appears in two places, so you can locate the first ‘be’ using indexOf() and the last ‘be’ with lastIndexOf():

var quote = "To be, or not to be."
var firstPosition = quote.indexOf('be'); // returns 3
var lastPosition = quote.lastIndexOf('be'); // returns 17

The results of those two methods are pictured in Figure 4-1. In both cases, if ‘be’ didn’t exist anywhere in the string, the result would be –1, and if there’s only one instance of the searched-for word, indexOf() and lastIndexOf() will return the same value—the starting position of the searched for string within the larger string.

Extracting Part of a String with slice()

To extract part of a string, use the slice() method. This method returns a portion of a string. For example, say you had a string like "http://www.sawmac.com" and you wanted to eliminate the http:// part. One way to do this is to extract every character in the string that follows the http:// like this:

The indexOf() and lastIndexOf() methods search for a particular string inside a larger string. If the search string is found, its position in the larger string is returned.
Figure 4-1. The indexOf() and lastIndexOf() methods search for a particular string inside a larger string. If the search string is found, its position in the larger string is returned.
var url = 'http://www.sawmac.com';
var domain = url.slice(7); // www.sawmac.com

The slice() method requires a number that indicates the starting index position for the extracted string (see Figure 4-2). In this example—url.slice(7)—the 7 indicates the eighth letter in the string (remember, the first letter is at position 0). The method returns all of the characters starting at the specified index position to the end of the string.

If you don’t supply a second argument to the slice() method, it just extracts a string from the specified position (7 in this example) all the way to the end of the string.
Figure 4-2. If you don’t supply a second argument to the slice() method, it just extracts a string from the specified position (7 in this example) all the way to the end of the string.

You can also extract a specific number of characters within a string by supplying a second argument to the slice() method. Here’s the basic structure of the slice() method:

string.slice(start, end);

The start value is a number that indicates the first character of the extracted string; the end value is a little confusing—it’s not the position of the last letter of the extracted string; it’s actually the position of the last letter + 1. For example, if you wanted to extract the first five letters of the string ‘To be, or not to be.', you would specify 0 as the first argument, and 5 as the second argument. As you can see in Figure 4-3, 0 is the first letter in the string, and 5 is the sixth letter, but the last letter specified is not extracted from the string. In other words, the character specified by the second argument is never part of the extracted string.

Tip

If you want to extract a specific number of characters from a string, just add that number to the starting value. For example, if you want to retrieve the first 10 letters of a string, the first argument would be 0 (the first letter) and the last would be 0 + 10 or just 10: slice(0,10).

You can also specify negative numbers, for example quote.slice(-6,-1). A negative number counts backwards from the end of the string, as pictured in Figure 4-3.

The slice() method extracts a portion of a string. The actual string is not changed in any way. For instance, the string contained in the quote variable in this example isn’t changed by quote.slice(0,5). The method simply returns the extracted string, which you can store inside a variable, display in an alert box, or even pass as an argument to a function.
Figure 4-3. The slice() method extracts a portion of a string. The actual string is not changed in any way. For instance, the string contained in the quote variable in this example isn’t changed by quote.slice(0,5). The method simply returns the extracted string, which you can store inside a variable, display in an alert box, or even pass as an argument to a function.

Tip

If you want, say, to extract a string that includes all of the letters from the 6th letter from the end of the string all the way to the end, you leave off the second argument:

quote.slice(-6);

Finding Patterns in Strings

Sometimes you wish to search a string, not for an exact value, but for a specific pattern of characters. For example, say you want to make sure when a visitor fills out an order form, he supplies a phone number in the correct format. You’re not actually looking for a specific phone number like 503-555-0212. Instead you’re looking for a general pattern: 3 numbers, a hyphen, three numbers, another hyphen, and four numbers. You’d like to check the value the visitor entered, and if it matches the pattern (for example, it’s 415-555-3843, 408-555-3782, or 212-555-4828, and so on) then everything’s OK. But if it doesn’t match that pattern (for example, the visitor typed 823lkjxdfglkj) then you’d like to post a message like “Hey buddy, don’t try to fool us!”

JavaScript lets you use regular expressions to find patterns within a string. A regular expression is a series of characters that define a pattern that you wish to search for. As with many programming terms, the name “regular expression” is a bit misleading. For example, here’s what a common regular expression looks like:

/^[-\w.]+@([a-zA-Z0-9][-a-zA-Z0-9]+\.)+[a-zA-Z]{2,4}$/

Unless you’re a super-alien from Omicron 9, there’s nothing very regular-looking about a regular expression. To create a pattern you use characters like *, +, ?, and \w, which are translated by the JavaScript interpreter to match real characters in a string like letters, numbers, and so on.

Note

Pros often shorten the name regular expression to regex.

Creating and Using a Basic Regular Expression

To create a regular expression in JavaScript, you must create a regular expression object, which is a series of characters between two forward slashes. For example, to create a regular expression that matches the word ‘hello', you’d type this:

var myMatch = /hello/;

Just as an opening and closing quote mark creates a string, the opening / and closing / create a regular expression.

There are several string methods that take advantage of regular expressions (you’ll learn about them starting on Matching every instance of a pattern), but the most basic method is the search() method. It works very much like the indexOf() method, but instead of trying to find one string inside another, larger string, it searches for a pattern (a regular expression) inside a string. For example, say you want to find ‘To be’ inside the string ‘To be or not to be.’ You saw how to do that with the indexOf() method on Searching a String: indexOf() Technique, but here’s how you can do the same thing with a regular expression:

var myRegEx = /To be/; // no quotes around regular expression
var quote = 'To be or not to be.';
var foundPosition = quote.search(myRegEx);  // returns 0

If the search() method finds a match, it returns the position of the first letter matched, and if it doesn’t find a match, it returns –1. So in the above example, the variable foundPosition is 0, since ‘To be’ begins at the very beginning (the first letter) of the string.

As you’ll recall from Searching a String: indexOf() Technique, indexOf() method works in the same way. You might be thinking that if the two methods are the same, why bother with regular expressions? The benefit of regular expressions is that they can find patterns in a string, so they can make much more complicated and subtle comparisons than the indexOf() method, which always looks for a match to an exact string. For example, you could use the indexOf() method to find out if a string contains the Web address http://www.missingmanuals.com/, but you’d have to use a regular expression to find any text that matches the format of a URL—exactly the kind of thing you want to do when verifying if someone supplied a Web address when posting a comment to your blog.

However, to master regular expressions, you need to learn the often confusing symbols required to construct a regular expression.

Building a Regular Expression

While a regular expression can be made up of a word or words, more often you’ll use a combination of letters and special symbols to define a pattern that you hope to match. Regular expressions provide different symbols to indicate different types of characters. For example, a single period (.) represents a single character, any character, while \w matches any letter or number (but not spaces, or symbols like $ or %). Table 4-3 provides a list of the most common pattern-matching characters.

Note

If this entire discussion of “regular” expressions is making your head hurt, you’ll be glad to know this book provides some useful regular expressions (see Useful Regular Expressions) that you can copy and use in your own scripts (without really knowing how they work).

Learning regular expressions is a topic better presented by example, so the rest of this section walks you through a few examples of regular expressions to help you wrap your mind around this topic. Assume you want to match five numbers in a row—perhaps to check if there’s a U. S. Zip code in a string:

  1. Match one number.

    The first step is simply to figure out how to match one number. If you refer to Table 4-3, you’ll see that there’s a special regex symbol for this, \d, which matches any single number.

  2. Match five numbers in a row.

    Since \d matches a single number, a simple way to match five numbers is with this regular expression: \d\d\d\d\d. (Building a Regular Expression, however, covers a more compact way to write this.)

  3. Match only five numbers.

    A regular expression is like a precision-guided missile: It sets its target on the first part of a string that it matches. So, you sometimes end up with a match that’s part of a complete word or set of characters. This regular expression matches the first five numbers in a row that it encounters. For example, it will match 12345 in the number 12345678998. Obviously, 12345678998 isn’t a Zip code, so you need a regex that targets just five numbers.

    The \b character (called the word boundary character) matches any nonletter or nonnumber character, so you could rewrite your regular expression like this: \b\d\d\d\d\d\b. You can also use the ^ character to match the beginning of a string and the $ character to match the end of a string. This trick comes in handy if you want the entire string to match your regular expression. For example, if someone typed “kjasdflkjsdf 88888 lksadflkjsdkfjl” in a Zip code field on an order form, you might want to ask the visitor to clarify (and fix) their Zip code before ordering. After all, you’re really looking for something like 97213 (with no other characters in the string). In this case, the regex would be ^\d\d\d\d\d$.

    Note

    Zip codes can have more than five numbers. The ZIP + 4 format includes a dash and four additional numbers after the first five, like this: 97213-1234. For a regular expression to handle this possibility, see Building a Regular Expression.

  4. Put your regex into action in JavaScript.

    Assume you’ve already captured a user’s input into a variable named zip, and you want to test to see if the input is in the form of a valid five-number Zip code:

    var zipTest = /^\d\d\d\d\d$/; //create regex
    if (zip.search(zipTest) == -1) {
      alert('This is not a valid zip code');
    } else {
      // is valid format
    }

Character

Matches

.

Any one character—will match a letter, number, space, or other symbol

\w

Any word character including a–z, A–Z, the numbers 0–9, and the underscore character: _.

\W

Any character that’s not a word character. It’s the exact opposite of \w.

\d

Any digit 0–9.

\D

Any character except a digit. The opposite of \d.

\s

A space, tab, carriage return, or new line.

\S

Anything but a space, tab, carriage return, or new line.

^

The beginning of a string. This is useful for making sure no other characters come before whatever you’re trying to match.

$

The end of a string. Use $ to make sure the characters you wish to match are at the end of a string. For example, /com$/ matches the string “com”, but only when it’s the last three letters of the string. In other words, /com$/ would match “com” in the string “Infocom,” but not ‘com’ in ‘communication’.

\b

A space, beginning of the string, end of string, or any nonletter or number character such as +, =, or ‘. Use \b to match the beginning or ending of a word, even if that word is at the beginning or ending of a string.

[ ]

Any one character between the brackets. For example, [aeiou] matches any one of those letters in a string. For a range of characters, use a hyphen: [a-z] matches any one lower case letter; [0-9] matches any one number (the same as \d.)

[^ ]

Any character except one in brackets. For example, [^aeiouAEIOU] will match any character that isn’t a vowel. [^0-9] matches any character that’s not a number (the same as \D).

|

Either the characters before or after the | character. For example, a|b will match either a or b, but not both. (See Matching a Pattern for an example of this symbol in action.)

\

Used to escape any special regex symbol (*,.,\,/, for instance) to search for a literal example of the symbol in a string. For example, . in regex-speak means “any character,” but if you want to really match a period in a string you need to escape it, like this: \..

The regex example in these steps works, but it seems like a lot of work to type \d five times. What if you want to match 100 numbers in a row? Fortunately, JavaScript includes several symbols that can match multiple occurrences of the same character. Table 4-4 includes a list of these symbols. You place the symbol directly after the character you wish to match.

For example, to match five numbers, you can write \d{5}. The \d matches one number, then the {5} tells the JavaScript interpreter to match five numbers. So \d{100} would match 100 digits in a row.

Let’s go through another example. Say you wanted to find the name of any GIF file in a string. In addition, you want to extract the file name and perhaps use it somehow in your script (for example, you can use the match() method described on Matching every instance of a pattern). In other words, you want to find any string that matches the basic pattern of a GIF file name, such as logo.gif, banner.gif or ad.gif.

  1. Identify the common pattern between these names.

    To build a regular expression, you first need to know what pattern of characters you’re searching for. Here, since you’re after GIFs, you know all the file names will end in .gif. In other words, there can be any number of letters or numbers or other characters before .gif.

  2. Find .gif.

    Since you’re after the literal string ‘.gif', you might think that part of the regular expression would just be .gif. However, if you check out Table 4-3, you’ll see that a period has special meaning as a “match any character” character. So .gif would match “.gif,” but it would also match “tgif.” A period matches any single character so in addition to matching a period, it will also match the “t” in tgif. To create a regex with a literal period, add a slash before it; so \. translates to “find me the period symbol”. So the regex to find .gif would be \.gif.

  3. Find any number of characters before .gif.

    To find any number of characters, you can use .*, which translates to “find one character (.) zero or more times (*).” That regular expression matches all of the letters in any string. However, if you used that to create a regular expression like .*\.gif, you could end up matching more than just a file name. For example, if you have the string ‘the file is logo.gif', the regex .*\.gif will match the entire string, when what you really want is just logo.gif. To do that, use the \S character, which matches any nonspace character: \S*\.gif matches just logo.gif in the string.

  4. Make the search case-insensitive.

    There’s one more wrinkle in this regular expression: it only finds files that end in .gif, but .GIF is also a valid file extension, so this regex wouldn’t pick up on a name like logo.GIF. To make a regular expression ignore the difference between upper and lowercase letters, you use the i argument when you create the regular expression:

    /\S*\.gif/i

    Notice that the i goes outside of the pattern and to the right of the / that defines the end of the regular expression pattern.

  5. Put it into action:

    var testString = 'The file is logo.gif'; // the string to test
    var gifRegex = /\S*\.gif/i; // the regular expression
    var results = testString.match(gifRegex);
    var file = results[0]; // logo.gif

    This code pulls out the file name from the string. (You’ll learn how the match() method works on Matching every instance of a pattern.)

Grouping Parts of a Pattern

You can use parentheses to create a subgroup within a pattern. Subgroups come in very handy when using any of the characters in Table 4-4 to match multiple instances of the same pattern.

Table 4-3. Characters used for matching multiple occurrences of the same character or pattern

Character

Matches

?

Zero or one occurrences of the previous item, meaning the previous item is optional, but if it does appear, it can only appear once. For example the regex colou?r will match both “color” and “colour,” but not “colouur.”

+

One or more occurrences of the previous item. The previous item must appear at least once.

*

Zero or more occurrences of the previous item. The previous item is optional and may appear any number of times. For example, .* matches any number of characters.

{n}

An exact number of occurrences of the previous item. For example \d{3} only matches three numbers in a row.

{n, }

The previous item n or more times. For example, a{2,} will match the letter “a” two or more times: that would match “aa” in the word “aardvark” and “aaaa” in the word “aaaahhhh.”

{n,m}

The previous item at least n times but no more than m times. So \d{3,4} will match three or four numbers in a row (but not two numbers in a row, nor five numbers in a row).

For example, say you want to see if a string contains either “Apr” or “April”—both of those begin with “Apr,” so you know that you want to match that, but you can’t just match “Apr,” since you’d also match the “Apr” in “Apricot” or “Aprimecorp.” So, you must match “Apr” followed by a space or other word ending (that’s the \b regular expression character described in Table 4-3) or April followed by a word ending. In other words, the “il” is optional. Here’s how you could do that using parentheses:

var sentence = 'April is the cruelest month.';
var aprMatch = /Apr(il)?\b/;
if (sentence.search(aprMatch) != -1) {
  // found Apr or April
} else {
   //not found
}

The regular expression used here—/Apr(il)?\b/—makes the “Apr” required, but the subpattern—(il)—optional (that ? character means zero or one time). Finally, the \b matches the end of a word, so you won’t match “Apricot” or “Aprilshowers.” (See the box on Trying Out Regular Expressions for another use of subpatterns.)

Tip

You can find a complete library of regular expressions at www.regexlib.com. At this Web site, you’ll find a regular expression for any situation.

Useful Regular Expressions

Creating a regular expression has its challenges. Not only do you need to understand how the different regular expression characters work, but you then must figure out the proper pattern for different possible searches. For example, if you want to find a match for a Zip code, you need to take into account the fact that a Zip code may be just five numbers (97213) or 5+4 (97213-3333). To get you started on the path to using regular expressions, here are a few common ones.

Note

If you don’t feel like typing these regular expressions (and who could blame you), you’ll find them already set up for you in a file named example_regex.txt in the chapter04 folder that’s part of the tutorial download. (See Your First JavaScript Program for information on downloading the tutorial files.)

U.S. Zip code

Postal codes vary from country to country, but in the United States they appear as either five numbers, or five numbers followed by a hyphen and four numbers. Here’s the regex that matches both those options:

\d{5}(-\d{4})?

Tip

For regular expressions that match the postal codes of other countries visit http://regexlib.com/Search.aspx?k=postal+code.

That regular expression breaks down into the following smaller pieces:

  • \d{5} matches five digits, as in 97213.

  • ( ) creates a subpattern. Everything between the parentheses is considered a single pattern to be matched. You’ll see why that’s important in a moment.

  • -\d{4} matches the hyphen followed by four digits, like this: -1234.

  • ? matches zero or one instance of the preceding pattern. Here’s where the parentheses come in: (-\d{4}) is treated as a single unit, so the ? means match zero or one instance of a hyphen followed by four digits. Because you don’t have to include the hyphen + four, that pattern might appear zero times. In other words, if you’re testing a value like 97213, you’ll still get a match because the hyphen followed by four digits is optional.

    Tip

    To make sure an entire string matches a regular expression, begin the regex with ^ and end it with $. For example, if you want to make sure that someone only typed a validly formatted Zip code into a Zip code form field, use the regex ^\d{5}(-\d{4})?$. to prevent a response like “blah 97213 blah blah.”

U.S. phone number

U.S. phone numbers have a three-digit area code followed by seven more digits. However, people write phone numbers in many different ways, like 503-555-1212, (503) 555-1212, 503.555.1212, or just 503 555 1212. A regex for this pattern is:

\(?(\d{3})\)?[ -.](\d{3})[ -.](\d{4})

Tip

For regular expressions that match the phone number format of other countries, visit http://regexlib.com/Search.aspx?k=phone+number.

This regex looks pretty complicated, but if you break it down (and have a good translation like the following) it comes out making sense:

  • \( matches a literal opening parenthesis character. Because parentheses are used to group patterns (see the Zip code example previously), the opening parentheses has special meaning in regular expressions. To tell the JavaScript interpreter to match an actual opening parenthesis, you need to escape the character (just like escaping the quotes discussed on Booleans) with the forward slash character.

  • ? indicates that the ( character is optional, so a phone number without parentheses like 503-555-1212 will still match.

  • (\d{3}) is a subpattern that matches any three digits.

  • \)? matches an optional closing parenthesis.

  • [ -.] will match either a space, hyphen, or period. (Note that normally you have to escape a period like this \. in order to tell the JavaScript interpreter that you want to match the period character and not treat it as the special regular expression symbol that matches any character; however, when inside brackets, a period is always treated literally.)

  • (\d{3}) is another subpattern that matches any three digits.

  • [ -.] will match either a space, hyphen or period.

  • (\d{4}) is the last subpattern, and it matches any four digits.

    Note

    Subpatterns are patterns that appear inside parentheses, as in (\d{3}) in the phone number regular expression above. They come in very handy when you use the replace(), method as described in the box on Trying Out Regular Expressions.

Email address

Checking for a valid email address is a common chore when accepting user input from a form. A lot of people try to get away without trying to provide a valid email using a response like “none of your business,” or people just mistype their email address ( for example). The following regex can check to see if a string contains a properly formatted email address:

[-\w.]+@([A-z0-9][-A-z0-9]+\.)+[A-z]{2,4}

Note

This regex doesn’t check to see if an address is somebody’s real, working email address, it just checks that it’s formatted like a real email address.

This regex breaks down like this:

  • [-\w.]+ matches a hyphen, any word character, or a period one or more times. So it will match “bob,” “bob.smith,” or “bob-smith.”

  • @ is the @ sign you find in an email address: .

  • [A-z0-9] matches one letter or number.

  • [-A-z0-9]+ matches one or more instances of a letter, number, or hyphen.

  • \. is a period character so it would match the period in sawmac.com.

  • + matches one or more instances of the pattern that includes the above three matches. This character allows for subdomain names like .

  • [A-z]{2,4} is any letter 2, 3, or 4 times. This matches the com in .com, or uk in .uk.

Note

The email regex listed above doesn’t match all technically valid email addresses. For example, !#$%&'*+-/=?^_`.{|}~@example.com is technically a valid email address, but the regex described here won’t match it. It’s designed to find email addresses that people would actually use. If you really want to be accurate, you can use the following regex. Type this expression on a single line:

/^[\w!#$%&\'*+\/=?^`{|}~.-]+@(?:[a-z\d][a-z\d-]*(?:\.[a-z\d][a-z\d-]*)?)+\.
(?:[a-z][a-z\d-]+)$/i

Date

A date can be written in many different ways; for example, 09/28/2008, 9-28-2007, 09 28 2007, or even 09.28.2007. (And those are just formats for the United States. In other part of the world, the day appears before the month like 28.09.2007.) Because your visitors may enter a date in any one of these formats, you need a way to check to see if they supplied a validly formatted date. (In the box on Trying Out Regular Expressions, you’ll learn how to convert any of these formats into a single, standard format, so that you can make sure all the dates you receive on a form are formatted correctly.)

Here’s the regex that checks for a correctly entered date:

([01]?\d)[-\/ .]([0123]?\d)[-\/ .](\d{4})
  • ( ) surrounds the next two regex patterns to group them. Together they form the number for the month.

  • [01]? matches either 0 or 1 and the ? makes this optional. This is for the first number in a month. Obviously it can’t be bigger than 1—there’s no 22 month. In addition, if the month is January through September, you might just get 5 instead of 05. That’s why it’s optional.

  • \d matches any number.

  • [-\/ .] will match a hyphen, a forwardslash, a period, or a space character. These are the acceptable separators between the month and day, like 10/21, 10 21, 10.21, or 10-21.

  • () is the next subpattern, which is meant to capture the day of the month.

  • [0123]? matches either 0, 1, 2, or 3 zero or more times. Since there’s no 40th day of the month, you limit the first number of the month to one of these four digits. This pattern is optional (as determined by the ? character), because someone might just type 9 instead of 09 for the ninth day of the month.

  • \d matches any digit.

  • [-\/ .] is the same as above.

  • () captures the year.

  • \d{4} matches any four digits, like 1908 or 2880.

Web address

Matching a Web address is useful if you’re asking a visitor for his Web site address and you want to make sure he’s supplied one, or if you want to scan some text and identify every URL listed. A basic regular expression for URLs is:

((\bhttps?:\/\/)|(\bwww\.))\S*

This expression is a little tricky because it uses lots of parentheses to group different parts of the expression. Figure 4-4 can help guide you through this regular expression. One set of parentheses (labeled 1) wraps around two other parenthetical groups (2 and 3). The | character between the two groups represents “or”. In other words, the regular expression needs to match either 2 or 3.

  • ( is the start of the outer group (1 in Figure 4-4).

  • ( is the start of inner group (2 in Figure 4-4).

  • \b matches the beginning of a word.

  • http matches the beginning of a complete Web address that begins with http.

  • s? is an optional s. Since a Web page may be sent via a secure connection, a valid Web address may also begin with https.

  • :\/\/ matches ://. Since the forward slash has meaning in regular expressions, you need to precede it by a backslash to match the forward slash character.

  • ) is the end of the inner group (2 in Figure 4-4). Taken all together, this group will match either http:// or https://.

  • | matches either one or the other group (2 or 3 in Figure 4-4).

  • ( is the start of second inner group (3 in Figure 4-4).

  • \b matches the beginning of a word.

  • www\. matches www..

  • ) is the end of the second inner group (3 in Figure 4-4). This group will capture a URL that is missing the http:// but begins with www.

  • ) is the end of the outer group (1 in Figure 4-4). At this point, the regular expression will match text that begins with http://, https://, or www.

  • \S* matches zero or more nonspace characters.

This expression isn’t foolproof (for example, it would match a nonsensical URL like http://#$*%&*@*), but it’s relatively simple, and will successfully match real URLs like http://www.sawmac.com/missing/js/index.html.

You can group expressions using parentheses and look for either one of two expressions by using the | (pipe) character. For example, the outer expression (1) will match any text that matches either 2 or 3.
Figure 4-4. You can group expressions using parentheses and look for either one of two expressions by using the | (pipe) character. For example, the outer expression (1) will match any text that matches either 2 or 3.

Tip

To see if a string only contains a URL (nothing comes before or after the URL), use the ^ and $ characters at the beginning and end of the regular expression and remove the \b characters: ^((https?:\/\/)|(www\.))\S*$.

Matching a Pattern

The search() method described on Building a Regular Expression is one way to see if a string contains a particular regular expression pattern. The match() method is another. You can use it with a string to not only see if a pattern exists within the string, but to also capture that pattern so that you can use it later in your script. For example, say you have a text area field on a form for a visitor to add a comment to your site. Perhaps you want to check if the comments include a URL, and if so, get the URL for further processing.

The following code finds and captures a URL using match():

// create a variable containing a string with a URL
var text='my web site is www.missingmanuals.com';
// create a regular expression
var urlRegex = /((\bhttps?:\/\/)|(\bwww\.))\S*/
// find a match for the regular expression in the string
var url = text.match(urlRegex);
alert(url[0]); // www.missingmanuals.com

First, the code creates a variable containing a string that includes the URL www.missingmanuals.com. Next, a regular expression matches a URL (see Web address for the details on this regex). Finally, it runs the match() method on the string. The match() function is a string method, so you start with the name of a variable containing a string, add a period, followed by match(). You pass the match() method a regular expression to match.

In the above example, the variable url holds the results of the match. If the regular expression pattern isn’t found in the string, then the result is a special JavaScript value called null. If there is a match, the script returns an array—the first value of the array is the matched text. For instance, in this example, the variable url contains an array, with the first array element being the matched text. In this case, url[0] contains www.missingmanuals.com (see Arrays for more on arrays).

Tip

In JavaScript, a null value is treated the same as false, so you could test to see if the match() method actually matched something like this:

var url = text.match(urlRegex);
if (! url) {
  //no match
} else {
  //match
}

Matching every instance of a pattern

The match() method works in two different ways, depending on how you’ve set up your regular expression. In the above example, the method returns an array with the first matched text. So, if you had a long string containing multiple URLs, only the first URL is found. However, you can also turn on a regular expression’s global search property to search for more than one match in a string.

You make a search global by adding a g at the end of a regular expression when you create it (just like the i used for a case-insensitive search, as discussed on Grouping Parts of a Pattern):

var urlRegex = /((\bhttps?:\/\/)|(\bwww\.))\S*/g

Notice that the g goes outside of the ending / (which is used to enclose the actual pattern). This regular expression performs a global search; when used with the match() method, it searches for every match within the string and will return an array of all matched text—a great way to find every URL in a blog entry, for example, or every instance of a word in a long block of text.

You could rewrite the code from Matching every instance of a pattern using a global search, like this:

// create a variable containing a string with a URL
var text='there are a lot of great web sites like ↵
          www.missingmanuals.com and http://www.oreilly.com';
// create a regular expression with global search
var urlRegex = /((\bhttps?:\/\/)|(\bwww\.))\S*/g
// find a match for the regular expression in the string
var url = text.match(urlRegex);
alert(url[0]);
alert(url[1]); // http://www.oreilly.com

You can determine the number of matches by accessing the length property of the resulting array: url.length. This example will return the number 2, since two URLs were found in the tested string. In addition, you access each matched string by using the array’s index number (as described on Accessing Items in an Array); so in this example, url[0] is the first match and url[1] is the second.

Replacing Text

You can also use regular expression to replace text within a string. For example, say you have a string that contains a date formatted like this: 10.28.2008. However, you want the date to be formatted like this: 10/28/2008. The replace() method can do that. It takes this form:

string.replace(regex,'replace');

The replace() method takes two arguments: the first is a regular expression that you wish to find in the string; the second is a string that replaces any matches to the regular expression. So, to change the format of 10.28.2008 to 10/28/2008, you could do this:

1   var date='10.28.2008'; // a string
2   var replaceRegex = /\./g // a regular expression
3   var date = date.replace(replaceRegex, '/'); // replace . with /
4   alert(date); // 10/28/2008

Line 1 creates a variable and stores the string ’10.28.2008’ in it. In a real program, this string could be input from a form. Line 2 creates the regular expression: the / and / marks the beginning and end of the regular expression pattern; the \. indicates a literal period; and the g means a global replace—every instance of the period will be replaced. If you left out the g, only the first matched period would be replaced, and you’d end up with ’10 /28.2008’. Line 3 performs the actual replacement—changing each . to a /, and stores the result back into the date variable. Finally the newly formed date—10/28/2008—is displayed in an alert box.

Trying Out Regular Expressions

As mentioned on Building a Regular Expression, you’ll find sample regular expressions in the example_regex.txt file that accompanies the Chapter 4 tutorial files. In addition, you’ll find a file named regex_tester.html. You can open this Web page in a browser and try your hand at creating your own regular expressions (see Figure 4-5). Just type the string you’d like to search in the “String to Search” box, and then type a regular expression in the box (leave out the beginning and ending / marks used when creating a regex in JavaScript and just type the search pattern). You can then select the method you’d like to use—Search, Match, or Replace—and any options, like case-insensitivity or global search. Click the Run button and see how your regex works.

This sample page, included with the tutorial files, lets you test out regular expressions using different methods—like Search or Match—and try different options such as case-insensitive or global searches.
Figure 4-5. This sample page, included with the tutorial files, lets you test out regular expressions using different methods—like Search or Match—and try different options such as case-insensitive or global searches.

Numbers

Numbers are an important part of programming. They let you perform tasks like calculating a total sales cost, determining the distance between two points, or simulating the roll of a die by generating a random number from 1 to 6. JavaScript gives you many different ways of working with numbers.

Changing a String to a Number

When you create a variable, you can store a number in it like this:

var a = 3.25;

However, there are times when a number is actually a string. For example, if you use the prompt() method (Tutorial: Asking for Information) to get visitor input, even if someone types 3.25, you’ll end up with a string that contains a number. In other words, the result will be ’3.25’ (a string) and not 3.25 (a number). Frequently, this method doesn’t cause a problem, since the JavaScript interpreter usually converts a string to a number when it seems like a number is called for. For example:

var a = '3';
var b = '4';
alert(a*b); // 12

In this example, even though the variables a and b are both strings, the JavaScript interpreter converts them to numbers to perform the multiplication (3 x 4) and return the result: 12.

However, when you use the + operator, the JavaScript interpreter won’t make that conversion, and you can end up with some strange results:

var a = '3';
var b = '4';
alert(a+b); // 34

In this case, both a and b are strings; the + operator not only does mathematical addition, it also combines (concatenates) two strings together (see The Order of Operations). So instead of adding 3 and 4 to get 7, in this example, you end up with two strings fused together: 34.

When you need to convert a string to a number, JavaScript provides several ways:

  • Number() converts whatever string is passed to it into a number, like this:

    var a = '3';
    a = Number(a); // a is now the number 3

    So the problem of adding two strings that contain numbers could be fixed like this:

    var a = '3';
    var b = '4';
    var total = Number(a) + Number(b); // 7

    A faster technique is the + operator, which does the same thing as Number(). Just add a + in front of a variable containing a string, and the JavaScript interpreter converts the string to a number.

    var a = '3';
    var b = '4';
    var total = +a + +b // 7

    The downside of either of these two techniques is that if the string contains anything except numbers, a single period or a + or – sign at the beginning of the string, you’ll end up with a nonnumber, or the JavaScript value NaN, which means “not a number” (see Combining Numbers and Strings).

  • parseInt() tries to convert a string to a number as well. However, unlike Number(), parseInt() will try to change even a string with letters to a number, as long as the string begins with numbers. This command can come in handy when you get a string like ’20 years’ as the response to a question about someone’s age:

    var age = '20 years';
    age = parseInt(age,10); //20

    The parseInt() method looks for either a number or a + or – sign at the beginning of the string and continues to look for numbers until it encounters a nonnumber. So in the above example, it returns the number 20 and ignores the other part of the string, ' years’.

    Note

    You’re probably wondering what the 10 is doing in parseInt(age,10);. JavaScript can handle Octal numbers (which are based on 8 different digits 0-7, unlike decimal numbers which are based on 10 different digits 0-9); when you add the, 10 to parseInt(), you’re telling the JavaScript interpreter to treat whatever the input is as a decimal number. That way, JavaScript correctly interprets a string like ’08’ in a prompt window or form field—decimally. For example, in this code age would be equal to 0:

    var age = '08 years';
    age = parseInt(age);

    However, in the following code the variable age would hold the value 8:

    var age = '08 years';
    age = parseInt(age,10);

    In other words, always add the ,10 when using the parseInt() method.

    This method is also helpful when dealing with CSS units. For example, if you want to find the width of an element on a page (you’ll learn how to do that on Reading and Changing CSS Properties), you often end up with a string like this: ’200px’ (meaning 200 pixels wide). Using the parseInt() method, you can retrieve just the number value and then perform some operation on that value.

  • parseFloat() is like parseInt(), but you use it when a string might contain a decimal point. For example, if you have a string like ’4.5 acres’ you can use parseFloat() to retrieve the entire value including decimal places:

    var space = '4.5 acres';
    space = parseFloat(space); // 4.5

    If you used parseInt() for the above example, you’d end up with just the number 4, since parseInt() only tries to retrieve whole numbers (integers).

Which of the above methods you use depends on the situation: If your goal is to add two numbers, but they’re strings, then use Number() or + operator. However, if you want to extract a number from a string that might include letters, like ’200px’ or ’1.5em', then use parseInt() to capture whole numbers (200, for example) or parseFloat() to capture numbers with decimals (1.5, for example).

Testing for Numbers

When using JavaScript to manipulate user input, you often need to verify that the information supplied by the visitor is of the correct type. For example, if you ask for people’s years of birth, you want to make sure they supply a number. Likewise, when you’re performing a mathematical calculation, if the data you use for the calculation isn’t a number, then your script might break.

To verify that a string is a number, use the isNaN() method. This method takes a string as an argument and tests whether the string is “not a number.” If the string contains anything except a plus or minus (for positive and negative numbers) followed by numbers and an optional decimal value, it’s considered “not a number,” so the string '-23.25’ is a number, but the string ’24 pixels’ is not. This method returns either true (if the string is not a number) or false (if it is a number). You can use isNaN() as part of a conditional statement like this:

var x = '10'; // is a number
if (isNaN(x)) {
  // is NOT a number
} else {
  // it is a number
}

Rounding Numbers

JavaScript provides a way to round a fractional number to an integer—for example, rounding 4.5 up to 5. Rounding comes in handy when you’re performing a calculation that must result in a whole number. For example, say you’re using JavaScript to dynamically set a pixel height of a <div> tag on the page based on the height of the browser window. In other words, the height of the <div> is calculated using the window’s height. Any calculation you make might result in a decimal value (like 300.25), but since there’s no such thing as .25 pixels, you need to round the final calculation to the nearest integer (300, for example).

You can round a number using the round() method of the Math object. The syntax for this looks a little unusual:

Math.round(number)

You pass a number (or variable containing a number) to the round() method, and it returns an integer. If the original number has a decimal place with a value below .5, the number is rounded down; if the decimal place is .5 or above, it is rounded up. For example, 4.4 would round down to 4, while 4.5 rounds up to 5.

var decimalNum = 10.25;
var roundedNum = Math.round(decimalNum); // 10

Note

JavaScript provides two other methods for rounding numbers Math.ceil() and Math.floor(). You use them just like Math.round(), but Math.ceil() always rounds the number up (for example, Math.ceil(4.0001) returns 5), while Math.floor() always rounds the number down: Math.floor(4.99999) returns 4. To keep these two methods clear in your mind, think a ceiling is up, and a floor is down.

Formatting Currency Values

When calculating product costs or shopping cart totals, you’ll usually include the cost, plus two decimals out, like this: 9.99. But even if the monetary value is a whole number, it’s common to add two zeros, like this: 10.00. And a currency value like 8.9 is written as 8.90. Unfortunately, JavaScript doesn’t see numbers that way: it leaves the trailing zeros off (10 instead of 10.00, and 8.9 instead of 8.90, for example).

Fortunately, there’s a method for numbers called toFixed(), which lets you convert a number to a string that matches the number of decimal places you want. To use it, add a period after a number (or after the name of a variable containing a number), followed by toFixed(2):

var cost = 10;
var printCost = '$' + cost.toFixed(2); // $10.00

The number you pass the toFixed() method determines how many decimal places to go out to. For currency, use 2 to end up with numbers like 10.00 or 9.90; if you use 3, you end up with 3 decimal places, like 10.000 or 9.900.

If the number starts off with more decimal places than you specify, the number is rounded to the number of decimal places specified. For example:

var cost = 10.289;
var printCost = '$' + cost.toFixed(2); // $10.29

In this case, the 10.289 is rounded up to 10.29.

Note

The toFixed() method only works with numbers. So if you use a string, you end up with an error:

var cost='10';//a string
var printCost='$' + cost.toFixed(2);//error

To get around this problem, you need to convert the string to a number as described on Numbers, like this:

var cost='10';//a string
cost = +cost;
var printCost='$' + cost.toFixed(2);//$10.00

Creating a Random Number

Random numbers can help add variety to a program. For example, say you have an array of questions for a quiz program (like Script 3.3 on Keeping Variables from Colliding). Instead of asking the same questions in the same order each time, you can randomly select one question in the array. Or, you could use JavaScript to randomly select the name of a graphic file from an array and display a different image each time the page loads. Both of these tasks require a random number.

JavaScript provides the Math.random() method for creating random numbers. This method returns a randomly generated number between 0 and 1 (for example .9716907176080688 or .10345038010895868). While you might not have much need for numbers like those, you can use some simple math operations to generate a whole number from 0 to another number. For example, to generate a number from 0 to 9, you’d use this code:

Math.floor(Math.random()*10);

This code breaks down into two parts. The part inside the Math.floor() method—Math.random()*10—generates a random number between 0 and 10. That will generate numbers like 4.190788392268892; and since the random number is between 0 and 10, it never is 10. To get a whole number, the random result is passed to the Math.floor() method, which rounds any decimal number down to the nearest whole number, so 3.4448588848 becomes 3 and .1111939498984 becomes 0.

If you want to get a random number between 1 and another number, just multiply the random() method by the uppermost number and add one to the total. For example, if you want to simulate a die roll to get a number from 1 to 6:

var roll = Math.floor(Math.random()*6 +1); // 1,2,3,4,5 or 6

Randomly selecting an array element

You can use the Math.random() method to randomly select an item from an array. As discussed on Accessing Items in an Array, each item in an array is accessed using an index number. The first item in an array uses an index value of 0, and the last item in the array is accessed with an index number that’s 1 minus the total number of items in the array. Using the Math.random() method makes it really easy to randomly select an array item:

var people = ['Ron','Sally','Tricia','Bob']; //create an array
var random = Math.floor(Math.random() * people.length);
var rndPerson = people[random]; //

The first line of this code creates an array with four names. The second line does two things: First, it generates a random number between 0 and the number of items in the array (people.length)—in this example, a number between 0 and 4. Then it uses the Math.floor() method to round down to the nearest integer, so it will produce the number 0, 1, 2, or 3. Finally, it uses that number to access one element from the array and store it in a variable named rndPerson.

A function for selecting a random number

Functions are a great way to create useful, reusable snippets of code (Functions: Turn Useful Code Into Reusable Commands). If you use random numbers frequently, you might want a simple function to help you select a random number between any two numbers—for example, a number between 1 and 6, or 100 and 1,000. The following function is called using two arguments; The first is the bottom possible value (1 for example), and the second is the largest possible value (6 for example):

function rndNum(from, to) {
  return Math.floor((Math.random()*(to - from + 1)) + from);
}

To use this function, add it to your Web page (as described on Functions: Turn Useful Code Into Reusable Commands), and then call it like this:

var dieRoll = rndNum(1,6); // get a number between 1 and 6

Dates and Times

If you want to keep track of the current date or time, turn to JavaScript’s Date object. This special JavaScript object lets you determine the year, month, day of the week, hour, and more. To use it, you create a variable and store a new Date object inside it like this:

var now = new Date();

The new Date() command creates a Date object containing the current date and time. Once created, you can access different pieces of time and date information using various date-related methods as listed in Table 4-5. For example, to get the current year use the getFullYear() method like this:

var now = new Date();
var year = now.getFullYear();

Note

new Date() retrieves the current time and date as determined by each visitor’s computer. In other words, if someone hasn’t correctly set their computer’s clock, then the date and time won’t be accurate.

Table 4-4. Methods for accessing parts of the Date object

Method

What it returns

getFullYear()

The year: 2008, for example.

getMonth()

The month as an integer between 0 and 11: 0 is January and 11 is December.

getDate()

The day of the month—a number between 1 and 31.

getDay()

The day of the week as a number between 0 and 6. 0 is Sunday, and 6 is Saturday.

getHours()

Number of hours on a 24-hour clock (i.e. a number between 0 and 23). For example, 11p.m. is 23.

getMinutes()

Number of minutes between 0 and 59.

getSeconds()

Number of seconds between 0 and 59.

getTime()

Total number of milliseconds since January 1, 1970 at midnight (see box on Getting the Day of the Week).

Getting the Month

To retrieve the month for a Date object, use the getMonth() method, which returns the month’s number:

var now = new Date();
var month = now.getMonth();

However, instead of returning a number that makes sense to us humans (as in 1 meaning January), this method returns a number that’s one less. For example, January is 0, February is 1, and so on. If you want to retrieve a number that matches how we think of months, just add 1 like this:

var now = new Date();
var month = now.getMonth()+1;//matches the real month

There’s no built-in JavaScript command that tells you the name of a month. Fortunately, JavaScript’s strange way of numbering months comes in handy when you want to determine the actual name of the month. You can accomplish that by first creating an array of month names, then accessing a name using the index number for that month:

var months = ['January','February','March','April','May',
              'June','July','August','September',
              'October','November','December'];
var now = new Date();
var month = months[now.getMonth()];

The first line creates an array with all twelve month names, in the order they occur (January–December). Remember that to access an array item you use an index number, and that arrays are numbered starting with 0 (see Accessing Items in an Array). So to access the first item of the array months, you use months[0]. So, by using the getMonth() method, you can retrieve a number to use as an index for the months array and thus retrieve the name for that month.

Getting the Day of the Week

The getDay() method retrieves the day of the week. And as with the getMonth() method, the JavaScript interpreter returns a number that’s one less than what you’d expect: 0 is considered Sunday, the first day of the week, while Saturday is 6. Since the name of the day of the week is usually more useful for your visitors, you can use an array to store the day names and use the getDay() method to access the particular day in the array, like this:

var days = ['Sunday','Monday','Tuesday','Wednesday',
            'Thursday','Friday','Saturday'];
var now = new Date();
var dayOfWeek = days[now.getDay()];

In the tutorial on Creating a date that’s one week from today, you’ll see use both the getDay() and getMonth() techniques to create a useful function for creating a human-readable date.

Getting the Time

The Date object also contains the current time, so you can display the current time on a Web page or use the time to determine if the visitor is viewing the page in the a.m. or p.m. You can then do something with that information, like display a background image of the sun during the day, or the moon at night.

You can use the getHours(), getMinutes(), and getSeconds() methods to get the hours, minutes, and seconds. So to display the time on a Web page, add the following in the HTML where you wish the time to appear:

var now = new Date();
var hours = now.getHours();
var minutes = now.getMinutes();
var seconds = now.getSeconds();
document.write(hours + ":" + minutes + ":" + seconds);

This code produces output like 6:35:56 to indicate 6 a.m., 35 minutes, and 56 seconds. However, it will also produce output that you might not like, like 18:4:9 to indicate 4 minutes and 9 seconds after 6 p.m. One problem is that most people reading this book, unless they’re in the military, don’t use the 24-hour clock. They don’t recognize 18 as meaning 6 p.m. An even bigger problem is that times should be formatted with two digits for minutes and seconds (even if they’re a number less than 10), like this: 6:04:09. Fortunately, it’s not difficult to adjust the above script to match those requirements.

Changing hours to a.m. and p.m.

To change hours from a 24-hour clock to a 12-hour clock, you need to do a couple of things. First, you need to determine if the time is in the morning (so you can add ‘am’ after the time) or in the afternoon (to append ‘pm'). Second, you need to convert any hours greater than 12 to their 12-hour clock equivalent (for example, change 14 to 2 p.m.).

Here’s the code to do that:

 1    var now = new Date();
 2    var hour = now.getHours();
 3    if (hour < 12) {
 4      meridiem = 'am';
 5    } else {
 6      meridiem = 'pm';
 7    }
 8    hour = hour % 12;
 9    if (hour==0) {
10      hour = 12;
11    }
12    hour = hour + ' ' + meridiem;

Note

The column of numbers at the far left is just line numbering to make it easier for you to follow the discussion below. Don’t type these numbers into your own code!

Lines 1 and 2 grab the current date and time and store the current hour into a variable named hour. Lines 3–7 determine if the hour is in the afternoon or morning; if the hour is less than 12 (the hour after midnight is 0), then it’s the morning (a.m.); otherwise, it’s the afternoon (p.m.).

Line 8 introduces a mathematical operator called modulus and represented by a percent (%) sign. It returns the remainder of a division operation. For example, 2 divides into 5 two times (2 x 2 is 4), with 1 left over. In other words, 5 % 2 is 1. So in this case, if the hour is 18, 18 % 12 results in 6 (12 goes into 18 once with a remainder of 6). 18 is 6 p.m., which is what you want. If the first number is smaller than the number divided into it (for example, 8 divided by 12), then the result is the original number. For example, 8 % 12 just returns 8; in other words, the modulus operator doesn’t change the hours before noon.

Lines 9–11 take care of two possible outcomes with the modulus operator. If the hour is 12 (noon) or 0 (after midnight), then the modulus operator returns 0. In this case, hour is just set to 12 for either 12 p.m. or 12 a.m.

Finally, line 12 combines the reformatted hour with a space and either “am” or “pm”, so the result is displayed as, for example, “6 am” or “6 pm”.

Padding single digits

As discussed on Getting the Day of the Week, when the minutes or seconds values are less than 10, you can end up with weird output like 7:3:2 p.m. To change this output to the more common 7:03:02 p.m., you need to add a 0 in front of the single digit. It’s easy with a basic conditional statement:

1    var minutes = now.getMinutes();
2    if (minutes<10) {
3      minutes = '0' + minutes;
4    }

Line 1 grabs the minutes in the current time, which in this example could be 33 or 3. Line 2 simply checks if the number is less than 10, meaning the minute is a single digit and needs a 0 in front of it. Line 3 is a bit tricky, since you can’t normally add a 0 in front of a number: 0 + 2 equals 2, not 02. However, you can combine strings in this way so ’0’ + minutes means combine the string ’0’ with the value in the minutes variable. As discussed on Combining Numbers and Strings, when you add a string to a number, the JavaScript interpreter converts the number to a string as well, so you end up with a string like ’08’.

You can put all of these parts together to create a simple function to output times in formats like 7:32:04 p.m., or 4:02:34 a.m., or even leave off seconds altogether for a time like 7:23 p.m.:

function printTime(secs) {
    var sep = ':'; //seperator character
    var hours,minutes,seconds,time;
    var now = new Date();
    hours = now.getHours();
    if (hours < 12) {
        meridiem = 'am';
    } else {
        meridiem = 'pm';
    }
    hours = hours % 12;
    if (hours==0) {
        hours = 12;
    }
    time = hours;
    minutes = now.getMinutes();
    if (minutes<10) {
        minutes = '0' + minutes;
    }
    time += sep + minutes;
    if (secs) {
        seconds = now.getSeconds();
        if (seconds<10) {
            seconds = '0' + seconds;
        }
        time += sep + seconds;
    }
    return time + ' ' + meridiem;
}

You’ll find this function in the file printTime.js in the chapter04 folder in the Tutorials. You can see it in action by opening the file time.html (in that same folder) in a Web browser. To use the function, either attach the printTime.js file to a Web page (see External JavaScript Files), or copy the function into a Web page or another external JavaScript file (How to Add JavaScript to a Page). To get the time, just call the function like this: printTime(), or, if you want the seconds displayed as well, printTime(true). The function will return a string containing the current time in the proper format.

Creating a Date Other Than Today

So far, you’ve seen how to use new Date() to capture the current date and time on a visitor’s computer. But what if you want to create a Date object for next Thanksgiving or New Year’s? JavaScript lets you create a date other than today in a few different ways. You might want to do this if you’d like to do a calculation between two dates: for example, “How many days until the new year?” (Also see the box on Getting the Day of the Week.)

When using the Date() method, you can also specify a date and time in the future or past. The basic format is this:

new Date(year,month,day,hour,minutes,seconds,milliseconds);

For example, to create a Date for noon on New Year’s Day 2010, you could do this:

var ny2010 = new Date(2010,0,1,12,0,0,0);

This code translates to “create a new Date object for January 1, 2010 at 12 o’clock, 0 minutes, 0 seconds, and 0 milliseconds.” You must supply at least a year and month, but if you don’t need to specify an exact time, you can leave off milliseconds, seconds, minutes, and so on. For example, to just create a date object for January 1, 2010, you could do this:

var ny2010 = new Date(2010,0,1);

Note

Remember that JavaScript uses 0 for January, 1 for February, and so on, as described on Getting the Day of the Week.

Creating a date that’s one week from today

As discussed in the box on Getting the Day of the Week, the JavaScript interpreter actually treats a date as the number of milliseconds that have elapsed since Jan 1, 1970. Another way to create a date is to pass a value representing the number of milliseconds for that date:

new Date(milliseconds);

So another way to create a date for January 1, 2010 would be like this:

var ny2010 = new Date(1262332800000);

Of course, since most of us aren’t human calculators, you probably wouldn’t think of a date like this. However, milliseconds come in very handy when you’re creating a new date that’s a certain amount of time from another date. For example, when setting a cookie using JavaScript, you need to specify a date at which point that cookie is deleted from a visitor’s browser. To make sure a cookie disappears after one week, you need to specify a date that’s one week from today.

To create a date that’s one week from now, you could do the following:

var now = new Date(); // today
var nowMS = now.getTime(); // get # milliseconds for today
var week = 1000*60*60*24*7; // milliseconds in one week
var oneWeekFromNow = new Date(nowMS + week);

The first line stores the current date and time in a variable named now. Next, the getTime() method extracts the number of milliseconds that have elapsed from January 1, 1970 to today. The third line calculates the total number of milliseconds in a single week (1000 milliseconds * 60 seconds * 60 minutes * 24 hours * 7 days). Finally, the code creates a new date by adding the number of milliseconds in a week to today.

Tutorial

To wrap up this chapter, you’ll create a useful function for outputting a date in several different human-friendly formats. The function will be flexible enough to let you print out a date, as in “January 1, 2009,” “1/1/09,” or “Monday, February 2, 2009.” In addition, you’ll use some of the date and string methods covered in this chapter to build this function.

Overview

As with any program you write, it’s good to start with a clear picture of what you want to accomplish and the steps necessary to get it done. For this program, you want to output the date in many different formats, and you want the function to be easy to use.

In other programming languages (like PHP or .NET), it’s common to use special characters or tokens to symbolize elements of a date that are formatted in a specific way. In PHP, for example, a lowercase l used with that language’s date function outputs the name of a month, like “January.”

In this program, you’ll use a similar approach by assigning special tokens to different parts of a date (see Table 4-5). The function will accept a date and a string containing these tokens, and return a human-friendly date.

For example, you’ll be able to call your function like this:

dateString(new Date(), '%N/%D/%Y');

This code returns a string, like ’01/25/2009’. In other words, the function replaces each token in the supplied string with a properly formatted part of the date. Note that the tokens listed in Table 4-5 aren’t any special JavaScript mojo; they’re just arbitrary characters that the author decided to use. You could just as easily change the function in this tutorial to accept different formatted tokens, like #YEAR# instead of %Y, or #DAY# instead of %D.

Table 4-5. Tokens for the date-formatting function

Token

Replaced with

%Y

Four digit year: 2009

%y

Last two digits of year: 09

%M

Full month name: January

%m

Abbreviated month name: Jan

%N

Number of month, with leading zero if necessary: 01

%n

Number of month without leading zero: 1

%W

Full name of weekday: Monday

%w

Abbreviated name of weekday: Mon

%D

Day of month with leading zero if necessary: 05

%d

Day of month without leading zero: 5

Writing the Function

Now it’s time to get down to coding and create your function. If you’re still a little unsure of what a function is and how it works, turn to Functions: Turn Useful Code Into Reusable Commands for a refresher.

Note

See the note on Your First JavaScript Program for information on how to download the tutorial files.

  1. In a text editor, open the file 4.1.html in the chapter04 folder.

    You’ll start by beginning the function definition.

  2. Between the first set of <script> tags in the page’s <head> section, type the code in bold:

    <script type="text/javascript">
    function dateString(date,string) {
    </script>

    This code creates a new function named dateString(), which accepts two pieces of information (arguments) and stores them in variables named date and string (see Mini-Tutorial for more on creating functions). The date variable will hold a JavaScript Date object, while the string variable will hold a string containing the special tokens like %D.

    It’s always a good idea to close any opening braces immediately, so you don’t forget later.

  3. Press Return twice to create two empty lines, and then type }.

    This closing brace marks the end of the function. All the code you enter between the braces makes up the steps in the function.

    This function will have two parts: the first part will get the different parts of the date in the proper formats; the second part of the function will then replace any tokens in the supplied string with correctly formatted parts of the date. First, you’ll determine the year.

  4. Click in the empty line above the closing brace you just typed and add the code in bold below:

    <script type="text/javascript">
    function dateString(date,string) {
     var year=date.getFullYear();
    }
    </script>

    This creates a new variable and stores the date’s full, four-digit year in it. Next you’ll get the date’s month and modify it for a few different format options.

  5. Hit Return to create a new, blank line, and then add the following code:

    var month=date.getMonth();
    var realMonth=month+1;

    The first line of code retrieves the number of the date’s month. Remember that JavaScript assigns a number that’s one less than you’d normally use for a month. For example, January is 0. So, the next line creates a variable named realMonth, which is simply the month plus 1. In other words, if the month is January, the realMonth variable will hold the number 1. Next, you’ll take care of the case when the month has to be two digits long: 11 or 08, for example.

  6. Press Return, and type:

    var fillMonth = realMonth;
    if (realMonth<10) {
      fillMonth = '0' + realMonth;
    }

    First, you declare a new variable named fillMonth, and store the current month’s value in it. This conditional statement adds zero in front of the value in realMonth, if realMonth is less than 10 and stores that value in fillMonth. This is the variable you’ll use if you want to format a date like this: 08/10/2008.

    Now you’ll get the name of the month.

  7. Hit Return and then add the following code:

    var months = ['January','February','March','April','May',
                  'June','July','August','September',
                  'October','November','December'];
    var monthName=months[month];

    The first line creates an array that stores the name of each month of the year. To get the proper name, you can use the value stored in the month variable as the index. For example, if the month is January, then the month variable will be 0: months[0] is the first item in the array, or the string ‘January’ (see Getting the Day of the Week for a detailed explanation).

    Next, you’ll retrieve the day of the month.

  8. Hit Return and then type:

    var day=date.getDate();
    var fillDate=day;
    if (day<10) {
      fillDate='0' + day;
    }

    The first line just gets the day of the month: if it’s January 5, then the date will be 5. The rest of the code above works like step 6, and adds a zero in front of any date that is less than 10, so 5 becomes 05.

    Now you’ll get the day of the week.

  9. Hit Return, and then add the following code:

    var weekday=date.getDay();
    var weekdays = ['Sunday','Monday','Tuesday','Wednesday', ↵
                    'Thursday','Friday','Saturday'];
    var dayName=weekdays[weekday];

    These three lines of code retrieve the name of the date’s day of the week. The method is similar to step 7: the names of the days of the week are stored in an array, then the correct name is retrieved using an index value retrieved from the getDay() method. For example, if the day of the week is Sunday, getDay() returns 0, and weekdays[0] returns the string ‘Sunday’.

    At this point, the function has collected all of the different parts of a date that you might need (year, month, and so on) and stored them into separate variables. Now, you’ll replace the tokens inside the string that was passed to the function with properly formatted date elements. First, you’ll tackle the year.

  10. Hit Return, and then type:

    string = string.replace(/%Y/g,year);

    Remember that string is a variable that’s created at the beginning of the function (see step 2), and it’s filled with a string full of tokens that the function will replace with formatted date parts. The heart of the process of replacing those tokens is the replace() method, which takes a regular expression and replaces any matches with another string (see Replacing Text). So string.replace() tells the JavaScript interpreter to execute the replace() method on the contents contained in the string variable.

    The first argument sent to replace() is a regular expression: /%Y/g. The first / marks the beginning of the regular expression pattern; %Y is the pattern to match. In other words, if the string contains the two characters %Y anywhere inside it, then there’s a match. The second / marks the end of the regex pattern, and the final g indicates that the replacement should be global. In other words, every instance of %Y should be replaced, not just the first one (see Replacing Text for a discussion of the g flag in regular expressions). The second argument—year—is the variable created in step 4.

    To break down this code into plain English: Replace every instance of %Y with the value stored in the variable year and store the results back into string. In other words, this line will replace %Y with something like 2009. If the characters %Y aren’t found in the string, then the string remains unchanged.

    Next, you’ll insert an abbreviated two-digit year when requested.

  11. Hit Return, and type:

    string = string.replace(/%y/g,year.toString().slice(-2));

    The token %y is to be replaced with just the last two digits of the year: 08, for example. This line of code uses the same replace() method described in step 10, but the replacement string (the year) is reduced to the last two digits using the slice() method described on Extracting Part of a String with slice().

    The rest of the lines of code in this function are all just variations on this theme: replace a token with one of the parts of the date.

  12. Hit Return and then type this code:

    string = string.replace(/%M/g,monthName);
    string = string.replace(/%m/g,monthName.slice(0,3));
    string = string.replace(/%N/g,fillMonth);
    string = string.replace(/%n/g,realMonth);
    string = string.replace(/%W/g,dayName);
    string = string.replace(/%w/g,dayName.slice(0,3));
    string = string.replace(/%D/g,fillDate);
    string = string.replace(/%d/g,day);

    These lines of code replace various tokens with the different formatted date elements created in the first part of this function. Once the program does all of the replacing, it returns the revised string.

  13. Press Return, and then type return string;

    The complete function should look like this:

    function dateString(date,string) {
      var year=date.getFullYear();
      var month=date.getMonth();
      var realMonth=month+1;
      var fillMonth=realMonth;
        if (realMonth<10) {
        fillMonth = '0' + realMonth;
      } 
      var months = ['January','February','March','April','May',
                    'June','July','August','September',
                    'October','November','December'];
      var monthName=months[month];
      var day=date.getDate();
      var fillDate=day;
        if (day<10) {
        fillDate='0' + day;
      }
      var weekday=date.getDay();
      var weekdays = ['Sunday','Monday','Tuesday','Wednesday', ↵
                      'Thursday','Friday','Saturday'];
      var dayName=weekdays[weekday];
      string = string.replace(/%Y/g,year); //2008
      string = string.replace(/%y/g,year.toString().slice(-2)); //08
      string = string.replace(/%M/g,monthName); //January
      string = string.replace(/%m/g,monthName.slice(0,3)); //Jan
      string = string.replace(/%N/g,fillMonth); //01
      string = string.replace(/%n/g,realMonth); //1
      string = string.replace(/%W/g,dayName); //Monday
      string = string.replace(/%w/g,dayName.slice(0,3)); //Mon
      string = string.replace(/%D/g,fillDate); //05
      string = string.replace(/%d/g,day); //5
      return string;
    }

    Now that the function is complete, you can use it to print many differently formatted dates to a page.

  14. Locate the second set of <script> tags down in the body of the page, and add the code in bold:

    <script type="text/javascript">
    var today = new Date();
    </script>

    This code creates a new variable named today and stores a Date object with the current date and time in it. You’ll use that Date object to call the newly created function

  15. Press Return and then type:

    var message = dateString(today, 'Today is %W, %M %d, %Y');

    Here you call the function by passing the Date object created previously as well as the string ‘Today is %W, %M %d, %Y’. Basically, the function takes the date, extracts different parts of the date, and then looks for and replaces any special token values in the string. You can refer to Table 4-5 to see what each of these tokens is replaced with, but, in a nutshell, this line of code will return a string like ‘Today is Sunday, January 6, 2008’ and store it into the variable message. Finally, you just need to print that string to the page.

  16. Hit Return one last time, and then type document.write(message);

    The final script should look like this.

    <script type="text/javascript">
    var today = new Date();
    var message = dateString(today, 'Today is %W, %M %d, %Y');
    document.write(message);
    </script>

    Save the file and preview it in a Web browser. The result should look something like Figure 4-6. The file complete_4.1.html contains the finished version of this tutorial. In addition, you’ll find a slightly more advanced version of this function in the file dateString.js. That function supports one other token, %O, which returns the date plus the correct ordinal for the date: 1st, 2nd, or 3rd, instead of 1, 2, or 3.

    The dateString() function you created in this tutorial lets you output a date in many different formats. Try rewriting the code in step 16 using different tokens listed in to produce dates in different formats.
    Figure 4-6. The dateString() function you created in this tutorial lets you output a date in many different formats. Try rewriting the code in step 16 using different tokens listed in Table 4-5 to produce dates in different formats.

Get JavaScript: The Missing Manual now with O’Reilly online learning.

O’Reilly members experience live online training, plus books, videos, and digital content from 200+ publishers.