Shawn Laffan






 use Geo::Converter::dms2dd qw { dms2dd };

 my $dms_value;
 my $dd_value;
 $dms_value = q{S23Â°32'09.567"};
 $dd_value  = dms2dd ({value => $dms_value});
 print $dms_value
 #  -23.5359908333333

 $dms_value = q{149Â°23'18.009"E};
 print $dd_value
 #   149.388335833333
 $dms_value = q{east 149Â°23'18.009};
 print $dd_value
 #   149.388335833333
 #  The following all croak with warnings:
 $dms_value = q{S23Â°32'09.567"};
 $dd_value  = dms2dd ({value => $dms_value, is_lon => 1});
 # Coord error:  Longitude specified, but latitude found

 $dms_value = q{149Â°23'18.009"E};
 $dd_value  = dms2dd ({value => $dms_value, is_lat => 1});
 # Coord error:  Latitude out of bounds: 149.388335833333
 $dms_value = q{149Â°23'18.009"25};  #  extra number
 # DMS value error: Too many numbers in string: '149Â°23'18.009"25'


Use this module to convert a coordinate value in degrees minutes seconds to decimal degrees. It exports a single sub dms2dd which will parse and convert a single value.

A reasonable amount of location information is provided in degrees/minutes/seconds (DMS) format, for example from Google Earth, GIS packages or similar. For example, one might be given a location coordinate for just north east of Dingo in Queensland, Australia. Four possible formats are:

 S23Â°32'09.567", E149Â°23'18.009"
 23Â°32'09.567"S, 149Â°23'18.009"E
 -23 32 9.567,   +149 23 18.009
 -23.535991,     149.388336

The first three coordinates are in degrees/minutes/seconds while the fourth is in decimal degrees. The fourth coordinate can be used in numeric calculations, but the first three must first be converted to decimal degrees.

The conversion process used in dms2dd is pretty generous in what it treats as DMS, as there is a multitude of variations in punctuation and the like. Up to three numeric values are extracted and any additional text is largely ignored unless it could be interpreted as the hemisphere (see below). It croaks if there are four or more numeric values. If the hemisphere is known or the is_lat or is_lon arguments are specified then values are validated (e.g. latitudes must be in the interval [-90, 90], and longitudes with a hemisphere specified must be within [-180, 180]). Otherwise values between [-180, 360] are accepted. If seconds are specified and minutes have values after the radix (decimal point) then it croaks (e.g. 35 26.5' 22"). Likewise, it croaks for cases like (35.2d 26'). It will also croak if you specify the hemisphere at the start and end of the value, even if it is the same hemisphere.

Note that this module only works on a single value. Call it once each for latitude and longitude values to convert a full coordinate.


Shawn Laffan (


Hemispheres are very liberally interpreted. So long as the text component starts with a valid character then it is used. This means that (E 35 26') is treated the same as (Egregious 35 26').

It also does not deal with non-English spellings of north, south, east or west. Hemispheres need to satisfy qr/[NESWnesw+-]/. A solution could be to drop in an appropriate regexp as an argument, or maybe there is an i18n solution. Patches welcome.

It could probably also give the parsed degrees, minutes and seconds rather than convert them. They are pretty easy to calculate, though.

Submit bugs, fixes and enhancement requests via the bug tracker at



See also

Geo::Coordinates::DecimalDegrees, although it requires the degrees, minutes and seconds values to already be parsed from the string.