67 howm-mode.vim (2-35) HowmDateTime2Int() の作成

「では、こちらに30分煮込んだものが〜」

ということで、いきなりだけど HowmDateTime2Int() を作った。以前からぼそぼそ言ってた文字列から日付をあらわす数値への変換。タイムゾーンまわりとかかなり適当。howm_timezone_hour, howm_timezone_min でタイムゾーンに関する修正を行う。でかいわりにやってることはちっちゃい。正規表現でひっぱりだして正しいか確認して足してるだけ。肝心な数値変換の部分は HowmDate2Int() で使われている、既存のものを利用しているので、そちらが正しく動いていればうまく動くはず。

" 注意: HowmDate2Int() とは基準日時も返り値の種類も違う
"
" format にしたがって書かれた日付 date を解釈し ( TimeZone を考慮する ),
" 1970-01-01 00:00:00 からの経過秒数を返す.
" 1970-01-01 00:00:00 以前や,
" 2038-01-01 00:00:00 以降のデータの場合は -1 を返す.
" その他, 解釈できなかった場合も -1 を返す.
" 既定値: 年:1970, 月:1, 日:1, 時:0, 分:0, 秒:0, TimeZone:+09:00
function! HowmDateTime2Int(datetime, format)
  " TimeZone の設定
  if !exists('g:howm_timezone_hour') ||
        \ g:howm_timezone_hour < -12 || 13 < g:howm_timezone_hour
    let tz_hour = 9
  endif
  if !exists('g:howm_timezone_min') ||
        \ g:howm_timezone_min < 0 || 59 < g:howm_timezone_min
    let tz_min = 0
  endif

  let format = '\V' . escape(a:format, '\')
  let format = substitute(format, '\C%F', escape('%Y-%m-%d', '\~&'), 'g')
  let format = substitute(format, '\C%T', escape('%H:%M:%S', '\~&'), 'g')
  let format = substitute(format, '\C%R', escape('%H:%M', '\~&'), 'g')

  let pat = format
  let pat = substitute(pat, '\C%Y', escape('\m\d\{4}\V', '\~&'), 'g')
  let pat = substitute(pat, '\C%m', escape('\m\d\{2}\V', '\~&'), 'g')
  let pat = substitute(pat, '\C%d', escape('\m\d\{2}\V', '\~&'), 'g')
  let pat = substitute(pat, '\C%H', escape('\m\d\{2}\V', '\~&'), 'g')
  let pat = substitute(pat, '\C%M', escape('\m\d\{2}\V', '\~&'), 'g')
  let pat = substitute(pat, '\C%S', escape('\m\d\{2}\V', '\~&'), 'g')
  if a:datetime !~ pat | return -1 | endif
  let date_pat = pat

  " %Y
  if format !~# '%Y'
    let year = 1970
  else
    let pat = format
    let pat = substitute(pat, '\C%Y', escape('\m\(\d\{4}\)\V', '\~&'), 'g')
    let pat = substitute(pat, '\C%m', escape('\m\d\{2}\V', '\~&'), 'g')
    let pat = substitute(pat, '\C%d', escape('\m\d\{2}\V', '\~&'), 'g')
    let pat = substitute(pat, '\C%H', escape('\m\d\{2}\V', '\~&'), 'g')
    let pat = substitute(pat, '\C%M', escape('\m\d\{2}\V', '\~&'), 'g')
    let pat = substitute(pat, '\C%S', escape('\m\d\{2}\V', '\~&'), 'g')
    let year = substitute(a:datetime, pat, '\1', 'g') + 0
    if year < 1970 || 2038 <= year | return -1 | endif
  endif
  " ec 'year: ' . year

  " %m
  if format !~# '%m'
    let month = 1
  else
    let pat = format
    let pat = substitute(pat, '\C%Y', escape('\m\d\{4}\V', '\~&'), 'g')
    let pat = substitute(pat, '\C%m', escape('\m\(\d\{2}\)\V', '\~&'), 'g')
    let pat = substitute(pat, '\C%d', escape('\m\d\{2}\V', '\~&'), 'g')
    let pat = substitute(pat, '\C%H', escape('\m\d\{2}\V', '\~&'), 'g')
    let pat = substitute(pat, '\C%M', escape('\m\d\{2}\V', '\~&'), 'g')
    let pat = substitute(pat, '\C%S', escape('\m\d\{2}\V', '\~&'), 'g')
    let month = substitute(a:datetime, pat, '\1', 'g') + 0
    if month < 1 || 12 < month | return -1 | endif
  endif
  " ec 'month: ' . month

  " %d
  if format !~# '%d'
    let day = 1
  else
    let pat = format
    let pat = substitute(pat, '\C%Y', escape('\m\d\{4}\V', '\~&'), 'g')
    let pat = substitute(pat, '\C%m', escape('\m\d\{2}\V', '\~&'), 'g')
    let pat = substitute(pat, '\C%d', escape('\m\(\d\{2}\)\V', '\~&'), 'g')
    let pat = substitute(pat, '\C%H', escape('\m\d\{2}\V', '\~&'), 'g')
    let pat = substitute(pat, '\C%M', escape('\m\d\{2}\V', '\~&'), 'g')
    let pat = substitute(pat, '\C%S', escape('\m\d\{2}\V', '\~&'), 'g')
    let day = substitute(a:datetime, pat, '\1', 'g') + 0
    if day < 1 || 31 < day | return -1 | endif
    if 28 < day
      if month =~ '^\%(\<2\|4\|6\|9\|11\)$' && 30 < day | return -1 | endif
      if month == '2'
        if (year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0))
          if 29 < day | return -1 | endif
        else
          if 28 < day | return -1 | endif
        endif
      endif
    endif
  endif
  " ec 'day: ' . day

  " %H
  if format !~# '%H'
    let hour = 0
  else
    let pat = format
    let pat = substitute(pat, '\C%Y', escape('\m\d\{4}\V', '\~&'), 'g')
    let pat = substitute(pat, '\C%m', escape('\m\d\{2}\V', '\~&'), 'g')
    let pat = substitute(pat, '\C%d', escape('\m\d\{2}\V', '\~&'), 'g')
    let pat = substitute(pat, '\C%H', escape('\m\(\d\{2}\)\V', '\~&'), 'g')
    let pat = substitute(pat, '\C%M', escape('\m\d\{2}\V', '\~&'), 'g')
    let pat = substitute(pat, '\C%S', escape('\m\d\{2}\V', '\~&'), 'g')
    let hour = substitute(a:datetime, pat, '\1', 'g') + 0
    if hour < 0 || 23 < hour | return -1 | endif
  endif
  " ec 'hour: ' . hour

  " %M
  if format !~# '%M'
    let min = 0
  else
    let pat = format
    let pat = substitute(pat, '\C%Y', escape('\m\d\{4}\V', '\~&'), 'g')
    let pat = substitute(pat, '\C%m', escape('\m\d\{2}\V', '\~&'), 'g')
    let pat = substitute(pat, '\C%d', escape('\m\d\{2}\V', '\~&'), 'g')
    let pat = substitute(pat, '\C%H', escape('\m\d\{2}\V', '\~&'), 'g')
    let pat = substitute(pat, '\C%M', escape('\m\(\d\{2}\)\V', '\~&'), 'g')
    let pat = substitute(pat, '\C%S', escape('\m\d\{2}\V', '\~&'), 'g')
    let min = substitute(a:datetime, pat, '\1', 'g') + 0
    if min < 0 || 59 < min | return -1 | endif
  endif
  " ec 'min: ' . min

  " %S
  if format !~# '%S'
    let sec = 0
  else
    let pat = format
    let pat = substitute(pat, '\C%Y', escape('\m\d\{4}\V', '\~&'), 'g')
    let pat = substitute(pat, '\C%m', escape('\m\d\{2}\V', '\~&'), 'g')
    let pat = substitute(pat, '\C%d', escape('\m\d\{2}\V', '\~&'), 'g')
    let pat = substitute(pat, '\C%H', escape('\m\d\{2}\V', '\~&'), 'g')
    let pat = substitute(pat, '\C%M', escape('\m\d\{2}\V', '\~&'), 'g')
    let pat = substitute(pat, '\C%S', escape('\m\(\d\{2}\)\V', '\~&'), 'g')
    let sec = substitute(a:datetime, pat, '\1', 'g') + 0
    if sec < 0 || 59 < sec | return -1 | endif
  endif
  " ec 'sec: ' . sec

  " 719527 : HowmDate2Int('1970-01-01', '%Y-%m-%d')
  "  86400 : 60 * 60 * 24
  let retval = (s:ymd2int(year, month, day) - s:ymd2int(1970, 1, 1)) * 86400
  if format =~# '%H' || format =~# '%M' || format =~# '%S'
    " TimeZone を考慮
    let retval = retval + hour * 60 * 60 - (tz_hour * 60 * 60)
    if tz_hour > 0
      let retval = retval + min * 60 + (tz_min * 60)
    else
      let retval = retval + min * 60 - (tz_min * 60)
    endif
  end
  let retval = retval + sec
  if retval < 0 | return -1 | endif
  " echo strftime('%Y-%m-%d %H:%M:%S', retval)

  return retval
endfunction