import java.util.*; // for GregorianCalendar and Date
import java.text.*; // for DateFormat
/**
* A library book. In this simple model of a book, a book has a title and
* an author, a due date, and a borrower.
*
* @author Jim Glenn
* @version 0.1 9/26/2003
*/
public class LibraryBook
{
// declarations of the fields
/**
* The title of this book.
*/
private String title;
/**
* The author of this book.
*/
private String author;
/**
* The name of the person who has borrowed this book, or null
* if this book is not checked out.
*/
private String borrower;
/**
* The date this book is due, or null if this book is not
* checked out.
*/
private GregorianCalendar dueDate;
// Definition of the constructor
/**
* Creates a new book with the given title and author. The book will
* not be checked out, so there is no borrower and date due.
*
* @param t the title of the book
* @param a the author of the book
*/
public LibraryBook(String t, String a)
{
title = t;
author = a;
borrower = null; // not really needed; object fields default to null
dueDate = null;
}
// Definitions of the methods
/**
* Returns the title of this book.
*
* @return the title of this book.
*/
public String getTitle()
{
return title;
}
/**
* Returns the author of this book.
*
* @return the author of this book.
*/
public String getAuthor()
{
return author;
}
/**
* Returns the borrower of this book. If this book is not checked out,
* returns null.
*
* @return the name of the borrower of this book
*/
public String getBorrower()
{
return borrower;
}
/**
* Returns the date this book is due. If this book is not checked out,
* returns null.
*
* @return the date this book is due
*/
public GregorianCalendar getDueDate()
{
return dueDate;
}
/**
* Checks this book out to the given borrower and records the given due
* date.
*
* @param n the name of the person borrowing this book
* @param due the date this book is due
*/
public void checkout(String n, GregorianCalendar due)
{
borrower = n;
dueDate = (GregorianCalendar)(due.clone());
}
/**
* Returns this book.
*/
public void checkin()
{
borrower = null;
dueDate = null;
}
/**
* Renews this book for the given time.
*
* @param days the number of days by which to extend the due date of this
* book
*/
public void renew(int days)
{
dueDate.add(GregorianCalendar.DAY_OF_MONTH, days);
}
/**
* Determines the number of days until this book is due. The return
* value will be negative if this book is overdue.
*
* @return the number of days until this book is due
* @throws NullPointerException if this book is not checked out
*/
public int getDaysUntilDue()
{
// get today's date, as milliseconds since 1/1/1970
Date today = new Date();
// convert the due date to milliseconds since 1/1/1970
Date due = dueDate.getTime();
// compute difference between dates (in milliseconds)
long diff = due.getTime() - today.getTime();
// convert from milliseconds to days
diff = diff / 1000 / 60 / 60 / 24;
// report that result
return (int)diff;
}
/**
* Calculates the overdue fine for this book. If this book is not overdue,
* returns zero.
*
* @param rate the daily fine
* @return the total fine for this book
* @throws NullPointerException if this book is not checked out
*/
public double calculateOverdueFine(double rate)
{
return -Math.min(0, getDaysUntilDue()) * rate;
}
}
import java.util.*;
/**
* Test driver for the LibraryBook class.
*
* @author Jim Glenn
* @version 0.1 9/26/2003
*/
public class BookTest
{
public static void main(String[] args)
{
LibraryBook one = new LibraryBook("A Lost Lady", "Willa Cather");
LibraryBook two = new LibraryBook("Hyperion", "Dan Simmons");
System.out.println("Book 1's title: " + one.getTitle());
System.out.println("Book 2's title: " + two.getTitle());
// no borrower -- prints null
System.out.println("Book 1 checked out by: " + one.getBorrower());
GregorianCalendar past = new GregorianCalendar(2003, Calendar.MAY, 1);
one.checkout("Crawford Hightower", past);
two.checkout("Bryant Stith", past);
System.out.println("Book 1 checked out by: " + one.getBorrower());
GregorianCalendar due = one.getDueDate();
System.out.println("Book 1 due on: " + due.get(Calendar.DAY_OF_MONTH));
System.out.println("Book 1 due in: " + one.getDaysUntilDue());
System.out.println("Book 1 fine: " + one.calculateOverdueFine(0.25));
one.renew(365);
due = one.getDueDate(); // due is not automatically updated
System.out.println("Book 1 due in year: " + due.get(Calendar.YEAR));
System.out.println("Book 1 due in: " + one.getDaysUntilDue());
System.out.println("Book 1 fine: " + one.calculateOverdueFine(0.25));
// without the .clone() in checkout we'd get unexpected results here!
System.out.println("Book 2 due in: " + two.getDaysUntilDue());
System.out.println("Book 2 fine: " + two.calculateOverdueFine(0.25));
two.checkin();
System.out.println("Book 2 checked out by: " + two.getBorrower());
}
}
The test driver outputs
Book 1's title: A Lost Lady Book 2's title: Hyperion Book 2 checked out by: null Book 2 checked out by: Crawford Hightower Book 1 due on: 1 Book 1 due in: -148 Book 1 fine: 37.0 Book 1 due in year: 2004 Book 1 due in: 216 Book 1 fine: 0.0 Book 2 due in: -148 Book 2 fine: 37.0 Book 2 checked out by: null
This code can also be downloaded from the files LibraryBook.java and BookTest.java.