!== dc_date_types#DC_DATETIME, dc_date_types#DC_DIFFTIME åž‹å¤‰æ•°ã®æ–‡å—å¤‰æ›
!
! Authors::   Yasuhiro MORIKAWA
! Version::   $Id: dcdatetimetochar.f90,v 1.2 2009-05-25 10:01:34 morikawa Exp $
! Tag Name::  $Name:  $
! Copyright:: Copyright (C) GFD Dennou Club, 2006-. All rights reserved.
! License::   See COPYRIGHT[link:../../COPYRIGHT]
!
! ã“ã®ãƒ•ã‚¡ã‚¤ãƒ«ã§æä¾›ã•ã‚Œã‚‹æ‰‹ç¶šãç¾¤ã¯ dc_date ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ã«ã¦æä¾›ã•ã‚Œã¾ã™ã€‚
!

function DCDateTimeToChar(time) result(result)
  !
  ! dc_date_types#DC_DATETIME åž‹å¤‰æ•°ã‚’æ–‡å—åž‹å¤‰æ•°ã¸å¤‰æ›ã—ã¦è¿”ã—ã¾ã™.
  ! æ›¸å¼ã¯ä¸‹è¨˜ã®ã‚ˆã†ã« JIS X 0301 ã®å®Œå…¨è¡¨è¨˜ã§ã™.
  !
  !   YYYY-MM-DDThh:mm:ss.sTZD
  !
  ! YYYY ã¯å¹´, MM ã¯æœˆ, DD ã¯æ—¥, hh ã¯æ™‚, mm ã¯åˆ†, ss.s ã¯ç§’,
  ! TZD ã¯ã‚¿ã‚¤ãƒ ã‚¾ãƒ¼ãƒ³ã‚’è¡¨ã—ã¾ã™.
  !
  use dc_types, only: STRING, TOKEN, DP
  use dc_string, only: toChar, CPrintf, StoA
  use dc_date_generic, only: Eval
  use dc_date_types, only: DC_DATETIME, &
    & MIN_SECONDS, HOUR_SECONDS, YEAR_MONTHS
  use dc_message, only: MessageNotify
  implicit none
  character(STRING):: result
  type(DC_DATETIME), intent(in):: time

  integer :: year, mon, day, hour, min, csec_len
  real(DP):: sec
  character(TOKEN) :: zone, csec
continue

  call Eval(time, &
    & year=year, mon=mon, day=day, hour=hour, min=min, sec=sec, zone=zone)

  csec = toChar(sec)
  if ( trim(csec) == '-0.' ) csec = '0.'
  do while ( index('123456789.', csec(len_trim(csec):len_trim(csec)) ) == 0 )
    if ( len_trim(csec) < 2 ) exit
    csec = csec(1:len_trim(csec)-1)
  end do
  if (int(sec) > -1 .and. int(sec) < 10)  csec = '0' // csec
  csec_len = len(trim(adjustl(csec)))
  if (csec(csec_len:csec_len) == '.') csec = csec(1:csec_len-1)

  result = CPrintf('%04d-%02d-%02dT%02d:%02d:%c%c', &
    & i=(/year, mon, day, hour, min/), &
    & c1=trim(csec), c2=trim(zone))

end function DCDateTimeToChar

