subroutine sexag(ch,rr8,ndiv)
  use phys_const
  use gsys_interfaces, except_this=>sexag
  !---------------------------------------------------------------------
  ! @ public (obsolescent since 19-mar-2015, use rad2sexa instead)
  !  Writes an angle in sexagesimal notation. The number of characters
  ! updated are limited to 13.
  !---------------------------------------------------------------------
  character(len=*), intent(out) :: ch    ! Formatted string
  real(kind=8),     intent(in)  :: rr8   ! Angle in radians
  integer(kind=4),  intent(in)  :: ndiv  ! Number of divisions per turn (24/360)
  ! Local
  integer(kind=4) :: nchar
  real(kind=8) :: r8
  !
  ch = ' '
  nchar=min(len(ch),13)
  if (ndiv.eq.360) then
    r8 = rr8*1.8d2*3.6d3/pi
    call gag_cflab1 (ch, r8, nchar, 2)
  else
    r8 = rr8
10  r8 = r8+2.d0*pi
    if (r8.lt.0.d0) goto 10
    r8 = dmod(r8,2.d0*pi)*1.2d1*3.6d3/pi
    call gag_cflab1 (ch, r8, nchar, 3)
  endif
end subroutine sexag
!
subroutine deg2sexa(d8,ndiv,ch,ndig,left)
  use phys_const
  use gsys_interfaces, except_this=>deg2sexa
  !---------------------------------------------------------------------
  ! @ public
  !  Write an angle (degrees) in sexagesimal notation.
  !---------------------------------------------------------------------
  real(kind=8),     intent(in)           :: d8    ! [Deg] Angle
  integer(kind=4),  intent(in)           :: ndiv  ! [   ] Number of div. per turn (24/360)
  character(len=*), intent(out)          :: ch    ! [   ] Formatted string
  integer(kind=4),  intent(in), optional :: ndig  ! [   ] Number of digits desired
  logical,          intent(in), optional :: left  ! [   ] Left justify the output string?
  ! Local
  logical :: doleft
  !
  doleft = .false.  ! Default
  if (present(left))  doleft = left
  !
  if (present(ndig)) then
    call rad2sexa(d8*rad_per_deg,ndiv,ch,ndig,left=doleft)
  else
    call rad2sexa(d8*rad_per_deg,ndiv,ch,left=doleft)
  endif
  !
end subroutine deg2sexa
!
subroutine rad2sexa(rr8,ndiv,ch,ndig,left)
  use phys_const
  use gsys_interfaces, except_this=>rad2sexa
  !---------------------------------------------------------------------
  ! @ public
  !  Write an angle (radians) in sexagesimal notation.
  !  The number of digits in the fractional part is controled by 'ndig'.
  ! If absent, the string will be filled with as many digits as
  ! possible, for example if you want a 3 digits fractional part, use
  !  -DDD:MM:SS.SSS = 14 characters (360 divisions per turn)
  !  -HH:MM:SS.SSS = 13 characters (24 divisions per turn)
  !---------------------------------------------------------------------
  real(kind=8),     intent(in)           :: rr8   ! [Rad] Angle
  integer(kind=4),  intent(in)           :: ndiv  ! [   ] Number of div. per turn (24/360)
  character(len=*), intent(out)          :: ch    ! [   ] Formatted string
  integer(kind=4),  intent(in), optional :: ndig  ! [   ] Number of digits desired
  logical,          intent(in), optional :: left  ! [   ] Left justify the output string?
  ! Local
  integer(kind=4) :: nchar,ndigi
  real(kind=8) :: r8
  !
  ch = ' '
  nchar = len(ch)
  if (present(ndig)) then
    ndigi = ndig
  else
    if (ndiv.eq.360) then
      ndigi = nchar-11  ! "-DDD:MM:SS." = 11 characters reserved before digits
    else
      ndigi = nchar-10  ! "-HH:MM:SS." = 10 characters reserved before digits
    endif
  endif
  !
  if (ndiv.eq.360) then
    ! Degrees
    r8 = rr8 * sec_per_rad
    call gag_cflab1(ch,r8,nchar,ndigi)
  else
    ! Hour angle
    r8 = rr8
    do while (r8.lt.0.d0)
      r8 = r8+2.d0*pi
    enddo
    r8 = mod(r8,2.d0*pi) * hang_per_rad*3.6d3
    call gag_cflab1(ch,r8,nchar,ndigi)
  endif
  !
  ! Historical default is right-justified by gag_cflab1
  if (present(left)) then
    if (left) then
      ch = adjustl(ch)
    endif
  endif
  !
end subroutine rad2sexa
!
subroutine deg2dms(r8,d,m,s)
  !---------------------------------------------------------------------
  ! @ public
  !  Split a floating point value in degreee-minute-seconds numerical
  ! values. No assumption on the input value unit.
  !---------------------------------------------------------------------
  real(kind=8),    intent(in)  :: r8
  integer(kind=4), intent(out) :: d
  integer(kind=4), intent(out) :: m
  real(kind=8),    intent(out) :: s
  ! Local
  real(kind=8) :: v
  !
  v = abs(r8)
  !
  ! Degree
  d = floor(v)
  v = (v-d)*60.d0
  !
  ! Minute
  m  = floor(v)
  !
  ! Seconds
  s = (v-m)*60.d0
  !
  if (r8.lt.0.d0) then
    d = -d
    m = -m
    s = -s
  endif
  !
