How to Format and Display Number to Currency in Java – Example Tutorial

Displaying financial amount in respective currency is common requirement in Java based E-commerce applications. For example if you are selling products on-line globally, you will show price of product in their local currency rather than USD or some other currency. Storing price in every currency is not a good option because of maintenance, and more realistically fluctuation in exchange rates. That’s why many of these application prefer stores price of books, electronic goods or whatever product they are selling in USD, and responsibility of converting that price to local currency and displaying is left to client side code. If your client is Java based client e.g. Swing GUI , Java FX client, or a JSP web page, you can use java.text.NumberFormat class to format currency in Java. NumberFormat class allows you to display price in multiple currencydepending upon Locale supported by your Java version. All you need to do is to get correct Currency Instance based upon Locale, for example to display amount in US dollar, call NumberFormat.getCurrencyInstance() method with Locale as Locale.US, similarly to display currency as UK pound sterling, pass Locale.UK and for displaying money in Japanese Yen, pass Locale.JAPAN. Once you get the correct instance of currencyformatter, all you need to do is call their format() method by passing your number. We will see an example of converting one currency to other and displaying amount in multiple currency in Java. It’s actually very much similar to formatting date in Java, so if you are familiar to that part, it would be easy to format currency as well.

How to format  Currency in Java

how to format Currency in Java NumbeFormat Example

Here is our sample program to format a number e.g. double or int to Currency in Java e.g. USD or GBP with dollar and pound sign. When we say formatting currency or formatting number as currency, what we mean is to show respective currency sign in front of price/amount. For example to display prince in USD, you will show something like $100.25. Similarly to show same price to UK customer in Pound, you will show £60.15 and if you are doing business in Asia, and have  Japanese customers, you will show prince in their local currency as well e.g. Japanese Yen, like ¥10,279. Did you notice currency sign in front of amount or price? This is what makes that number and amount rather than just a number. Java also put comma, just like the way write a bigger amount. This type of Locale specific issue becomes really tricky if you are doing this by hard-coding. Suppose you started your business with USD, and then start selling your product on England, if you keep storing price in database in multiple currency you will face hell lot of issue. Instead of that, just keep price in one currency in database, get the latest FX rate and covert price in real time for display. Java API has rich support for formatting currency by java.text.NumberFormat class, and good knowledge of it will save lot of your time, so do invest some time on this class. Also this program is compiled using JDK 1.7, did you notice use of String in Switch case, though I am not a big fan of it in production code, it works perfectly in short tutorials.

import java.text.NumberFormat;
import java.util.Locale;

/**
 * How to format Number to different currency in Java. Following Java program
 * will show you, how you can display double value in different currency e.g.
 * USD, GBP and JPY. This example show price in multiple currency.
 * 
* @author
 */
public class Test {

    public static void main(String args[]) {
        double price = 100.25;

        showPriceInUSD(price, getExchangeRate("USD"));
        showPriceInGBP(price, getExchangeRate("GBP"));
        showPriceInJPY(price, getExchangeRate("JPY"));

    }

    /**
     * Display price in US Dollar currency
     *
     * @param price
     * @param rate
     */
    public static void showPriceInUSD(double price, double rate) {
        double priceInUSD = price * rate;
        NumberFormat currencyFormat = NumberFormat.getCurrencyInstance(Locale.US);
        System.out.printf("Price in USD : %s %n", currencyFormat.format(priceInUSD));

    }

    /**
     * Display prince in British Pound
     *
     * @param price
     * @param rate
     */
    public static void showPriceInGBP(double price, double rate) {
        double princeInGBP = price * rate;
        NumberFormat GBP = NumberFormat.getCurrencyInstance(Locale.UK);
        System.out.printf("Price in GBP : %s %n", GBP.format(princeInGBP));
    }

    /**
     * Display prince in Japanese Yen
     *
     * @param price
     * @param rate
     */
    public static void showPriceInJPY(double price, double rate) {
        double princeInJPY = price * rate;
        NumberFormat currency = NumberFormat.getCurrencyInstance(Locale.JAPAN);
        System.out.printf("Price in JPY : %s %n", currency.format(princeInJPY));
    }