function DCDiffTimeToChar(diff) result(result)
  !
  ! dc_date_types#DC_DIFFTIME åž‹å¤‰æ•°ã‚’æ–‡å—åž‹å¤‰æ•°ã¸å¤‰æ›ã—ã¦è¿”ã—ã¾ã™.
  ! æ›¸å¼ã¯ä»¥ä¸‹ã®ã‚ˆã†ã«ãªã‚Šã¾ã™.
  !
  !   +YYYY-MM-DDThh:mm:ss.s
  !   -YYYY-MM-DDThh:mm:ss.s
  !
  ! YYYY ã¯å¹´, MM ã¯æœˆ, DD ã¯æ—¥, hh ã¯æ™‚, mm ã¯åˆ†, ss.s ã¯ç§’ã‚’è¡¨ã—ã¾ã™.
  ! ãŸã ã—, DD ã¯ 2 æ¡ã‚’è¶…ãˆã‚‹å ´åˆãŒã‚ã‚Šã¾ã™.
  ! (dc_date_types#DC_DIFFTIME ã¯ X ãƒ¶æœˆå¾Œ, X æ—¥å‰, ãªã©ã‚’è¡¨ç¾ã™ã‚‹ãŸã‚
  ! ã®ãƒ‡ãƒ¼ã‚¿åž‹ãªã®ã§, æ—¥ã‚’æœˆã«ç¹°ã‚Šä¸Šã’ãŸã‚Š, æœˆã‚’æ—¥ã«ç¹°ã‚Šä¸‹ã’ã‚‹ã“ã¨ã‚’
  ! ã—ã¾ã›ã‚“. ã¾ãŸã€Œå¹´ã€ã®æƒ…å ±ã‚‚æŒã¡ã¾ã›ã‚“. 1 å¹´ã®æ—¥æ•°ã‚„ 1 æœˆã®æ—¥æ•°ã¯
  ! dc_date_types#DC_DATETIME å´ã§æ±ºã¾ã‚Šã¾ã™).
  !
  ! ãªãŠ, DCDiffTimeCreate ã«ãŠã„ã¦, å˜ä½ã‚’ '1' ã¨ã—ãŸå ´åˆã¯ç„¡æ™‚é™æ™‚é–“ã¨
  ! æ‰±ã†ãŸã‚, ä»¥ä¸‹ã®ã‚ˆã†ãªæ›¸å¼ã¨ãªã‚Šã¾ã™.
  !
  !   ss.s
  !
  use dc_types, only: STRING, TOKEN, DP
  use dc_string, only: toChar, CPrintf, StoA
  use dc_date_generic, only: Eval
  use dc_date_types, only: DC_DIFFTIME
  use dc_scaledsec, only: assignment(=)
  implicit none
  character(STRING):: result
  type(DC_DIFFTIME), intent(in):: diff

  integer :: year, mon, day, hour, min, csec_len
  real(DP):: sec
  character(TOKEN) :: csec
  character(1) :: pm
continue

  if ( .not. diff % nondim_flag ) then
    call Eval(diff, year=year, mon=mon, day=day, hour=hour, min=min, sec=sec)

    if ( year < 0 .or. mon < 0 .or. day < 0 .or.  &
      &  hour < 0 .or. min < 0 .or. sec < 0         ) then
      year=abs(year) ; mon=abs(mon) ; day=abs(day)
      hour=abs(hour) ; min=abs(min) ; sec=abs(sec)
      pm = '-'
    else
      pm = '+'
    end if

    csec = toChar(sec)
    if ( trim(csec) == '-0.' ) csec = '0.'
    do while ( index('123456789.', csec(len_trim(csec):len_trim(csec)) ) == 0 )
      if ( len_trim(csec) < 2 ) exit
      csec = csec(1:len_trim(csec)-1)
    end do
    if (int(sec) > -1 .and. int(sec) < 10)  csec = '0' // csec
    csec_len = len(trim(adjustl(csec)))
    if (csec(csec_len:csec_len) == '.') csec = csec(1:csec_len-1)

    result = CPrintf('%c%04d-%02d-%02dT%02d:%02d:%c', &
      & i=(/year, mon, day, hour, min/), &
      & c1=pm, c2=trim(csec))
  else
    sec = diff % sec
    result = toChar( sec )
  end if

end function DCDiffTimeToChar

function DCDateTimeToCharCal(time, upcase) result(result)
  !
  ! dc_date_types#DC_DATETIME åž‹å¤‰æ•°ã®æš¦ã‚’æ–‡å—åž‹ã«ã—ã¦è¿”ã—ã¾ã™.
  ! ç¾åœ¨ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã‚‹æš¦ã¯ä»¥ä¸‹ã®é€šã‚Šã§ã™.
  ! å·¦ãŒæš¦ã‚’ç¤ºã™æ•´æ•°åž‹å¤‰æ•°, å³ãŒè¿”ã‚‹æ–‡å—åˆ—ã§ã™.
  ! *upcase* ã« .true. ã‚’ä¸ŽãˆãŸå ´åˆã«ã¯, å¤§æ–‡å—ã¨ãªã£ã¦è¿”ã‚Šã¾ã™.
  !
  ! dc_date_types#CAL_CYCLIC    :: cyclic
  ! dc_date_types#CAL_NOLEAP    :: noleap
  ! dc_date_types#CAL_JULIAN    :: julian
  ! dc_date_types#CAL_GREGORIAN :: gregorian
  !
  !
  use dc_types, only: TOKEN
  use dc_present, only: present_and_true
  use dc_date_types, only: DC_DATETIME, &
    & CAL_CYCLIC, CAL_NOLEAP, CAL_JULIAN, CAL_GREGORIAN
  use dc_string, only: toUpper
  character(TOKEN) :: result
  type(DC_DATETIME), intent(in):: time
  logical, intent(in), optional:: upcase
continue
  select case( time % caltype )
  case(CAL_CYCLIC)
    result = 'cyclic'
  case(CAL_NOLEAP)
    result = 'noleap'
  case(CAL_JULIAN)
    result = 'julian'
  case(CAL_GREGORIAN)
    result = 'gregorian'
  case default
    result = 'none'
  end select

  if ( present_and_true(upcase) ) then
    call toUpper(result) ! (inout)
  end if

end function DCDateTimeToCharCal