diff --git a/utm/__init__.py b/utm/__init__.py
index 4c844d2..3dece60 100644
--- a/utm/__init__.py
+++ b/utm/__init__.py
@@ -1,2 +1,2 @@
-from utm.conversion import to_latlon, from_latlon
+from utm.conversion import to_latlon, from_latlon, latlon_to_zone_number, latitude_to_zone_letter
 from utm.error import OutOfRangeError
diff --git a/utm/conversion.py b/utm/conversion.py
old mode 100644
new mode 100755
index 5d5723a..eb3b35d
--- a/utm/conversion.py
+++ b/utm/conversion.py
@@ -29,16 +29,10 @@ P5 = (1097. / 512 * _E4)
 
 R = 6378137
 
-ZONE_LETTERS = [
-    (84, None), (72, 'X'), (64, 'W'), (56, 'V'), (48, 'U'), (40, 'T'),
-    (32, 'S'), (24, 'R'), (16, 'Q'), (8, 'P'), (0, 'N'), (-8, 'M'), (-16, 'L'),
-    (-24, 'K'), (-32, 'J'), (-40, 'H'), (-48, 'G'), (-56, 'F'), (-64, 'E'),
-    (-72, 'D'), (-80, 'C')
-]
+ZONE_LETTERS = "CDEFGHJKLMNPQRSTUVWXX"
 
 
 def to_latlon(easting, northing, zone_number, zone_letter=None, northern=None):
-
     if not zone_letter and northern is None:
         raise ValueError('either zone_letter or northern needs to be set')
 
@@ -90,7 +84,7 @@ def to_latlon(easting, northing, zone_number, zone_letter=None, northern=None):
     n = R / ep_sin_sqrt
     r = (1 - E) / ep_sin
 
-    c = _E * p_cos**2
+    c = _E * p_cos ** 2
     c2 = c * c
 
     d = x / (n * K0)
@@ -103,7 +97,7 @@ def to_latlon(easting, northing, zone_number, zone_letter=None, northern=None):
     latitude = (p_rad - (p_tan / r) *
                 (d2 / 2 -
                  d4 / 24 * (5 + 3 * p_tan2 + 10 * c - 4 * c2 - 9 * E_P2)) +
-                 d6 / 720 * (61 + 90 * p_tan2 + 298 * c + 45 * p_tan4 - 252 * E_P2 - 3 * c2))
+                d6 / 720 * (61 + 90 * p_tan2 + 298 * c + 45 * p_tan4 - 252 * E_P2 - 3 * c2))
 
     longitude = (d -
                  d3 / 6 * (1 + 2 * p_tan2 + c) +
@@ -138,8 +132,8 @@ def from_latlon(latitude, longitude, force_zone_number=None):
     central_lon = zone_number_to_central_longitude(zone_number)
     central_lon_rad = math.radians(central_lon)
 
-    n = R / math.sqrt(1 - E * lat_sin**2)
-    c = E_P2 * lat_cos**2
+    n = R / math.sqrt(1 - E * lat_sin ** 2)
+    c = E_P2 * lat_cos ** 2
 
     a = lat_cos * (lon_rad - central_lon_rad)
     a2 = a * a
@@ -158,7 +152,7 @@ def from_latlon(latitude, longitude, force_zone_number=None):
                         a5 / 120 * (5 - 18 * lat_tan2 + lat_tan4 + 72 * c - 58 * E_P2)) + 500000
 
     northing = K0 * (m + n * lat_tan * (a2 / 2 +
-                                        a4 / 24 * (5 - lat_tan2 + 9 * c + 4 * c**2) +
+                                        a4 / 24 * (5 - lat_tan2 + 9 * c + 4 * c ** 2) +
                                         a6 / 720 * (61 - 58 * lat_tan2 + lat_tan4 + 600 * c - 330 * E_P2)))
 
     if latitude < 0:
@@ -168,11 +162,10 @@ def from_latlon(latitude, longitude, force_zone_number=None):
 
 
 def latitude_to_zone_letter(latitude):
-    for lat_min, zone_letter in ZONE_LETTERS:
-        if latitude >= lat_min:
-            return zone_letter
-
-    return None
+    if -80 <= latitude <= 84:
+        return ZONE_LETTERS[int(latitude + 80) >> 3]
+    else:
+        return None
 
 
 def latlon_to_zone_number(latitude, longitude):

Zone letter problem
Zone letter return 'None' for latitude 84
diff --git a/test/test_utm.py b/test/test_utm.py
old mode 100644
new mode 100755
index 1ffcab2..4e8f7e8
--- a/test/test_utm.py
+++ b/test/test_utm.py
@@ -58,6 +58,12 @@ class KnownValues(UTMTestCase):
             (377486, 6296562, 30, 'V'),
             {'northern': True},
         ),
+        # Latitude 84
+        (
+            (84, -5.00601),
+            (476594, 9328501, 30, 'X'),
+            {'northern': True},
+        ),
     ]
 
     def test_from_latlon(self):

pip install -e .
parse_log_pytest
pytest
pytest
3.9
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
exceptiongroup @ file:///croot/exceptiongroup_1706031385326/work
iniconfig @ file:///home/linux1/recipes/ci/iniconfig_1610983019677/work
packaging @ file:///croot/packaging_1734472117206/work
pluggy @ file:///croot/pluggy_1733169602837/work
pytest @ file:///croot/pytest_1738938843180/work
tomli @ file:///opt/conda/conda-bld/tomli_1657175507142/work
-e git+https://github.com/Turbo87/utm.git@a8b2496e534671e5f07a19371f2c80813d7f2f50#egg=utm

name: utm
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - exceptiongroup=1.2.0=py39h06a4308_0
  - iniconfig=1.1.1=pyhd3eb1b0_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - packaging=24.2=py39h06a4308_0
  - pip=25.0=py39h06a4308_0
  - pluggy=1.5.0=py39h06a4308_0
  - pytest=8.3.4=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tomli=2.0.1=py39h06a4308_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
prefix: /opt/conda/envs/utm

test/test_utm.py::KnownValues::test_from_latlon
test/test_utm.py::KnownValues::test_to_latlon test/test_utm.py::BadInput::test_from_latlon_range_checks test/test_utm.py::BadInput::test_to_latlon_range_checks
utm/conversion.py utm/__init__.py
utm/conversion.py utm/__init__.py