    /**
     * @return FX exchange rate for USD
     * @param currency
     */
    public static double getExchangeRate(String currency) {
        switch (currency) {
            case "USD":
                return 1;
            case "JPY":
                return 102.53;
            case "GBP":
                return 0.60;
            case "EURO":
                return 0.73;
            default:
                throw new IllegalArgumentException(String.format("No rates available for currency %s %n", currency));
        }
    }

}


Output
Price in USD : $100.25 
Price in GBP : £60.15

Price in JPY : ¥10,279

That’s all about how to display currency in Java, or how to format a number like integer or double to currency in Java. Remember, NumberFormat class is on java.text package and not on java.util package. I have instance when people searching for this class, thinking that by importing java.util.* they should get NumberFormat class as well. Let me know if you face any issue while formatting currency or displaying amount in multiple currency to Java clients e.g. Swing, Java FX or JSP pages.

Read more: http://javarevisited.blogspot.com/2014/02/how-to-format-and-display-number-to.html#ixzz3vgIPk13U

By Rz Rasel Posted in Java

How to generate random locations nearby my location?

I am trying to create random locations nearby my location. What i want is to create random latitude/longitude pairs inside a 200 meters circle surrounding my location.

This is the formula i came up with (with the help of people at StackOverFlow): (Random number between -1 and 1)*radius + (old longitude) = new longitude within radius of old longitude

(Random number between -1 and 1)*radius + (old latitude) = new latitude within radius of old latitude

The thing is that something weird is happening with my implementation because all the random locations are too near of my location center, it seems that the formula does not cover the whole radius.

Any idea of what could be wrong with my formula?

Edited to show the current java implementation:

public static Location getLocation(Location location, int radius) {
    Random random = new Random();

    // Convert radius from meters to degrees
    double radiusInDegrees = radius / METERS_IN_DEGREES;

    double x0 = location.getLongitude() * 1E6;
    double y0 = location.getLatitude() * 1E6;
    double u = random.nextInt(1001) / 1000;
    double v = random.nextInt(1001) / 1000;
    double w = radiusInDegrees * Math.sqrt(u);
    double t = 2 * Math.PI * v;
    double x = w * Math.cos(t);
    double y = w * Math.sin(t);

    // Adjust the x-coordinate for the shrinking of the east-west distances
    double new_x = x / Math.cos(y0);

    // Set the adjusted location
    Location newLocation = new Location("Loc in radius");
    newLocation.setLongitude(new_x + x0);
    newLocation.setLatitude(y + y0);

    return newLocation;
}

I am not sure what i am doing wrong, because the new locations are created in the middle of the sea 🙂

Any idea? thank you

 

Answer:—

The correct implementation is:

public static void getLocation(double x0, double y0, int radius) {
    Random random = new Random();

    // Convert radius from meters to degrees
    double radiusInDegrees = radius / 111000f;

    double u = random.nextDouble();
    double v = random.nextDouble();
    double w = radiusInDegrees * Math.sqrt(u);
    double t = 2 * Math.PI * v;
    double x = w * Math.cos(t);
    double y = w * Math.sin(t);

    // Adjust the x-coordinate for the shrinking of the east-west distances
    double new_x = x / Math.cos(y0);

    double foundLongitude = new_x + x0;
    double foundLatitude = y + y0;
    System.out.println("Longitude: " + foundLongitude + "  Latitude: " + foundLatitude );
}

I removed the dependency on external libraries to make it more accessible.

 

SELECT * FROM(
    SELECT *,(((acos(sin((@latitude*pi()/180)) * sin((Latitude*pi()/180))+cos((@latitude*pi()/180)) * cos((Latitude*pi()/180)) * cos(((@longitude - Longitude)*pi()/180))))*180/pi())*60*1.1515*1.609344) as distance FROM Distances) t
WHERE distance <= @distance



