Further Object-Oriented Programming Lecture 21

Formatting Numbers and Dates

Prof. Dr. Igor Trajkovski Faculty of Computer Science and IT New York University Skopje [email protected]

1

Introduction Last lecture we: • considered how to search a string – for an exact match – for a match to a pattern – to split the string at a given delimiter

• introduced regular expressions • looked at classes in the java.util.regex package

Today we will: • look at how to represent and format numbers, percentages, currencies and dates

2

Outputting numbers imagine a program that prints out a table of unit costs the print statement in the loop is System.out.println(units + "

" + totalCost + " £" + totalCost / units );

Units

Cost

Cost per unit

34

54.46

£1.601764705882353

68

97.67

£1.4363235294117647

102

140.88

£1.3811764705882352

136

184.09

£1.3536029411764705

170

227.3

£1.3370588235294119

problems – alignment, rounding 3

Solution – use printf for formatted output System.out.printf("%5d%8.2f Units

Cost

£%5.2f\n", units, totalCost, totalCost / units );

Cost per unit

34

54.46

£ 1.60

68

97.67

£ 1.44

102

140.88

£ 1.38

136

184.09

£ 1.35

170

227.30

£ 1.34

printf has the signature public PrintStream printf(String format, Object... args)

the String can include text and format specifiers this is followed by the list of variables to be formatted 4

Format specifiers format specifiers have the syntax •

[] means optional

%[argument_index$][flags][width][.precision]conversion the argument index specifies the position of the argument to be formatted •

1$ first, 2$ second



by default the arguments in the argument list are formatted in order

System.out.printf("%3$5d%2$8.2f £%1$5.2f\n", totalCost / units, totalCost, units );

the flags can specify -

left-justified

+ use + or – signs 0 pad with leading zeros ( enclose negative numbers in parentheses

5

Format specifiers (cont) format specifiers have the syntax %[argument_index$][flags][width][.precision]conversion the width is the minimum number of characters •

includes the decimal place and digits to the right and left of it



useful for tables



more spaces will be used if needed

precision, when formatting floating point numbers, is the number of digits after the decimal point there are many conversion characters for different data types and formats •

b boolean, c char, d integer, f floating point, s string



o octal, h hexadecimal, e scientific notation

System.out.printf("%1$10.3f%1$10.3e%1$10.3g\n", 42.36453); 42.365 4.236e+01

42.4

see the documentation of java.util.Formatter for details 6

SCJP Example

Which will compile and run without exception? (Choose all that apply.) A. B. C. D. E. F. G.

System.out.printf("%b", 123); System.out.printf("%c", "x"); System.out.printf("%d", 123); System.out.printf("%f", 123); System.out.printf("%d", 123.45); System.out.printf("%f", 123.45); System.out.printf("%s", new Long("123"));

7

PrintWriter methods printf is a method of the PrintWriter class • System.out is a PrintWriter object • can also use printf when writing to files

PrintWriter another method, format, which works the same as printf • printf is familiar to C programmers

printf and format use Java.util.Formatter to do the formatting each method is overloaded to also take the Locale as the first parameter public PrintStream format(Locale l, String format, Object... args) uses correct format for a given location • more next lecture 8

NumberFormat the java.text.NumberFormat class can be used to format numbers, currencies and percentages it is an abstract class use its static factory methods to get an object of the appropriate subclass •

NumberFormat.getInstance() or NumberFormat.getNumberInstance()



NumberFormat.getIntegerInstance()



NumberFormat.getCurrencyInstance()



NumberFormat.getPercentInstance()

by default, the format of the current Locale is used this can be changed using set- methods the format() method can then be used to format numbers •

returns a String

useful if the same format needs to be applied to several numbers

9

NumberFormat Example NumberFormat nf=NumberFormat.getInstance(); System.out.println(nf.format(5000.555)); nf=NumberFormat.getCurrencyInstance(); System.out.println(nf.format(5000.555)); nf=NumberFormat.getInstance(Locale.FRANCE); System.out.println(nf.format(5000.555)); nf=NumberFormat.getCurrencyInstance(Locale.FRANCE); System.out.println(nf.format(5000.555));

Output: 5,000.555 £5,000.56 5 000,555 5 000,56 € 10

NumberFormat Example NumberFormat f1 = NumberFormat.getInstance(); System.out.println(f1.format(12345.6789)); f1.setMaximumFractionDigits(1); f1.setRoundingMode(RoundingMode.UP); f1.setGroupingUsed(false); System.out.println(f1.format(12345.6789));

Output: 12,345.679 12345.7

11

Percentage and Currency NumberFormat cf1 = NumberFormat.getCurrencyInstance(); System.out.println(cf1.format(12345.6789)); NumberFormat pf1 = NumberFormat.getPercentInstance(); System.out.println(pf1.format(0.6789));

Output: £12,345.68 68% notice than British currency and format is used by default will see how to use different Locales next lecture

12

Custom Number Format patterns you can also create custom NumberFormat objects by specifying the pattern to use in the constructor DecimalFormat df = new DecimalFormat("$###,###.#"); System.out.println(df.format(12345.6789)); DecimalFormat df1 = new DecimalFormat("0000000.0000000"); System.out.println(df1.format(12345.6789));

Output: $12,345.7 0012345.6789000 # is a placeholder for a digit using 0 instead specifies leading or trailing zeros 13

Dates java.util.Date represents an instance in time with millisecond precision the default constructor constructs a Date object representing now Date date = new Date(); the toString method returns a formatted String representing the date and time to the nearest second System.out.println(date.toString()); Sun Dec 02 23:33:32 GMT 2007

14

Dates any date can be constructed using the constructor public Date(long millis)

which takes the number of milliseconds since 1 January 1970 Date date1 = new Date(1000000000L);

Mon Jan 12 14:46:40 GMT 1970 a long value is used – should cope with any date you need Date date2 = new Date(Long.MAX_VALUE);

Maximum long value 9223372036854775807 is Sun Aug 17 07:12:55 GMT 292278994 Date date3 = new Date(-1000000000L); Sat Dec 20 11:13:20 GMT 1969

15

Manipulating dates most of the methods of the Date class are deprecated •

not recommended for use any more



may not be supported in future versions of Java



aren’t suited to internationalisation

use the Calendar class instead to manipulate dates Date d1 = new Date();

// todays date

System.out.println("Now it is " + d1); Calendar c1 = Calendar.getInstance(); c1.setTime(d1); c1.add(Calendar.MONTH, 6);

// add 6 months

Date d2 = c1.getTime(); System.out.println("In 6 months it will be " + d2); Now it is Sun Dec 02 23:56:03 GMT 2007 In 6 months it will be Mon Jun 02 23:56:03 BST 2008 16

Using Calendar to manipulate dates create a Date object to represent the desired date Calendar is abstract and does not have a constructor use the static Calendar factory method which returns instance of a subclass, such as GregorianCalendar set the time of the Calendar object using the Date object use Calendar methods to manipulate the date use the getTime method of Calendar to get a Date object representing the new time • the original Date object is unchanged

call its toString method and print out 17

Useful methods of the Calendar class public void add(int field, int amount) • field could be Calendar.YEAR, Calendar.MONTH, Calendar.DAY, Calendar.HOUR, Calendar.MINUTE, Calendar.SECOND, Calendar.MILLISECOND • amount can be positive or negative (go back in time)

public int get(int field) • field could be Calendar.DAY_OF_WEEK or DAY_OF_YEAR etc. as well as those above

lots of get and set methods public boolean after(Object when) • does this date come after the specified date? • there’s also a before method 18

Calendar and Gregorian calendar java.util.Calendar #Calendar()

Constructs a default calendar.

+get(field: int): int

Returns the value of the given calendar field.

+set(field: int, value: int): void

Sets the given calendar to the specified value.

+set(year: int, month: int, dayOfMonth: int): void

Sets the calendar with the specified year, month, and date. The month parameter is 0-based, that is, 0 is for January.

+getActualMaximum(field: int): int

Returns the maximum value that the specified calendar field could have.

+add(field: int, amount: int): void

Adds or subtracts the specified amount of time to the given calendar field.

+getTime(): java.util.Date

Returns a Date object representing this calendar’s time value (million second offset from the Unix epoch).

+setTime(date: java.util.Date): void Sets this calendar’s time with the given Date object. java.util.GregorianCalendar +GregorianCalendar()

Constructs a GregorianCalendar for the current time.

+GregorianCalendar(year: int, month: int, dayOfMonth: int)

Constructs a GregorianCalendar for the specified year, month, and day of month.

+GregorianCalendar(year: int, Constructs a GregorianCalendar for the specified year, month, day of month: int, dayOfMonth: int, month, hour, minute, and second. The month parameter is 0-based, that hour:int, minute: int, second: int) is, 0 is for January. 19

Formatting dates the Date toString() method returns a String in a fixed format Sun Dec 02 23:56:03 GMT 2007 can’t change to suit Locale, or show only some of the information •

may only want the time, or only the date

could use the get() method of Calendar with different fields •

but this returns an integer that need to be interpreted and formatted

instead, use a subclass of the DateFormat class in package java.text this has methods to return a formatted String in several different styles SHORT, MEDIUM, LONG, FULL can format the date, the time, or both

20

java.text.DateFormat +format(date: Date): String +getDateInstance(): DateFormat +getDateInstance(dateStyle: int): DateFormat +getDateInstance(dateStyle: int, aLocale: Locale): DateFormat +getDateTimeInstance(): DateFormat +getDateTimeInstance(dateStyle: int, timeStyle: int): DateFormat +getDateTimeInstance(dateStyle: int, timeStyle: int, aLocale: Locale): DateFormat +getInstance(): DateFormat

21

Formatting Date information Date d = new Date(); DateFormat form = DateFormat.getDateInstance(DateFormat.MEDIUM); System.out.println(form.format(d)); Output: 02-Dec-2007

Date

Time

SHORT

02/12/07

23.56

MEDIUM

02-Dec-2007

23.56.03

LONG

02 December 2007

23.56.03 GMT

FULL

02 December 2007

23.56.03 o'clock GMT 22

SimpleDateFormat you can define your own pattern of date formatting using java.text.SimpleDateFormat Date d = new Date(); SimpleDateFormat form = new SimpleDateFormat("'Today is' EE', the 'd MMMM yyyy"); System.out.println(form.format(d));

Today is Sun, the 2 December 2007 SimpleDateFormat form1 = new SimpleDateFormat("'Today is' EEEE dd MM yy");

Today is Sunday 02 12 07

23

SimpleDateFormat symbols y year M month d h hour (am/pm) H hour (24-hour clock) m minute s second S millisecond E day in week a am/pm z time zone the format is specified by the number of times the symbol is repeated •

1 abbreviated 4 full form

24

Summary Today we have: • looked at how to represent and format numbers, percentages, currencies and dates Further reading: Liang Chapter 31.3.2, 31.4 Sun Java tutorials: •

Learning the Java Language – Numbers and Strings: Formatting Numeric Print output



Internationalization: Formatting

Next lecture: •

Internationalization – how to format numbers, currencies, percentages and dates appropriately for different locations – how to use locale-specific resources

25