end subroutine deg2dms
!
subroutine gag_cflab (chrstr,x,w,d)
  !---------------------------------------------------------------------
  ! @ private
  !  Convert floating point value to a display of the form of the
  ! "Babylonian" ddd mm ss.s, where each field represents a sexagesimal
  ! increment over its successor. The value X must be in the units of
  ! the rightmost field.  For instance, X must be in seconds of time for
  ! hours, minutes, seconds display.
  !---------------------------------------------------------------------
  character(len=*), intent(out)   :: chrstr  ! Formatted string
  real(kind=8),     intent(in)    :: x       ! Input number
  integer(kind=4),  intent(inout) :: w       ! Length of string
  integer(kind=4),  intent(in)    :: d       ! Number of decimals
  ! Local
  real(kind=8) :: y
  integer(kind=4) :: h, m, s
  integer(kind=4) :: lh, lm, ls, dd
  integer(kind=8) :: f,fd
  character(len=20) :: th
  character(len=30) :: ts  ! Seconds+fractional part: arbitrary long
  character(len=2) :: tm
  logical :: short
  character(len=20) :: forma
  !
  short = .true.
  goto 1
  !
entry gag_cflab1 (chrstr, x, w, d)
  short = .false.
  !
1 y = abs (x)
  ! Hour
  h = y
  h = h / 3600
  y = y - (3600*h)
  ! Minute
  m = y
  m = m / 60
  y = y - (60*m)
  ! Second
  s = y
  y = y - s
  ! Rounding of the fractional part. This technique is limited to the 18 decimal
  ! digits stored in an I*8 for the fractional part (beyond 18, 'fd' overflows).
  ! Not a big problem since this is much further than the input R*8 precision.
  dd = min(max(0,d),18)
  fd = 10_8**dd
  f = fd*y + 0.5d0
  if (f .ge. fd) then
    f = f - fd
    s = s + 1
  endif
  if (s .gt. 59) then
    s = 0
    m = m + 1
  endif
  if (m .gt. 59) then
    m = 0
    h = h + 1
  endif
  if (x .lt. 0.d0) h = -h
  write(ts,'(I2.2,A1)') s,'.'
  if (dd.eq.0) then
    dd = -1
  else
    write(forma,'(A,I0,A,I0,A)')  '(I',dd,'.',dd,')'
    write(ts(4:3+dd),forma) f
  endif
  ls = dd+3
  !
  write(tm,'(I2.2)') m
  lm = 2
  !
  if ((h .eq. 0) .and. (x .ge. 0.d0)) then
    th = '00'
    lh = 2
  elseif ((h .eq. 0) .and. (x .lt. 0.d0)) then
    th = '-00'
    lh = 3
  else
    lh = alog10 (1.0 * abs(h) + .0001) + 1
    if (lh .eq. 1) lh = lh + 1 ! LH at least 2
    if (h .lt. 0) then
      lh = lh + 1              ! Allow for sign
      if (lh.eq.2) then
        write(th,132) h
      elseif (lh.eq.3) then
        write(th,133) h
      elseif (lh.eq.4) then
        write(th,134) h
      else
        write(th,120) h
      endif
    else
      if (lh.eq.2) then
        write(th,122) h
      elseif (lh.eq.3) then
        write(th,123) h
      elseif (lh.eq.4) then
        write(th,124) h
      else
        write(th,120) h
      endif
    endif
  endif
  !
  ! Short left justified format
  if (short) then
    chrstr(1:lh) = th
    chrstr(lh+1:lh+1) = ' '
    chrstr(lh+2:lh+3) = tm
    chrstr(lh+4:lh+4) = ' '
    chrstr(lh+5:w) = ts
    w = lh+lm+ls+2
  else
    !
    ! Long right justified format
    if (w .ge. lh+lm+ls+2) then
      chrstr (1:w-ls-lh-4) = ' '
      chrstr (w-ls-4-lh+1 : w-ls-4) = th
      chrstr (w-ls-3      : w-ls-3) = ':'
      chrstr (w-ls-2      : w-ls-1) = tm
      chrstr (w-ls        : w-ls)   = ':'
      chrstr (w-ls+1      : w)      = ts
    elseif (w .ge. lh+lm+1) then
      chrstr (1:w-3-lh) = ' '
      chrstr (w-3-lh+1 : w-3) = th
      chrstr (w-2      : w-2) = ':'
      chrstr (w-1      : w)   = tm
    elseif (w .ge. lh) then
      chrstr (1:w-lh) = ' '
      chrstr (w-lh+1 : w) = th
    else
      chrstr(1:w) = '*************'
    endif
  endif
  !
120 format (i10)
122 format (i2.2)
123 format (i3.2)
124 format (i4.2)
  !
132 format (i2.1)
133 format (i3.2)
134 format (i4.3)
end subroutine gag_cflab