SELECT * , 6371.04 * ACOS( COS( PI( ) /2 - RADIANS( 90 - Latitude) ) * COS( PI( ) /2 - RADIANS( 90 - '$latitude' ) ) * COS( RADIANS( Longitude) - RADIANS( '$longitude' ) ) + SIN( PI( ) /2 - RADIANS( 90 - Latitude) ) * SIN( PI( ) /2 - RADIANS( 90 - '$latitude' ) ) ) AS Distance FROM MyLocations WHERE ( 6371.04 * ACOS( COS( PI( ) /2 - RADIANS( 90 - Latitude) ) * COS( PI( ) /2 - RADIANS( 90 - '$latitude' ) ) * COS( RADIANS( Longitude) - RADIANS( '$longitude' ) ) + SIN( PI( ) /2 - RADIANS( 90 - Latitude) ) * SIN( PI( ) /2 - RADIANS( 90 - '$latitude' ) ) ) <1 ) GROUP BY one_id HAVING dist < '$radius' ORDER BY Distance LIMIT 0 , $numberOfResults

Finding Points Within a Distance of a Latitude/Longitude Using Bounding Coordinates

Abstract

This article describes how to efficiently query a database for places that are within a certain distance from a point given in spherical coordinates (latitude and longitude). The method computes bounding coordinates that can be used for a database index scan – just like we would use minimum bounding rectangles to speed up queries in Cartesian space. It is accurate for short distances as well as for long distances, and works for any geographic location, even if it is near a pole or the 180th meridian.

Contents

1 Distance Between Two Given Points

The shortest distance (the geodesic) between two given points P1=(lat1, lon1) and P2=(lat2, lon2) on the surface of a sphere with radiusR is the great circle distance. It can be calculated using the formula:

dist = arccos(sin(lat1) · sin(lat2) + cos(lat1) · cos(lat2) · cos(lon1lon2)) · R(1)

For example, the distance between the Statue of Liberty at (40.6892°, -74.0444°)=(0.7102 rad, -1.2923 rad) and the Eiffel Tower at (48.8583°, 2.2945°)=(0.8527 rad, 0.0400 rad) – assuming a spherical approximationa of the figure of the Earth with radius R=6371 km – is:

dist = arccos(sin(0.7102) · sin(0.8527) + cos(0.7102) · cos(0.8527) · cos(-1.2923 – 0.0400)) · 6371 km
= 5837 km(2)

2 Finding Places Within a Distance Without Using an Index

Suppose we want to find places within a distance d=1000 km from M=(lat, lon)=(1.3963, -0.6981) in a database. Given that we have a table named Places with columns Lat and Lon that hold the coordinates in radians (the trigonometric functions of SQL expect radians), then we could use this SQL query:

SELECT * FROM Places WHERE acos(sin(1.3963) * sin(Lat) + cos(1.3963) * cos(Lat) * cos(Lon - (-0.6981))) * 6371 <= 1000;

The problem with this query is that our database system will not be able to utilize indices on the Lat and Lon columns because of the complexity of the formula in the WHERE clause.

3 Finding Places Within a Distance Using an Index

In order to utilize indices on the Lat and Lon columns we can use a method similar to the bounding rectangle method in Cartesian space. Let’s call the circle that is formed by all points which have distance d from M the query circle. The following subsections explain how to compute bounding coordinates (latmin, lonmin) and (latmax, lonmax) which are opposite corners of a bounding rectangle (on the sphere) that completely contains the query circle. Points outside this rectangle are therefore definitely not within distance d from M, so in order to find points that are within the query circle, we need to consider the points within the bounding rectangle only. Those points (called candidate places) can be found quickly using an index (see section 3.5 for SQL queries).

Let’s define r = d/R = (1000 km)/(6371 km) = 0.1570 as the angular radius of the query circle.

3.1 Computing the Minimum and Maximum Latitude

Moving on a circle with radius R=6371 km from a point A to a point B such that there is an angle r=0.1570 between A and B means covering a distance of d=1000 km. Meridians are on such great circles with radius R. Hence we can move along a meridian, i.e. keep the longitude fixed, and simply substract/add r from/to lat in order to obtain the minimum/maximum latitude of all points within the query circle with center M=(lat, lon)=(1.3963, -0.6981):

latmin = latr = 1.2393(3)
latmax = lat + r = 1.5532(4)

Note that special care must be taken if a pole is within the query circle. See section 3.4 for details.

3.2 Computing the Minimum and Maximum Longitude – the Incorrect Way

One approach seen on several web pages for computing the minimum and maximum longitudes is keeping the latitude fixed and changing the longitude, i.e. moving along a circle of latitude. This section will show that this approach gives inaccurate results.

