Murach's Java Programming Word
Murach's Java Programming Word
Although Java doesn't have a primitive data type for working with dates
and times, it does have several classes that you can use to work with dates and
times. In this topic, you'll learn how to create objects that store dates and
times, how to manipulate the values stored in those objects, and how to format
those objects.
When you create dates and times, you usually use the GregorianCalendar
class as shown in figure 13-1. Although you might think that a class named
after a calendar would work mainly with dates, this class actually represents a
point in time down to the millisecond.
This figure starts by showing four constructors of the GregorianCalendar
class. The first constructor creates an object that contains the current date and
time. The next three constructors create objects that contain values for a date
and time that you specify. For instance, the second constructor creates a date
and time using integer values for year, month, and day. In this case, Java sets
the hour, minute, and second to 00. However, you can use the third or fourth
constructors to set these values.
The statement in the first example shows how to get the current date and
time. When you call this constructor, it sets the GregorianCalendar object equal
to the current date and time. Java gets this date from your computer's internal
clock. As a result, the date and time should be set correctly for your time zone.
The two statements in the second example show how to create a date
using literals as arguments in the constructor of the GregorianCalendar class.
Here, the first statement creates a GregorianCalendar object named startDate
and sets the date to January 30, 2009. The second statement creates a
GregorianCalendar object named startTime and sets it to 3:30 PM on July 20,
2012. Notice in both of these examples that the month is specified as an
integer between 0 and 11, which might not be what you'd expect.
Like the first statement in the second example, the statement in the third
example creates a GregorianCalendar object by supplying just a date. In this
case, though, the year, month, and day are supplied as variables instead of
literals.
When setting times, any values that you don't set will default to 0. The
exception is if you use the first constructor shown in this figure, in which case
the time is set to the current time. In addition, to set the hour, you must enter
an integer between 0 and 23 where 0 is equal to midnight and 23 is equal to Il
PM. As a result, the first statement of example 2 and example 3 sets the time to
midnight (12:00:00 AM). The second statement of example 2 sets the hours to
15, which represents 3:00 PM, and the minutes to 30.
Chapter 13 How to work with dates and strings 407
The
j
Description
Year must be a four-digit integer.
Month must be an integer from 0 to 11 with 0 being January and 11 being December.
Day must be an integer from 1 to 31.
Hour must be an integer from 0 to 23, with 0 being 12 AM (midnight) and 23 being
The
j
Calendar and GregorianCaIendar
fields and methods
set (intYear, intMonth Sets the values for year, month, day, hour, minute, and second just as
they are set in the constructor for the
GregorianCalendar class.
set (intFie1d, intVa1ue) Sets the specified field to the supplied value.
setTime (Date) Sets the date and time values based on the supplied Date object.
add ( intFie1d, intVa1ue) Adds the supplied value to the specified field.
roll (intFie1d, intVa1ue) Adds the supplied value to the specified field, but doesn't affect other
fields.
roll (intFie1d, booleanVa1ue) Increments the value of the specified field by 1 for true values
and decrements the value of the field by 1 for false
values.
get ( intFie1d) Returns the int value of the specified field.
getTime ( ) Returns a Date object.
The
j
Date class
Figure 13-3 shows how to use the Date class. Unlike the GregorianCalendar
class, the Date class doesn't have fields that represent the year, month, day, and so
on. Instead, the Date class represents a point in time by the number of milliseconds
since January 1, 1970 00:00:00 Greenwich Mean Time (GMT). You need to use Date
objects when you want to format a date as shown in the next figure. You may also
find Date objects useful when you want to perform arithmetic operations on dates
like subtracting one date from another.
To create a Date object, you can invoke the getTime method of a
GregorianCalendar object as shown in the first example in this figure. Since the
getTime method returns a Date object, you don't need to call either of the Date
constructors. However, you can also use either of the constructors in this figure to
create a Date object. The first constructor creates a Date object for the current date
and time while the second constructor creates a Date object based on the number of
milliseconds that are passed to it. The second example shows how to use the first
constructor to create a Date object for the current date and time.
The third example shows how to use the toString and getTime methods of the
Date class. The toString method returns a readable string that displays the day of
the week, month, date, time, time zone, and year. The getTime method returns a
long integer that represents the number of milliseconds since January 1, 1970
GMT.
The fourth example shows how Date objects can be useful when you want to
calculate the elapsed time between two dates. First, two GregorianCalendar dates are
converted to Date objects using the getTime method of the
GregorianCalendar class. Next, the Date objects are converted to milliseconds using
the getTime method of the Date class. Then, the starting date in milliseconds is
subtracted from the ending date in milliseconds to get the elapsed milliseconds, and
that result is divided by the number of milliseconds in a day to get the elapsed days.
This type of routine is useful in many business programs.
Date class
ava . util
Date;
Common constructors
Constructor Description
Date ( ) Creates a Date object for the current date and time based on your computer's internal
clock.
Date ( longMi11 i seconds ) Creates a Date object based on the number of milliseconds that is
passed to it.
Description
A Date object stores a date and time as the number of milliseconds since January l,
1970 GMT (Greenwich Mean Time).
You need to convert GregorianCalendar objects to Date objects when you want
to use the DateFormat class to format them as shown in the next figure.
Date objects are also useful when you want to calculate the number of
milliseconds (or days) between two dates.
Date class
DateFormat class
to format dates and times
Figure 13-4 shows how to use the DateFormat class to convert a Date
object to a string that you can use to display dates and times. In addition, it
Chapter 13 How to work with dates and strings 413
The
j
shows how to control the format of these strings. Since this class works
similarly to the NumberFormat class, you shouldn't have much trouble using it.
Before you can format a date, you need to use one of the static methods of
the DateFormat class to create a DateFormat object that has a particular format.
When you do that, you can choose to return the date only, the time only, or the
date and time. If you don't specify a format, the DateFormat object will use the
default format. However, you can use one of the four DateFormat fields to
override the default date format. Once you've created a DateFormat object that
has the format you want, you can use its format method to apply the specified
format to a Date object.
The first example shows how to format a Date object with the default
format. Here, the getDateTimeInstance method is used to return both date and
time. Since no arguments are supplied for this method, it will return a string
that contains the current date and time with the default format, which should
look something like this:
Jan 30, 2010 PM
The second example shows how to format a GregorianCalendar object with
the default date format. Here, you can see that you start by using the getTime
method to convert the GregorianCalendar object to a Date object. Then, you
use the getDateInstance method to return a format with the date only. Since no
arguments are supplied for this method, it will return a string that contains this
date:
Dec 31, 2010
The third example shows how you can use the fields of the DateFormat
class to override the default date format. Here, you can see how to use the
SHORT field, but the same skills apply to the other three fields. If you use the
getDateTimeInstance method, you need to supply the first argument for the
date and the second argument for the time. Since both of the arguments are
specified as short in this example, they will return a date with a format
something like this:
12/31/10 7:30 AM
When you use the LONG and FULL fields, the time portion of the date will
end with an abbreviation for the current time zone. In this figure, the examples
use the Pacific Standard Time (PST) time zone.
DateFormat class
ava . text . DateFormat ;
Common fields
Style Date example Time example
Common method
Method Description
format (Date) Returns a String object of the Date object with the
format that's specified by the DateFormat object.
Example 3: Code that overrides the default date and time formats
DateFormat shortDate = DateFormat . getDateInstance (DateFormat . SHORT) ;
DateFormat shortTime = DateFormat.getTimeInstance (DateFormat . SHORT) ; DateFormat
BhortDateTime =
DateFormat.getDateTime1nstance (DateFormat. SHORT, SHORT) ;
Description
You can use the DateFormat class to format Date objects in various ways.
Although the date handling features of the Java API are powerful, they must
frequently be used in combination to provide some of the most common operations
needed by business applications. As a result, it's common for an application that uses
dates to include a class like the one in figure 13-5. This class presents just a few of the
date handling operations you may need to perform, but it should give you a good idea of
what you can do with the date handling features.
In the DateUtils class, the getCurrentDate method returns a Date object that contains
just the current date. To do that, it creates a GregorianCalendar object with the current
date and time. Then, it uses the set method to set the hour, minute, and second to zero.
Finally, it uses the getTime method to convert the GregorianCalendar object to a Date
object. You might want to use a method like this to get a date that you can use to calculate
the age of an invoice. In that case, you'll want to be sure that neither the invoice date or
the current date contains a time so the age is calculated properly.
The createDate method provides a simple way to create a Date object for a specific
date with the hour, minute, and second set to zero. This method starts by creating a
GregorianCalendar object for the specified date. Then, it uses the getTime method to
convert the GregorianCalendar object to a Date object.
The stripTime method strips the hour, minute, and second from a Date object. It
works by setting a GregorianCalendar object to the date and time specified by the Date
object so the hour, minute, and second can be accessed.
Then, it sets these values to zero and converts the result back to a Date object.
The daysDiff method calculates the difference between two Date objects in days. To
do that, it starts by calling the stripTime method to remove the time-ofday component
from both Date objects. That's important when you're working with Date objects that
include times, because you don't want the time of day to be considered in the calculation.
Next, the daysDiff method uses the getTime method to convert the Date objects to
long values. Then, it subtracts these two values to get the difference, which is expressed
in milliseconds. To convert that value to days, it divides it by the number of milliseconds
in a day, which is represented by the constant named MILLS_IN_DAY that's defined at
the top of the class.
The code example at the bottom of this figure shows how you might use the DateUtils
class in a simple application. This example determines the number of days between the
current date and Christmas. The first two lines get the current date and then extract the
current year using the get method. Next, a Date object named currentDate is set to the
current date and another Date object named Christmas is set to December 25 of the
current year. Then, an int variable named daysToChristmas is calculated by calling the
daysDiff method. The rest of the code formats and displays the result.
Figure 13-5
416 Section 3 More Java essentials
public static Date createDate (int year, int month, int day) {
GregorianCa1endar date = new GregorianCa1endar (year, month, day) ; return date. getTime ( ) ;
public static int daysDiEf (Date datel, Date date2) datel = stripTime
(datel) ; date2 = BtripTime (date2) ; long longDate1 = datel .
getTime ( ) ; long longDate2 = date2 . getTime ( ) ; long longDiff =
longDate2 - longDate1; return (int) (longDiff / MILLS IN DAY) ;
Resulting output
Chapter 13 How to work with dates and strings 417
To show how you can use some of the date skills you just learned, figure 13-6 shows
how to add a date to the Invoice class that was presented in chapter
12. The constructor for this class sets the invoice date, which is declared as a Date object,
to the current date. To do that, it uses the getCurrentDate method of the DateUtils class so
that the invoice date doesn't include a time.
Two methods have also been added to this class to provide access to the invoice date.
The getInvoiceDate method simply returns the invoice date as a Date object. The
getFormattedDate method applies a short date format to the invoice date and returns it as
a string.
To make the date classes available to this class, the two import statements at the
beginning of the class have been changed. Now, instead of just importing the
NumberFormat class of the java.text package and the ArrayList class of the java.util
package, they import all of the classes in these packages. That way, the DateFormat class
is available from the java.text package, and the
GregorianCalendar, Calendar, and Date classes are available from the java.util package.
Figure 13-5
418 Section 3 More Java essentials
private
lineltems; private Date invoiceDate;
public Invoice ( )
lineltems = new ;
invoiceDate = DateUti1s.getCurrentDate
( ) ;
public getLineItems ( )
return lineltems ;
return invoiceTota1;
return invoiceDate;
Figure 13-7 shows three constructors of the String class. The first constructor
provides another way to create an empty string, and the second and third
constructors allow you to create a string from an array of char or byte types.
Although none of these constructors are commonly used, the second and third
constructors show that you can think of a string as an array of Unicode characters.
You may remember from chapter 3 that char is a primitive type that can hold a
Unicode character with two bytes used for each character. That provides for over
65,000 unique characters. Now, you'll learn that a String variable can store an array
of these Unicode characters.
The first two examples in this figure show how to create a string. In example 1,
the first statement uses the shorthand notation you learned how to use in chapter 2.
Then, the second statement shows how to do the same task using a constructor of the
String class. In example 2, the first statement initializes the new string from a string
literal, and the second statement initializes it from a variable.
The third example creates a string from an array of characters. Here, the second
statement converts the entire array of characters to a string named cityString1. Then,
the third statement converts the first three characters in the array to a string named
cityString2. Although there's little reason to create a string in this way, we included
this example to demonstrate that an array of characters can be converted to a string.
Note that literal char values must be enclosed in single quotes, not double quotes the
way string literals are.
The fourth example creates a string from an array of bytes. Here, the first
statement creates an array of bytes that represents the same characters as the
characters that are used in the third example. That's because every character in the
Figure 13-6
420 Section 3 More Java essentials
ASCII character set corresponds to a byte value. For example, the byte value of 68
represents the character D. Then, the second and third statements in this example
work just like they did in the previous example.
The string class
j ava . lang. String ;
Notes
For the third constructor shown above, the characters referred to by the intOffset and
intLength arguments must fall within the array. Otherwise, the constructor will throw
an IndexOutOfBoundsException.
A char data type contains a single Unicode character, which is stored in two bytes.
When you use the second and third constructors above, you can construct a String
object from an array of char types. To code a literal char value, you use single quotes
instead of double quotes as shown in the third example.
Because a byte data type can hold the Unicode value for every character in the ASCII
character set, you can also construct a String object from an array of bytes as shown in
the fourth example.
Chapter 13 How to work with dates and strings 421
Since String objects are immutable, they can't grow or shrink. Later in this chapter,
you'll learn how to work with StringBuilder objects that can grow and shrink.
In chapters 2 and 4, you learned how to use the equals and equalsIgnoreCase
methods of the String class to compare strings. Now, figure 13-8 reviews these
methods and introduces you to 17 more methods that you can use to work with
strings. In the next figure, you'll see some examples that use some of these
methods. You can also get more information about any of these methods by looking
up the String class in the documentation for the Java API.
As you can see, we divided the methods presented in this figure into two
categories. The first table lists methods that are used to manipulate the value of the
string in one way or another. The first five of these methods return int values. The
length method returns the total number of characters in the string. The indexOf and
lastlndexOf methods return a value that represents an index within the string. This
index value works as if the string was an array of characters. In other words, the
index value for the first character in a string is 0, the index value for the second
character is 1, and so on.
The next four methods return String objects. Here, the trim method returns the
string, but it removes any spaces from the beginning and end of the string. The
substring methods allow you to return part of a string by specifying index values.
The replace method replaces all occurrences of a specified character with another
character.
The split method returns an array of String objects. This method splits the string
up into individual strings based on the delimiter string you specify.
Actually, the delimiter string can be any regular expression, which is a complicated
expression that can contain wildcards and other special characters. If you want to
learn more about regular expressions, you can search the web for "java regular
expression." In most cases, however, the delimiter string will be a single character or
an escape sequence such as "\t" for tabs or "\n" for returns.
When using methods that require an index, you must be careful to supply a valid
index. If you supply an index argument that's negative or greater than the length of
the string minus one, the method will throw a StringIndexOutOfBoundsException.
The second table in this figure lists methods that are useful for comparing string
values. The first six of these methods return boolean values. You've already seen
the equals and equalsIgnoreCase methods, which compare strings and return a true
value if the strings are equal. The startsWith and endsWith methods check whether
Figure 13-6
422 Section 3 More Java essentials
a string starts or ends with a certain combination of characters and return a true
value if it does. And the isEmpty method checks whether the string is an empty
string and returns a true value if it is.
The last two methods are used to compare two strings to see which one is
greater according to the sort order of the strings. These methods return an int value
that's negative if the string is less than the specified string, zero if the strings are
equal, and positive if the string is greater than the specified string. These methods
are useful because you can't use normal comparison operators (such as < and >) with
String objects.
Methods for manipulating strings
length ( ) Returns an int value for the number of characters in this sting.
indexOf (String) Returns an int value for the index of the first occurrence of the specified string in this
string. If the string isn't found, this method returns -1.
indexOf (String, start Index) Returns an int value for the index of the first occurrence of the specified
string starting at the specified index. If the string isn't found,
this method returns -1.
lastlndexOf (String) Returns an int value for the index of the last occurrence of the specified string in this
string.
lastlndexOf (String , Returns an int value for the index of the last occurrence of start Index) the specified
string in this string starting at the specified index.
trim ( ) Returns a String object with any spaces removed from the beginning and end of this suing.
subs tring ( start Index) Returns a String object that starts at the specified index and goes to the end of the
string.
substring (start Index , Returns a String object that starts at the specified start index endlndex) and goes to,
but doesn't include, the end index.
replace (oldChar, newChar) Returns a String object that results from replacing all instances of the specified
old char value with the specified new char value.
split (delimiter) Returns an array of String objects that were separated in the original string by the specified
delimiter.
charAt ( index) Returns the char value at the specified index.
equals (String) Returns a boolean true value if the specified string is equal to the current string. This
comparison is case-sensitive.
equal B IgnoreCase ( String) Returns a boolean true value if the specified string is equal to the current string.
This comparison is not case-sensitive.
s tartswi th (String) Returns a boolean true value if this string starts with the specified string.
B tartBWi th (String , Returns a boolean true value if this string starts with the start Index) specified
string starting at the start index.
endsWi th ( String) Returns a boolean true value if the string ends with the specified
string.
i sEmpty ( ) Returns a Boolean true value if this string contains an empty string. This method was introduced
with Java 1.6.
compareTo (String) Returns an int that's less than zero if the string is less than the specified string, greater
than zero if the string is greater than the specified string, and
zero if the strings are equal.
compareToIgnoreCase ( String) The same as compareTo, but the case of the strings is ignored.
Methods of the String class
Figure 13-9 shows some examples of how you can use the methods of the String
class. The first example shows how to parse the first name from a string that
contains a full name. Here, the first statement sets the string to a string literal that
includes a first and last name, and the second statement uses the trim method to
remove any spaces from the beginning or end of the string. Then, the third statement
uses the indexOf method to get the index of the first space in the string, which is the
space between the first and last names. Finally, the last statement uses the substring
method to set the first name variable equal to the string that begins at the first
character of the string and ends at the first space character in the string.
The second example shows how to parse a string that contains an address into
the components of the address. In this case, tab characters separate each component
of the address. Here, the second statement uses the trim method to remove any
spaces that may have been included at the beginning or end of the string. Next, the
split method is used to separate the string into its individual components. Then,
simple assignment statements are used to assign the components to individual
strings. Note that this code doesn't account for an improperly formatted address
string. In an actual application, you'd want to at least check the length of the
addressParts array to make sure the string was successfully parsed into four
components.
The third example shows how to add dashes to a phone number. To do that, this
example creates a second string. Then, it uses the substring method to parse the first
string and add the dashes at the appropriate locations in the string. In figure 13-11,
you'll learn an easier way to accomplish this task.
Figure 13-6
424 Section 3 More Java essentials
The fourth example shows how to remove the dashes from a phone number. To
do that, this example creates a second string. Then, it uses a for loop to cycle
through each character in the first string. The only statement within this loop uses
the charAt method to add all characters in the first string that are not equal to a dash
to the second string. As a result, the second string won't contain any dashes. You'll
learn another way to accomplish this task in figure 13-11.
The fifth example shows how to compare two strings to determine which one
comes first based on the string's sort order. Here, two strings are created. Then, the
compareToIgnoreCase method of the first string is used to compare the strings. If the
result is less than zero, a message is printed indicating that the first string comes first
in sequence. If the result is zero, the message indicates that the strings are equal.
And if the result is greater than zero, the message indicates that the second string
comes first.
The sixth example shows how to use the isEmpty method that was introduced
with Java 1.6 to check if a string contains an empty string. Here, the first statement
creates a string variable named customerNumber that contains an empty string.
Then, two commented out if statements show two ways that were commonly used to
check for empty strings prior to Java 1.6. Although these statements will still work,
the isEmtpy method that's used in the third if statement requires less typing and is
easier to read.
Chapter How to work with dates and strings
425
13
capaci ty ( ) Returns an int value for the capacity of this StringBuilder object.
length ( ) Returns an int value for the number of characters in this StringBuilder object.
setLength ( intNumOf Chars ) Sets the length of this StringBuilder object to the specified number of
characters.
append (value ) Adds the specified value to the end of the string.
insert ( index, value) Inserts the specified value at the specified index pushing the rest of the string back.
replace ( start Index , Replaces the characters from the start index to, but not including, the endlndex, String)
end index with the specified string.
delete ( start Index, Removes the substring from the start index to, but not including, the endlndex) end index.
deleteCharAt ( index) Removes the character at the specified index.
setCharAt ( index, Replaces the character at the specified index with the specified character) character.
charAt ( index) Returns a char value for the character at the specified index.
substring ( index) Returns a String object that contains the characters starting at the specified index to the end
of the string.
substring ( start Index , Returns a String object that contains the characters from the start endlndex) index to,
but not including, the end index.
toString ( ) Returns a String object that contains the string that's stored in the
StringBuilder object.
Description
• StringBuilder objects are mutable, which means you can modify the characters in the
string. The capacity of a StringBuilder object is automatically increased if necessary.
• The append and insert methods accept primitive types, objects, and arrays of characters.
The StringBuilder class was introduced with Java 1.5. It's designed to replace the
older StringBuffer class, which has identical constructors and methods but isn't as
efficient.
Figure 13-11 presents some examples that show how you can use the
constructors and methods of the StringBuilder class. In particular, this figure shows
how to add characters to the end of a string, insert characters into the middle of a
string, and delete characters from a string.
The first example shows how to use the append method of the StringBuilder
class. Here, the first statement creates an empty StringBuilder object with the default
capacity of 16 characters. Then, the next three statements use the append method to
Chapter How to work with dates and strings
429
add 10 characters to the end of the string. As a result, the length of the string is 10
and the capacity of the StringBuilder object is 16. (You can do the same thing by
using simple string concatenation, but Java must create a new String object for each
statement since the length of a String object can't be increased. In contrast, when you
use the append method of the StringBuilder class, a new StringBuilder object isn't
created because the length of a StringBuilder object can be increased.)
The second example adds dashes to the string that was created in the first
example. Here, the first statement uses the insert method to insert a dash after the
first three characters. This pushes the remaining numbers back one index. Then, the
second statement uses the insert method to insert a dash after the seventh character in
the string, which was the sixth character in the original string. This pushes the
remaining four numbers in the string back one index.
The third example shows how to remove dashes from a phone number. Here, a
loop cycles through each character, using the charAt method to check if the current
character is a dash. If so, the deleteCharAt method deletes it. Since this causes all
characters to the right of the dash to move forward one index, it's necessary to
decrement the counter so the loop doesn't skip any characters.
The fourth example shows how to use the substring method of the
StringBuilder class to separate the area code, prefix, and suffix components of a
phone number. Here, the first statement uses a constructor to create a
StringBuilder object from a String literal. Then, the next three statements use the
substring method to create three String objects from the StringBuilder object. For
example, the second statement specifies a substring that goes from the first
character up to, but not including, the fourth character. (Note that the substring
method works the same for the String class as it does for the
StringBuilder class, so the same thing could be done with a simple string.)
The fifth example shows how a StringBuilder object automatically increases its
capacity as the length of the string increases. Here, the first statement creates an
empty StringBuilder object with a capacity of 8 characters, and the second statement
uses the capacity method to check the capacity. Next, the third statement appends a
string of 17 characters to the empty string. Since this causes the capacity of the
StringBuilder object to be exceeded, Java automatically increases the capacity. As a
result, the capacity of the name string is increased from 8 to 18 characters. Then, the
last two statements check the length and capacity of the modified StringBuilder
object.
13
Figure 13-1 1 Code examples that work with the StringBuilder class
Chapter How to work with dates and strings
431
Perspective
Now that you've finished this chapter, you should be able to use the classes
provided by the Java API to work with dates, and you should be able to use the
String and StringBuilder classes to work with strings. These are skills that you will
use often as you develop Java applications.
Summary
You can use the GregorianCalendar, Calendar, Date, and DateFormat classes to create,
manipulate, and format dates and times.
You can use methods of the String class to locate a string within another string,
return parts of a string, and compare all or part of a string. However, String objects are
immutable, so you can't add, delete, or modify individual characters in a string.
StringBuilder objects are mutable, so you can use the StringBuilder methods to add,
delete, or modify characters in a StringBuilder object. Whenever necessary, Java
automatically increases the capacity of a StringBuilder object.
1. Open the project named ch13_ex3_NameParser that's in the ex_starts directory. Then,
review the code in the NameParserApp class.
2. Add code that separates the name into two or three strings depending on whether the
user entered a name with two words or three.
3. Display each word of the name on a separate line. If the user enters fewer than two
words or more than three words, display an error message. Also, make sure the
application works even if the user enters one or more spaces before or after the name.
Chapter How to work with dates and strings
433
4. Test the project to make sure it works correctly.