How do you convert Decimal Degrees to Degrees Minutes Seconds In Python? Is there a Formula already written?
-
@David: it's a matter of multiplying decimal part by 60. What do you need beyond that? – SilentGhost Apr 05 '10 at 16:45
15 Answers
This is exactly what divmod
was invented for:
def decdeg2dms(dd):
mult = -1 if dd < 0 else 1
mnt,sec = divmod(abs(dd)*3600, 60)
deg,mnt = divmod(mnt, 60)
return mult*deg, mult*mnt, mult*sec
dd = 45 + 30/60 + 1/3600
print(decdeg2dms(dd))
# negative value returns all negative elements
print(decdeg2dms(-122.442))
Prints:
(45.0, 30.0, 1.0)
(-122.0, -26.0, -31.199999999953434)

- 62,419
- 16
- 94
- 130
-
2It doesn't work with negative. -122.442 returns (-123,33,28.8). Should be (-122,26,31.12) – Erik L Apr 23 '12 at 18:16
-
@baens - do you mean `(-122, -26, -31.12)`? I think `-123 + 33/60 + 28.8/3600` does in fact equal `-122.442` – PaulMcG Jun 24 '12 at 19:19
-
A multiplication by 3600, followed by 2 divisions by 60, doesn't look as efficient as possible. – musiphil Jun 01 '15 at 22:44
-
As said by @erik-l it gives wrong results for negative angles and must be corrected – John Smith May 27 '22 at 09:39
-
2Only took 10 years, but here is a solution where all values are positive or negative, not mixed. – PaulMcG May 28 '22 at 00:31
Here is my updated version based upon Paul McGuire's. This one should handle negatives correctly.
def decdeg2dms(dd):
is_positive = dd >= 0
dd = abs(dd)
minutes,seconds = divmod(dd*3600,60)
degrees,minutes = divmod(minutes,60)
degrees = degrees if is_positive else -degrees
return (degrees,minutes,seconds)

- 1,104
- 15
- 31
-
`minutes` and `seconds` also need to be negated if `is_positive` is False. – PaulMcG May 28 '22 at 00:33
If you want to handle negatives properly, the first non-zero measure is set negative. It is counter to common practice to specify all of degrees, minutes and seconds as negative (Wikipedia shows 40° 26.7717, -79° 56.93172 as a valid example of degrees-minutes notation, in which degrees are negative and minutes have no sign), and setting degrees as negative does not have any effect if the degrees portion is 0. Here is a function that adequately handles this, based on Paul McGuire's and baens' functions:
def decdeg2dms(dd):
negative = dd < 0
dd = abs(dd)
minutes,seconds = divmod(dd*3600,60)
degrees,minutes = divmod(minutes,60)
if negative:
if degrees > 0:
degrees = -degrees
elif minutes > 0:
minutes = -minutes
else:
seconds = -seconds
return (degrees,minutes,seconds)

- 170
- 2
- 5
Just a couple of * 60
multiplications and a couple of int
truncations, i.e.:
>>> decdegrees = 31.125
>>> degrees = int(decdegrees)
>>> temp = 60 * (decdegrees - degrees)
>>> minutes = int(temp)
>>> seconds = 60 * (temp - minutes)
>>> print degrees, minutes, seconds
31 7 30.0
>>>

- 854,459
- 170
- 1,222
- 1,395
This is my Python code:
def DecimaltoDMS(Decimal):
d = int(Decimal)
m = int((Decimal - d) * 60)
s = (Decimal - d - m/60) * 3600.00
z= round(s, 2)
if d >= 0:
print ("N ", abs(d), "º ", abs(m), "' ", abs(z), '" ')
else:
print ("S ", abs(d), "º ", abs(m), "' ", abs(z), '" ')

- 658
- 8
- 29
-
4Using `Decimal` as a variable name may conflict with `decimal.Decimal` and is not a good idea. – musiphil Jun 01 '15 at 22:51
Improving @chqrlie answer:
def deg_to_dms(deg, type='lat'):
decimals, number = math.modf(deg)
d = int(number)
m = int(decimals * 60)
s = (deg - d - m / 60) * 3600.00
compass = {
'lat': ('N','S'),
'lon': ('E','W')
}
compass_str = compass[type][0 if d >= 0 else 1]
return '{}º{}\'{:.2f}"{}'.format(abs(d), abs(m), abs(s), compass_str)

- 463
- 6
- 10
The sign has better be returned separately, so that it can be used to choose from ('N', 'S')
or ('E', 'W')
, for example.
import math
def dd_to_dms(degs):
neg = degs < 0
degs = (-1) ** neg * degs
degs, d_int = math.modf(degs)
mins, m_int = math.modf(60 * degs)
secs = 60 * mins
return neg, d_int, m_int, secs

- 3,837
- 2
- 20
- 26
Here's my slightly different approach that works the same as on my HP Prime for positive and negative decimal degrees...
def dms(deg):
f,d = math.modf(deg)
s,m = math.modf(abs(f) * 60)
return (d,m,s * 60)

- 61
- 3
Use fmod
and rounding to get the degrees and fraction separated. Multiply the fraction by 60 and repeat to get minutes and a remainder. Then multiply that last part by 60 again to get the number of seconds.

