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