1
0
mirror of https://github.com/SpaceVim/SpaceVim.git synced 2025-02-03 11:50:05 +08:00
SpaceVim/bundle/calendar.vim/autoload/calendar/time.vim
2022-05-28 15:29:51 +08:00

242 lines
6.0 KiB
VimL
Vendored

" =============================================================================
" Filename: autoload/calendar/time.vim
" Author: itchyny
" License: MIT License
" Last Change: 2017/05/08 07:45:01.
" =============================================================================
let s:save_cpo = &cpo
set cpo&vim
" Time object
" h: hour
" m: minute
" s: second
function! calendar#time#new(h, m, s) abort
return extend(copy(s:self), { 'h': a:h, 'm': a:m, 's': a:s })
endfunction
if exists('*strftime')
function! calendar#time#now() abort
return calendar#time#new(strftime('%H') * 1, strftime('%M') * 1, strftime('%S') * 1)
endfunction
else
function! calendar#time#now() abort
return calendar#time#new(system('date "+%H"') * 1, system('date "+%M"') * 1, system('date "+%S"') * 1)
endfunction
endif
function! calendar#time#hour12(h) abort
return a:h == 0 ? 12 : a:h < 13 ? a:h : a:h - 12
endfunction
let s:time_zone_cache = {}
function! calendar#time#time_zone() abort
let time_zone = calendar#setting#get('time_zone')
if has_key(s:time_zone_cache, time_zone)
return s:time_zone_cache[time_zone]
endif
if time_zone ==# ''
return 0
endif
let str = time_zone
let sign_str = str[0] ==# '-' ? '-' : str[0] ==# '+' ? '+' : ''
let str = str[len(sign_str):]
let d = matchstr(str, '^\d\+')
let str = str[len(d):]
let [ h, m, s ] = [ 0, 0, 0 ]
let onlyhour = 0
if len(d) == 1 || len(d) == 2
let h = d + 0
let onlyhour = 1
elseif len(d) == 3
let h = d[0] + 0
let m = d[1:] + 0
elseif len(d) == 4
let h = d[:1] + 0
let m = d[2:] + 0
elseif len(d) >= 5
let h = d[:1] + 0
let m = d[2:] + 0
let s = d[4:] + 0
endif
let str = substitute(str, '^[^[:digit:]]\+', '', 'g')
let d = matchstr(str, '^\d\+')
let str = str[len(d):]
if len(d) == 1 || len(d) == 2
if onlyhour
let m = d + 0
else
let s = d + 0
endif
elseif len(d) == 3
if onlyhour
let m = d[0] + 0
let s = d[1:] + 0
else
let s = d + 0
endif
elseif len(d) == 4
if onlyhour
let m = d[:1] + 0
let s = d[2:] + 0
else
let s = d + 0
endif
endif
let str = substitute(str, '^[^[:digit:]]\+', '', 'g')
let d = matchstr(str, '^\d\+')
if len(d)
let s = d + 0
endif
let s:time_zone_cache[time_zone] = (sign_str ==# '-' ? -1 : 1) * (((h * 60) + m) * 60 + s)
return s:time_zone_cache[time_zone]
endfunction
let s:time_cache = {}
function! calendar#time#parse(str) abort
if a:str ==# ''
return 0
endif
if has_key(s:time_cache, a:str)
return s:time_cache[a:str]
endif
let [ h, m, s ] = [ 0, 0, 0 ]
let timestr = matchstr(a:str, '^\d\+:\d\+\%(:\d\+\)\?')
let str = a:str[len(timestr):]
let hms = map(split(timestr, ':'), 'v:val + 0')
if len(hms) == 3
let [ h, m, s ] = hms
elseif len(hms) == 2
let [ h, m ] = hms
endif
let time = ((h * 60) + m) * 60 + s
if str ==? 'Z'
let s:time_cache[a:str] = time
return s:time_cache[a:str]
endif
if str ==# ''
let s:time_cache[a:str] = time - calendar#time#time_zone()
return s:time_cache[a:str]
endif
if has_key(s:time_cache, str)
let [ dh, dm, ds ] = s:time_cache[str]
else
let [ dh, dm, ds ] = [ 0, 0, 0 ]
let timestr = matchstr(str, '-\?\d\+:\d\+\%(:\d\+\)\?')
let hms = map(split(timestr, ':'), 'v:val + 0')
if len(hms) == 3
let [ dh, dm, ds ] = hms
elseif len(hms) == 2
let [ dh, dm ] = hms
endif
let s:time_cache[str] = [ dh, dm, ds ]
endif
let s:time_cache[a:str] = time - (((dh * 60) + dm) * 60 + ds)
return s:time_cache[a:str]
endfunction
let s:datetime_cache = {}
function! calendar#time#datetime(str) abort
let time_zone = calendar#time#time_zone()
let key = a:str . ',' . time_zone
if has_key(s:datetime_cache, key)
return s:datetime_cache[key]
endif
let time = a:str =~# 'T' ? calendar#time#parse(matchstr(a:str, 'T\zs.*')) + time_zone : 0
let ymd = map(split(matchstr(a:str, '\d\+-\d\+-\d\+'), '-'), 'v:val + 0')
if len(ymd) != 3
return []
endif
let [ y, m, d ] = ymd
let min = s:div(time, 60)
let sec = time - 60 * min
let hour = s:div(min, 60)
let min -= 60 * hour
let day = s:div(hour, 24)
let hour -= 24 * day
if day != 0
let [ y, m, d ] = calendar#day#new(y, m, d).add(day).get_ymd()
endif
let s:datetime_cache[key] = [ y, m, d, hour, min, sec ]
return s:datetime_cache[key]
endfunction
let s:self = {}
function! s:div(x, y) abort
return a:x/a:y-((a:x<0)&&(a:x%a:y))
endfunction
function! s:self.new(h, m, s) dict abort
return calendar#time#new(a:h, a:m, a:s)
endfunction
function! s:self.get_hms() dict abort
return [self.h, self.m, self.s]
endfunction
function! s:self.add_hour(diff) dict abort
let [h, m, s] = self.get_hms()
let d = 0
let h += a:diff
let d += s:div(h, 24)
let h -= 24 * s:div(h, 24)
return [d, self.new(h, m, s)]
endfunction
function! s:self.add_minute(diff) dict abort
let [h, m, s] = self.get_hms()
let d = 0
let m += a:diff
let h += s:div(m, 60)
let m -= 60 * s:div(m, 60)
let d += s:div(h, 24)
let h -= 24 * s:div(h, 24)
return [d, self.new(h, m, s)]
endfunction
function! s:self.add_second(diff) dict abort
let [h, m, s] = self.get_hms()
let d = 0
let s += a:diff
let m += s:div(s, 60)
let s -= 60 * s:div(s, 60)
let h += s:div(m, 60)
let m -= 60 * s:div(m, 60)
let d += s:div(h, 24)
let h -= 24 * s:div(h, 24)
return [d, self.new(h, m, s)]
endfunction
function! s:self.second() dict abort
return self.get_hms()[2]
endfunction
function! s:self.minute() dict abort
return self.get_hms()[1]
endfunction
function! s:self.hour() dict abort
return self.get_hms()[0]
endfunction
function! s:self.seconds() dict abort
return (self.hour() * 60 + self.minute()) * 60 + self.second()
endfunction
function! s:self.add(time) dict abort
return self.add_second(a:time.seconds())
endfunction
function! s:self.subtract(time) dict abort
return self.add_second(-a:time.seconds())
endfunction
function! s:self.sub(time) dict abort
return self.seconds() - a:time.seconds()
endfunction
let &cpo = s:save_cpo
unlet s:save_cpo