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/']
**Edit:** For (non-R) code that works for *all* non-polar areas on earth, see [here](https://gis.stackexchange.com/questions/13291/is-there-a-simple-way-to-compute-the-utm-zone-from-a-lat-long-point) or [here](http://www.igorexchange.com/node/927).

---

Unless you are dealing with data from a couple of exceptional areas ([Svalbard and parts of Norway](http://en.wikipedia.org/wiki/Universal_Transverse_Mercator_coordinate_system#Exceptions)), this is a simple enough calculation that you might as well just do it yourself in R. Here is [Wikipedia's description](http://en.wikipedia.org/wiki/Universal_Transverse_Mercator_coordinate_system) of how longitude relates to UTM Zone number:

> 
> The UTM system divides the surface of Earth between 80°S and 84°N latitude into 60 zones, each 6° of longitude in width. Zone 1 covers longitude 180° to 174° W; zone numbering increases eastward to zone 60 that covers longitude 174 to 180 East. 
> 
> 
> 

So, assuming that in your data longitudes to the west of the [Prime Meridian](http://en.wikipedia.org/wiki/Prime_Meridian) are encoded as running from -180 to 0 degrees, here's an R-code version of the above:

```
long2UTM <- function(long) {
    (floor((long + 180)/6) %% 60) + 1
}

# Trying it out for San Francisco, clearly in UTM Zone 10 
# in the figure in the Wikipedia article linked above
SFlong <- -122.4192
long2UTM(SFlong)
# [1] 10

```

That expression could obviously be simplified a bit, but I think in this form the logic underlying its construction is most clear. The `%% 60` bit is in there just in case some of your longitudes are greater than 180 or less than -180.
I made this function for me using the previous answers.
Maybe it is useful to someone here =)

```
utmzone <- function(lon,lat) {
## Special Cases for Norway & Svalbard
if (lat > 55 & lat < 64 & lon > 2 & lon < 6){ 
    band <- 32
  } else {
if (lat > 71 & lon >= 6 & lon < 9){
    band <- 31
  } else {
if (lat > 71 & lon >= 9 & lon < 12){
    band <- 33
  } else {
if (lat > 71 & lon >= 18 & lon < 21){
    band <- 33
  } else {
if (lat > 71 & lon >= 21 & lon < 24){
    band <- 35
  } else {
if (lat > 71 & lon >= 30 & lon < 33){
    band <- 35
  } else {
## Rest of the world
if (lon >= -180 & lon <= 180){
    band <- (floor((lon + 180)/6) %% 60) + 1
  } else {
    band <- "something is wrong"
    }}}}}}}
return(band)
}

utmzone(-43,-22)
#[1] 23

```