- 133,037
- 18
- 149
- 215
Now we can use LatLon library...
https://pypi.org/project/LatLon/
>> palmyra = LatLon(Latitude(5.8833), Longitude(-162.0833)) # Location of Palmyra Atoll in decimal degrees
>> palmyra = LatLon(5.8833, -162.0833) # Same thing but simpler!
>> palmyra = LatLon(Latitude(degree = 5, minute = 52, second = 59.88),
Longitude(degree = -162, minute = -4.998) # or more complicated!
>> print palmyra.to_string('d% %m% %S% %H') # Print coordinates to degree minute second
('5 52 59.88 N', '162 4 59.88 W')`
-
The version you linked is only tested to Python 2.7. There is a newer version, but even that one is only tested to Python 3.6 https://pypi.org/project/latlon3 – user3185563 Dec 19 '20 at 10:24
-
1Hi, what I am using now is LatLon23 in my Python 3.7.4 https://pypi.org/project/LatLon23/#description – Sungsoo Lim Dec 20 '20 at 16:46
-
That's great. It seems to be working with 3.9 as well. It's more straightforward than Geographiclib, which is what I ended up with. – user3185563 Dec 21 '20 at 11:34
-
Just a note for users following the documentation that says that you import the module using the syntax `import latlon` You need to use the following `from latlon import LatLon` to make these examples work. Note the case – Jul 19 '22 at 02:41
You can use the function clean_lat_long()
from the library DataPrep if your data is in a DataFrame. Install DataPrep with pip install dataprep
.
from dataprep.clean import clean_lat_long
df = pd.DataFrame({"coord": [(45.5003, -122.4420), (5.8833, -162.0833)]})
df2 = clean_lat_long(df, "coord", output_format="dms")
# print(df2)
coord coord_clean
0 (45.5003, -122.442) 45° 30′ 1.08″ N, 122° 26′ 31.2″ W
1 (5.8833, -162.0833) 5° 52′ 59.88″ N, 162° 4′ 59.88″ W
Or if latitude and longitude are in separate columns:
df = pd.DataFrame({"latitude": [45.5003, 5.8833], "longitude": [-122.4420, -162.0833]})
df2 = clean_lat_long(df, lat_col="latitude", long_col="longitude", output_format="dms")
# print(df2)
latitude longitude latitude_longitude
0 45.5003 -122.4420 45° 30′ 1.08″ N, 122° 26′ 31.2″ W
1 5.8833 -162.0833 5° 52′ 59.88″ N, 162° 4′ 59.88″ W

- 225
- 2
- 6
# Program to convert degree to Degree, Minutes and Seconds
# Using try and except for int data validations
try:
# Requesting input degree from user
print ("degree to Degree Minutes seconds converter ". upper ())
degree = float(input ("\nEnter Degree: "))
# Casting input from float to int
degree_d = int(degree)
# Working on minutes
minute =60 * (degree - degree_d)
minutes = int(minute)
# Working on seconds
second = 60 * (minute - minutes)
# Rounding seconds to whole number
seconds= round(second)
# print
print (f"\nThe Answer In Degree-Minutes-Seconds are: \n{degree_d}°{minutes}'{seconds}\" ✓\n ")
#Except
except ValueError:
print ("Wrong Input ")

- 3,578
- 2
- 8
- 30

- 1
My approach:
import sys
import math
dd = float(sys.argv[1])
f,d = math.modf(dd)
f,m = math.modf(60*f)
s = round(60*f, 6)
print(int(d), int(m), s)

- 11
- 1
-
1Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jun 19 '23 at 21:57
-
Testing with math.degrees(1.777036) and rounding set to 1 decimal place on seconds you get (101 48 60.0) -- any simplistic conversion that rounds will have this kind of issue. – DarkStar Jun 26 '23 at 19:42
This is a numpy version of PaulMcG's answer with the addition that it will round to tenths of a second (you can change second argument to round function) and it returns the sign (-1 or 1) as a separate value (this made it easier for me to handle as latitude/longitude values). Main difference here is that you can pass in an array of decimal_degrees or a single double value (note if you pass a list you get a list-of-lists back). Before using please make sure you are happy with the rounding behavior or you can remove it.
def to_dms(decimal_degrees):
# convert degrees into dms and a sign indicator
degrees = np.array(decimal_degrees)
sign = np.where(degrees < 0, -1, 1)
r, s = np.divmod(np.round(np.abs(degrees) * 3600, 1), 60)
d, m = np.divmod(r, 60)
# np.transpose([d, m, s]*sign) # if you wanted signed results
return np.transpose([d, m, s, sign])
# print("array test:", to_dms([101.816652, -101.816653]))
# array test: [[101. 48. 59.9000000000232831 1.] [101. 49. 0. -1.]]

- 555
- 4
- 5
def dms_to_deg(dms):
import math
import numpy as np
a=math.fabs(dms)
d=a//10000
m=(a-d*10000)//100
s=(a-d*10000-m*100)
deg=(d+m/60+s/3600)*np.sign(dms)
return deg
#---Usage
r1=dms_to_deg(243055.25)
r2=dms_to_deg(-243055.25)
print(r1,r2)

- 1,673
- 7
- 24
- 38

- 1
- 1
-
A Python function to Convert degree minutes seconds to degree decimal for both positive and negative numbers. Check Example in Usage. – S.M.Saifullah Jul 19 '23 at 04:13
-
As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jul 23 '23 at 14:46