Moving along a circle of latitude means moving along a small circle. A circle of latitude at latitude lat=1.3963 has the radius Rs = R · cos(lat) = 1106 km, so d=1000 km now corresponds to an angular radius of rs = d/Rs = d/(R · cos(lat)) = 0.9039. Hence, coveringd=1000 km on a circle of latitude gets you to longitude lonS = lon ± d/(R · cos(lat)) = -0.6981 ± 0.9039. But this is not the minimum/maximum longitude you can get to by moving d=1000 km in any direction! This is because we moved the distance on a small circle, but small circle distances are greater than great circle distances. Although M=(lat, lon)=(1.3963, -0.6981) and PS=(lat, lonS)=(1.3963, -1.6020) have a distance of d=1000 km on the short circle, we could take a shortcut from M to PS on a great circle. According toequation 1, that shortcut has a length of 967 km. So we could move another 33 km and would still be within the query circle. In particular, we could reach even smaller respectively greater longitudes. So using lon ± d/(R · cos(lat)) as bounding values for longitude would miss some locations that are actually within distance d. For example, the point P3=(1.4618, -1.6021) is outside the computed bounding “box”, although its distance to M is only 872 km. That is an error of more than 12 %!

3.3 Computing the Minimum and Maximum Longitude – the Correct Way

Figure 1: Tangent meridians to the query circle [1]

Moving along a circle of latitude in order to find the minimum and maximum longitude does not work at all as you can see in figure 1: The points on the query circle having the minimum/maximum longitude, T1 and T2, are not on the same circle of latitude as M but closer to the pole. The formulae for the coordinates of these points can be found in a good math handbook like [1]. They are:

latT = arcsin(sin(lat)/cos(r)) = 1.4942(5)
lonmin = lonT1 = lonΔlon = -1.8184(6)
lonmax = lonT2 = lon + Δlon = 0.4221(7)

where

Δlon = arccos( ( cos(r) – sin(latT) · sin(lat) ) / ( cos(latT) · cos(lat) ) )
= arcsin(sin(r)/cos(lat)) = 1.1202(8)

Note that special care must be taken if the 180th meridian is within the query circle. See section 3.4 for details.

3.4 Dealing with Poles and the 180th Meridian

If latmax, as defined in section 3.1, is greater than π/2, then the North Pole is within the query circle, which means that parts of all meridians are within the query circle as well. Thus, in that case the bounding coordinates are (latmin, -π) and (π/2, π). If latmin is smaller than -π/2, then the South Pole is within the query circle and the bounding coordinates are (-π/2, -π) and (latmax, π).

If one of lonmin/max, as defined in section 3.3, is outside the range of valid longitude values [-π, π], the 180th meridian is within the query circle. In that case one could use (latmin, -π) and (latmax, π) as the bounding coordinates, i.e. something with a shape like a belt around the sphere. But that would include many candidate places that are not actually within the distance. Alternatively one could use two bounding “boxes” and it is sufficient for a candidate place to be in one of them. If lonmin < -π, the two sets of bounding coordinates are (latmin, lonmin + 2π), (latmax, π) and (latmin, -π), (latmax, lonmax). If lonmax > π, the two sets of bounding coordinates are (latmin,lonmin), (latmax, π) and (latmin, -π), (latmax, lonmax – 2π).

3.5 SQL Queries

Now that we have computed the bounding coordinates (latmin, lonmin)=(1.2393, -1.8184) and (latmax, lonmax)=(1.5532, 0.4221), we can use them in an SQL query. In the following, it is assumed that latitude and longitude – both in radians – are stored in two separate columns with an index that supports range queries (e.g. a B-tree) on each of them. If your database management system supports a point data type and a spatial index (e.g. an R-tree) on such columns, you can also use that.

