function ConvertDDToDMS(D, lng) {
return {
dir: D < 0 ? (lng ? "W" : "S") : lng ? "E" : "N",
deg: 0 | (D < 0 ? (D = -D) : D),
min: 0 | (((D += 1e-9) % 1) * 60),
sec: (0 | (((D * 60) % 1) * 6000)) / 100,
};
}
The above gives you an object {deg, min, sec, dir}
with sec truncated to two digits (e.g. 3.14
) and dir being one of N
, E
, S
, W
depending on whether you set the lng
(longitude) parameter to true. e.g.:
ConvertDDToDMS(-18.213, true) == {
deg : 18,
min : 12,
sec : 46.79,
dir : 'W'
}
Or if you just want the basic string:
function ConvertDDToDMS(D){
return [0|D, 'd ', 0|(D=(D<0?-D:D)+1e-4)%1*60, "' ", 0|D*60%1*60, '"'].join('');
}
ConvertDDToDMS(-18.213) == `-18d 12' 47"`
[edit June 2019] -- fixing an 8 year old bug that would sometimes cause the result to be 1 minute off due to floating point math when converting an exact minute, e.g. ConvertDDToDMS(4 + 20/60)
.
[edit Dec 2021] -- Whoops. Fix #2. Went back to the original code and added 1e-9
to the value which a) bumps any slightly low floating point errors to the next highest number and b) is less than .01
sec, so has no effect on the output. Added 1e-4
to the "string" version which is the same fix, but also rounds seconds (it's close to 1/2 sec).