program date
  call test_dfmt
  call test1
  call test2
  call test3
end program

subroutine test_dfmt
  use n3fmt, only: dfmt_decimal
  implicit none
  character(2):: s = '00'
  integer:: j, i, p
  do, j = 0, 99
    write(unit=s, fmt="(i2.1)") j
    call dfmt_decimal(s, i, p)
    if (i /= j .or. p /= 3) then
      print *, 'j', j, 'i', i, 'p', p
      stop 16
    endif
  enddo
end subroutine

subroutine test3
  use n3date
  implicit none
  integer:: y0, m0, d0
  integer:: y, m, d, iseq
  logical:: mismatch
  print *, 'test3:'
  do, y0 = 5883, -2282, -1
    d0 = 1
    do, m0 = 1, 12
      call roundtrip
    enddo
    m0 = 12; d0 = 31
    call roundtrip
    !print *, '      ', y0, 'ok'
  enddo
  print *, 'test3 ok'
contains

  subroutine roundtrip
    100 format(' ',i5.4,2('-',i2.2),i5.4,2('-',i2.2),i12.0,' ',L1)
    call nwp_ymd2seq(y0, m0, d0, iseq)
    call nwp_seq2ymd(y, m, d, iseq)
    mismatch = (y /= y0 .or. m /= m0 .or. d /= d0)
    if (.not. mismatch) return
    print 100, y0, m0, d0, y, m, d, iseq, mismatch
    stop 16
  end subroutine

end subroutine

subroutine test2
  use n3date
  implicit none
  integer:: iseq, dum(6)
  call nwp_systime(dum(1), dum(2), dum(3), dum(4), dum(5), iseq)
  print *, 'system clock =', isotime(iseq)
  call nwp_ymd2seq(1801, 1, 1, iseq)
  if (iseq == 0) then
    print *, 'test2 ok'
  else
    print *, 'test2 ng: 1801-01-01T0000Z =', iseq
    stop 16
  endif
  call nwp_ymd2seq(2000, 3, 1, iseq)
  print *, 'origin (2000-03-01) = ', iseq
end subroutine

subroutine test1
  use n3date
  implicit none
  integer:: y, m, iseq, iseq2, days
  do, y = 5883, -2282, -1
    do, m = 1, 12
      call nwp_ymd2seq(y, m, 1, iseq)
      if ((y < 1700 .and. iseq > 0).or.(y > 1900 .and. iseq < 0)) then
        print *, iseq, y, m
        stop 16
      endif
      call nwp_ymd2seq(y, m + 1, 1, iseq2)
      days = (iseq2 - iseq) / 24 / 60
      if (days /= month_days(y, m)) goto 900
      !print *,  y, m, days
    enddo
  enddo
  print *, 'test1 ok'
  return
  900 continue
  print *, 'wrong length month', y, m, days
  stop 16
contains

  integer function month_days(y, m) result(result)
    integer, intent(in):: y, m
    select case(m)
    case (4, 6, 9, 11)
      result = 30
    case (2)
      if (modulo(y, 4) /= 0) then
        result = 28
      else
        if (modulo(y, 100) /= 0) then
          result = 29
        else
          if (modulo(y, 400) /= 0) then
            result = 28
          else
            result = 29
          endif
        endif
      endif
    case default
      result = 31
    end select
  end function

end subroutine