There are different ways to combine the filter using the bounding coordinates with the formula for the great circle distance in an SQL statement:

  • Simply combining the conditions with AND:
    SELECT * FROM Places WHERE
        (Lat => 1.2393 AND Lat <= 1.5532) AND (Lon >= -1.8184 AND Lon <= 0.4221)
    AND
        acos(sin(1.3963) * sin(Lat) + cos(1.3963) * cos(Lat) * cos(Lon - (-0.6981))) <= 0.1570;

    Most query optimizers are smart enough to perform an index scan to quickly find places satisfying (Lat >= 1.2393 AND Lat <= 1.5532) AND (Lon >= -1.8184 AND Lon <= 0.4221) and evaluate the formula for the great circle distance for each remaining candidate result only.

  • The pre-filter in the WHERE clause and the more specific formula in a HAVING clause:
    SELECT * FROM Places WHERE
        (Lat >= 1.2393 AND Lat <= 1.5532) AND (Lon >= -1.8184 AND Lon <= 0.4221)
    HAVING
        acos(sin(1.3963) * sin(Lat) + cos(1.3963) * cos(Lat) * cos(Lon - (-0.6981))) <= 0.1570;
  • The pre-filter in a sub-query:
    SELECT * FROM (
        SELECT * FROM Places WHERE
            (Lat >= 1.2393 AND Lat <= 1.5532) AND (Lon >= -1.8184 AND Lon <= 0.4221)
    ) WHERE
        acos(sin(1.3963) * sin(Lat) + cos(1.3963) * cos(Lat) * cos(Lon - (-0.6981))) <= 0.1570;

4 Java Source Code

4.1 The GeoLocation Class

Below you will find a ready-to-use Java GeoLocation class. The boundingCoordinates() method computes the bounding coordinates using the method explained in section 3. Section 4.2 shows an example usage of the GeoLocation class.

Download GeoLocation.java

/**
 * <p>Represents a point on the surface of a sphere. (The Earth is almost
 * spherical.)</p>
 *
 * <p>To create an instance, call one of the static methods fromDegrees() or
 * fromRadians().</p>
 *
 * <p>This code was originally published at
 * <a href="http://JanMatuschek.de/LatitudeLongitudeBoundingCoordinates#Java">
 * http://JanMatuschek.de/LatitudeLongitudeBoundingCoordinates#Java</a>.</p>
 *
 * @author Jan Philip Matuschek
 * @version 22 September 2010
 */
public class GeoLocation {

	private double radLat;  // latitude in radians
	private double radLon;  // longitude in radians
	/**
	 * Computes the great circle distance between this GeoLocation instance
	 * and the location argument.
	 * @param radius the radius of the sphere, e.g. the average radius for a
	 * spherical approximation of the figure of the Earth is approximately
	 * 6371.01 kilometers.
	 * @return the distance, measured in the same unit as the radius
	 * argument.
	 */
	public double distanceTo(GeoLocation location, double radius) {
		return Math.acos(Math.sin(radLat) * Math.sin(location.radLat) +
				Math.cos(radLat) * Math.cos(location.radLat) *
				Math.cos(radLon - location.radLon)) * radius;
	}

	/**
	 * <p>Computes the bounding coordinates of all points on the surface
	 * of a sphere that have a great circle distance to the point represented
	 * by this GeoLocation instance that is less or equal to the distance
	 * argument.</p>
	 * <p>For more information about the formulae used in this method visit
	 * <a href="http://JanMatuschek.de/LatitudeLongitudeBoundingCoordinates">
	 * http://JanMatuschek.de/LatitudeLongitudeBoundingCoordinates</a>.</p>
	 * @param distance the distance from the point represented by this
	 * GeoLocation instance. Must me measured in the same unit as the radius
	 * argument.
	 * @param radius the radius of the sphere, e.g. the average radius for a
	 * spherical approximation of the figure of the Earth is approximately
	 * 6371.01 kilometers.
	 * @return an array of two GeoLocation objects such that:<ul>
	 * <li>The latitude of any point within the specified distance is greater
	 * or equal to the latitude of the first array element and smaller or
	 * equal to the latitude of the second array element.</li>
	 * <li>If the longitude of the first array element is smaller or equal to
	 * the longitude of the second element, then
	 * the longitude of any point within the specified distance is greater
	 * or equal to the longitude of the first array element and smaller or
	 * equal to the longitude of the second array element.</li>
	 * <li>If the longitude of the first array element is greater than the
	 * longitude of the second element (this is the case if the 180th
	 * meridian is within the distance), then
	 * the longitude of any point within the specified distance is greater
	 * or equal to the longitude of the first array element
	 * <strong>or</strong> smaller or equal to the longitude of the second
	 * array element.</li>
	 * </ul>
	 */
	public GeoLocation[] boundingCoordinates(double distance, double radius) {

		if (radius < 0d || distance < 0d)
			throw new IllegalArgumentException();

		// angular distance in radians on a great circle
		double radDist = distance / radius;

		double minLat = radLat - radDist;
		double maxLat = radLat + radDist;

		double minLon, maxLon;
		if (minLat > MIN_LAT && maxLat < MAX_LAT) {
			double deltaLon = Math.asin(Math.sin(radDist) /
				Math.cos(radLat));
			minLon = radLon - deltaLon;
			if (minLon < MIN_LON) minLon += 2d * Math.PI;
			maxLon = radLon + deltaLon;
			if (maxLon > MAX_LON) maxLon -= 2d * Math.PI;
		} else {
			// a pole is within the distance
			minLat = Math.max(minLat, MIN_LAT);
			maxLat = Math.min(maxLat, MAX_LAT);
			minLon = MIN_LON;
			maxLon = MAX_LON;
		}

		return new GeoLocation[]{fromRadians(minLat, minLon),
				fromRadians(maxLat, maxLon)};
	}

}

