Thursday, 13th October 2011
Follow WikiJava on twitter now. @Wikijava

Parsing complex command line parameters

From WikiJava

Jump to: navigation, search
The author suggests:

buy this book

This article shows an example of how to parse the command line parameters in a Java application. This is generally a quite important part of any non interactive software, that you run from a command line or a script. The example below is taken from the PrintDate Wikijava Project. See the Projects Page for info about the projects.

Contents

The command line parameters

Every Java program can get the command line parameters using the args array, defined in the main method:

public static void main(String[] args)

The args contains the list of parameters given in the command line. This is just a predefined behavior, whenever you will run a java class, by default the Java Virtual Machine (JVM) will search the main method in it, defined as above. The JVM will populate all the command line parameters in the args array, so it will contain all it is needed for running the program.

For example if the program is called with no parameters then args will be an empty array. If you call the program by typing:

java -jar PrintDate.jar -f yy.MM.dd -t UK

The JVM will call the main method and populate the args array with:

args[0] = -f 
args[1] = yy.MM.dd 
args[2] = -t 
args[3] = UK

Note that the first element of the array has index 0 and the array starts with the first command line parameter. This is a bit different from some other languages, for example in C the first parameter is the name of the program.

How to use the command line parameters

In general for simple programs where you don't allow users to have a choice of which parameters to specify, they must always be specified and in the right format you can just write something similar to:

	if (args.length < 6) {
	    System.err
		    .println("usage: java -jar TimeMilliseconds "
			    + "[year] [month] [day] [hour] "
			    + "[minute] [second]");
	    return;
	}
 
	final int year = Integer.parseInt(args[0]);
	final int month = Integer.parseInt(args[1]);
	final int day = Integer.parseInt(args[2]);
	final int hourOfDay = Integer.parseInt(args[3]);
	final int minute = Integer.parseInt(args[4]);
	final int second = Integer.parseInt(args[5]);

This is of course not very elastic, and not useful in most occasions. I will describe below a much more flexible approach.

The idea is to use options in the command line format, so that the user can decide which options to specify, in which order, and he can even omit some.

All the trick is made via a simple if - else if - else structure. Shown in the for loop below:


String format = "d MMM yyyy hh:mm aaa";
	String localeName = "UK";
 
	for (int i = 0; i < args.length; i++) {
	    if (args[i].equals("-h")) {
		System.out.println(helpString);
		return;
	    } else if (args[i].equals("-f")) {
		format = args[++i];
	    } else if (args[i].equals("-l")) {
		localeName = args[++i];
	    }
 
	}

Note that this trick supports default values (format and localeName) are initialized at first, if the command line does not override them, the initial values are kept.

After the for loop the variables are all initialized and the program is ready to go.

You could even add the behavior for the required options, basically adding an if statement to check if any of the required variables were not initialized.

for example:

	String format = null;
	String localeName = "UK";
 
	for (int i = 0; i < args.length; i++) {
	    if (args[i].equals("-h")) {
		System.out.println(helpString);
		return;
	    } else if (args[i].equals("-f")) {
		format = args[++i];
	    } else if (args[i].equals("-l")) {
		localeName = args[++i];
	    }
 
	}
 
	if (null == format){
	    System.err.println("The required -f parameter is missing");
	    System.out.println(helpString);
	    return;
	}

The complete code

/**
 * 
 */
package org.wikijava.time;
 
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
 
/**
 * Prints the current date in various formats
 * 
 * @author GiulioG
 */
public class PrintDate {
 
    private static final String helpString = "usage: java -jar PrintDate.jar\n"
	    + "for default 'd MMM yyyy hh:mm aaa' date format in Locale = UK\n"
	    + "\n"
	    + "or: java -jar PrintDate.jar <-h>\n "
	    + "for this help\n"
	    + "\n"
	    + "or: java -jar PrintDate.jar <-f [format]> <-l [locale]>\n"
	    + "for specifying your settings.\n"
	    + "\n"
	    + "Allowed formats are the same as in "
	    + "java.text.SimpleDateFormat\n"
	    + "\n"
	    + "Letter 	Date or Time Component 	Presentation 	Examples\n"
	    + "G 	Era designator 	Text 	AD\n"
	    + "y 	Year 	Year 	1996; 96\n"
	    + "M 	Month in year 	Month 	July; Jul; 07\n"
	    + "w 	Week in year 	Number 	27\n"
	    + "W 	Week in month 	Number 	2\n"
	    + "D 	Day in year 	Number 	189\n"
	    + "d 	Day in month 	Number 	10\n"
	    + "F 	Day of week in month 	Number 	2\n"
	    + "E 	Day in week 	Text 	Tuesday; Tue\n"
	    + "a 	Am/pm marker 	Text 	PM\n"
	    + "H 	Hour in day (0-23) 	Number 	0\n"
	    + "k 	Hour in day (1-24) 	Number 	24\n"
	    + "K 	Hour in am/pm (0-11) 	Number 	0\n"
	    + "h 	Hour in am/pm (1-12) 	Number 	12\n"
	    + "m 	Minute in hour 	Number 	30\n"
	    + "s 	Second in minute 	Number 	55\n"
	    + "S 	Millisecond 	Number 	978\n"
	    + "z 	Time zone 	General time zone 	"
	    + "Pacific Standard Time; PST; GMT-08:00\n"
	    + "Z 	Time zone 	RFC 822 time zone 	"
	    + "-0800\n"
	    + "\n"
	    + "\n"
	    + "Allowed locales are Format are the same defined "
	    + "in java.util.Locale: \n"
	    + "[\"ENGLISH\", \"FRENCH\", \"GERMAN\", \"ITALIAN\", "
	    + "\"JAPANESE\",  \n"
	    + "\"KOREAN\", \"CHINESE\", \"FRANCE\",  \n"
	    + "\"GERMANY\", \"ITALY\", \"JAPAN\", \"KOREA\",  \n"
	    + "\"UK\", \"US\", \"CANADA\", \"CANADA_FRENCH\",  \n"
	    + "\"ROOT\"]\n";
 
    /**
     * 
     * 
     * 
     * @param the
     *            input params
     */
    public static void main(String[] args) {
	String format = "d MMM yyyy hh:mm aaa";
	String localeName = "UK";
 
	for (int i = 0; i < args.length; i++) {
	    if (args[i].equals("-h")) {
		System.out.println(helpString);
		return;
	    } else if (args[i].equals("-f")) {
		format = args[++i];
	    } else if (args[i].equals("-l")) {
		localeName = args[++i];
	    }
 
	}
 
	Locale[] availableLocales = Locale
		.getAvailableLocales();
 
	Locale locale = Locale.UK;
	for (int l = 0; l < availableLocales.length; l++) {
	    if (availableLocales[l].getClass().getName()
		    .equals(localeName)) {
		locale = availableLocales[l];
	    }
	}
 
	SimpleDateFormat simpleDateFormat = new SimpleDateFormat(
		format, locale);
 
	String dateToPrint = simpleDateFormat
		.format(new Date());
	System.out.println(dateToPrint);
 
    }
 
}


Comments from the users

To be notified via mail on the updates of this discussion you can login and click on watch at the top of the page


Comments on wikijava are disabled now, cause excessive spam.