I'm writing a program which expects a number of lat/long points, and I convert them internally to UTM in order to do some calculations in metres.

The range of the lat/long points themselves is quite small -- about 200m x 200m. They can be relied on almost always to be within a single UTM zone (unless you get unlucky and are across the border of a zone).

However, the zone that the lat/longs are in is unrestricted. One day the program might be run for people in Australia (and oh, how many zones does even a single state lie across, and how much pain has that caused me already...), and another day for people in Mexico.

My question is -- is there a way to determine which zone a particular long/lat is in so that it may be fed into a conversion library (I currently use proj4 and also the R package `rgdal`). 

My language is R, but the answer doesn't have to be -- maybe it's just a simple calculation, or maybe I can embed a system call to the `proj` exectuable.

cheers.
['https://Stackoverflow.com/questions/9186496', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/913184/']
I don't know r-code but I suppose this PL/SQL code can help you with the exceptions:

```
   UTMZone := Trunc((lon - Zone0WestMeridian) / d);
    --Special Cases for Norway & Svalbard
    CASE 
    WHEN (lat > 55) AND (UTMZone = 31) AND (lat < 64) AND (lon >  2) THEN UTMZone := 32;
    WHEN (lat > 71) AND (UTMZone = 32) AND (lon <  9) THEN UTMZone := 31;
    WHEN (lat > 71) AND (UTMZone = 32) AND (lon >  8) THEN UTMZone := 33;
    WHEN (lat > 71) AND (UTMZone = 34) AND (lon < 21) THEN UTMZone := 33;
    WHEN (lat > 71) AND (UTMZone = 34) AND (lon > 20) THEN UTMZone := 35; 
    WHEN (lat > 71) AND (UTMZone = 36) AND (lon < 33) THEN UTMZone := 35;
    WHEN (lat > 71) AND (UTMZone = 36) AND (lon > 32) THEN UTMZone := 37;
    ELSE UTMZone := UTMZone;  
    END CASE;

```
Python version:

```
def get_utm_fromLatLon(lat, lon):
    #Special Cases for Norway and Svalbard
    if (lat > 55 and lat < 64 and lon > 2 and lon < 6):
        return 32
    elif (lat > 71 and lon >= 6 and lon < 9):
        return 31
    elif (lat > 71 and ((lon >= 9 and lon < 12) or (lon >= 18 and lon < 21))):
        return 33
    elif (lat > 71 and ((lon >= 21 and lon < 24) or (lon >= 30 and lon < 33))):
        return 35
    # Rest of the world
    elif (lon >= -180 and lon <= 180):
        return (math.floor((lon + 180) / 6) % 60) + 1
    else:
        raise ValueError('Cannot figure out UTM zone from given Lat: {0}, Lon: {1}.'.format(lat, lon))

```