Download GeoLocation.java

4.2 Using the GeoLocation Class

Here is some demo code that shows how to use the GeoLocation class from section 4.1 to query a database for places within a certain distance.

Download GeoLocationDemo.java

/**
 * <p>See
 * <a href="http://JanMatuschek.de/LatitudeLongitudeBoundingCoordinates#Java">
 * http://JanMatuschek.de/LatitudeLongitudeBoundingCoordinates#Java</a>
 * for the GeoLocation class referenced from this code.</p>
 *
 * @author Jan Philip Matuschek
 * @version 26 May 2010
 */
public class GeoLocationDemo {

	/**
	 * @param radius radius of the sphere.
	 * @param location center of the query circle.
	 * @param distance radius of the query circle.
	 * @param connection an SQL connection.
	 * @return places within the specified distance from location.
	 */
	public static java.sql.ResultSet findPlacesWithinDistance(
			double radius, GeoLocation location, double distance,
			java.sql.Connection connection) throws java.sql.SQLException {

		GeoLocation[] boundingCoordinates =
			location.boundingCoordinates(distance, radius);
		boolean meridian180WithinDistance =
			boundingCoordinates[0].getLongitudeInRadians() >
			boundingCoordinates[1].getLongitudeInRadians();

		java.sql.PreparedStatement statement = connection.prepareStatement(
			"SELECT * FROM Places WHERE (Lat >= ? AND Lat <= ?) AND (Lon >= ? " +
			(meridian180WithinDistance ? "OR" : "AND") + " Lon <= ?) AND " +
			"acos(sin(?) * sin(Lat) + cos(?) * cos(Lat) * cos(Lon - ?)) <= ?");
		statement.setDouble(1, boundingCoordinates[0].getLatitudeInRadians());
		statement.setDouble(2, boundingCoordinates[1].getLatitudeInRadians());
		statement.setDouble(3, boundingCoordinates[0].getLongitudeInRadians());
		statement.setDouble(4, boundingCoordinates[1].getLongitudeInRadians());
		statement.setDouble(5, location.getLatitudeInRadians());
		statement.setDouble(6, location.getLatitudeInRadians());
		statement.setDouble(7, location.getLongitudeInRadians());
		statement.setDouble(8, distance / radius);
		return statement.executeQuery();
	}

	public static void main(String[] args) {

		double earthRadius = 6371.01;
		GeoLocation myLocation = GeoLocation.fromRadians(1.3963, -0.6981);
		double distance = 1000;
		java.sql.Connection connection = ...;

		java.sql.ResultSet resultSet = findPlacesWithinDistance(
				earthRadius, myLocation, distance, connection);

		...;
	}

}

Download GeoLocationDemo.java

5 Implementations in Other Programming Languages

Some people have translated the Java code from section 4 into other programming languages and published their results. There are implementations in C#, PHP and Python. Note that I have not checked these for correctness.

Footnotes

  1. The maximum error that results from using a spherical Earth model for distance calculations is no more than 0.5 %. [2]

References

  1. Clynch: Earth Models and Maps. http://www.oc.nps.edu/oc2902w/general/mapmodel.pdf