" date.vim " @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim]) " @Website: http://www.vim.org/account/profile.php?user_id=4037 " @License: GPL (see http://www.gnu.org/licenses/gpl.txt) " @Created: 2010-03-25. " @Last Change: 2017-09-06. " @Revision: 44.0.34 if !exists('g:tlib#date#ShortDatePrefix') | let g:tlib#date#ShortDatePrefix = '20' | endif "{{{2 if !exists('g:tlib#date#TimeZoneShift') | let g:tlib#date#TimeZoneShift = 0 | endif "{{{2 let g:tlib#date#dayshift = 60 * 60 * 24 " let g:tlib#date#date_rx = '\<\(\d\{4}\)-\(\d\d\)-\(\d\d\)\%(\s\+\(\(\d\d\):\(\d\d\)\)\)\?\>' let g:tlib#date#date_rx = '\<\(\d\{4}\)-\(\d\d\)-\(\d\d\)\>' let g:tlib#date#date_format = '%Y-%m-%d' function! tlib#date#IsDate(text) abort "{{{3 return a:text =~# '^'. g:tlib#date#date_rx .'$' && \ !empty(tlib#date#Parse(a:text, 0, 1)) endf function! tlib#date#Format(...) abort "{{{3 let secs1970 = a:0 >= 1 ? a:1 : localtime() return strftime(g:tlib#date#date_format, secs1970) endf " :display: tlib#date#DiffInDays(date1, ?date2=localtime(), ?allow_zero=0) function! tlib#date#DiffInDays(date, ...) let allow_zero = a:0 >= 2 ? a:2 : 0 let s0 = tlib#date#SecondsSince1970(a:date, 0, allow_zero) let s1 = a:0 >= 1 ? tlib#date#SecondsSince1970(a:1, 0, allow_zero) : localtime() let dd = (s0 - s1) / g:tlib#date#dayshift " TLogVAR dd return dd endf " :display: tlib#date#Parse(date, ?allow_zero=0, ?silent=0) "{{{3 function! tlib#date#Parse(date, ...) "{{{3 let min = a:0 >= 1 && a:1 ? 0 : 1 let silent = a:0 >= 2 ? a:2 : 0 Tlibtype 'tlib', a:date, min, silent let m = matchlist(a:date, '^\(\d\{2}\|\d\{4}\)-\(\d\{1,2}\)-\(\d\{1,2}\)$') Tlibtype 'tlib', m let year = '' let month = '' let days = '' if !empty(m) let year = m[1] let month = m[2] let days = m[3] else let m = matchlist(a:date, '^\(\d\+\)/\(\d\{1,2}\)/\(\d\{1,2}\)$') if !empty(m) let year = m[1] let month = m[3] let days = m[2] else let m = matchlist(a:date, '^\(\d\{1,2}\)\.\s*\(\d\{1,2}\)\.\s*\(\d\d\{2}\|\d\{4}\)$') if !empty(m) let year = m[3] let month = m[2] let days = m[1] endif endif endif Tlibtype 'tlib', year, month, days if empty(m) || year == '' || month == '' || days == '' || \ month < min || month > 12 || days < min || days > 31 if !silent echoerr 'TLib: Invalid date: '. a:date endif return [] endif if strlen(year) == 2 let year = g:tlib#date#ShortDatePrefix . year Tlibtype 'tlib', year endif return [0 + year, 0 + month, 0 + days] endf " tlib#date#SecondsSince1970(date, ?daysshift=0, ?allow_zero=0) function! tlib#date#SecondsSince1970(date, ...) "{{{3 let allow_zero = a:0 >= 2 ? a:2 : 0 " TLogVAR a:date, allow_zero let date = tlib#date#Parse(a:date, allow_zero) if empty(date) return 0 endif let [year, month, days] = date if a:0 >= 1 && a:1 > 0 let days = days + a:1 end let days_passed = days let i = 1970 while i < year let days_passed = days_passed + 365 if i % 4 == 0 || i == 2000 let days_passed = days_passed + 1 endif let i = i + 1 endwh let i = 1 while i < month if i == 1 let days_passed = days_passed + 31 elseif i == 2 let days_passed = days_passed + 28 if year % 4 == 0 || year == 2000 let days_passed = days_passed + 1 endif elseif i == 3 let days_passed = days_passed + 31 elseif i == 4 let days_passed = days_passed + 30 elseif i == 5 let days_passed = days_passed + 31 elseif i == 6 let days_passed = days_passed + 30 elseif i == 7 let days_passed = days_passed + 31 elseif i == 8 let days_passed = days_passed + 31 elseif i == 9 let days_passed = days_passed + 30 elseif i == 10 let days_passed = days_passed + 31 elseif i == 11 let days_passed = days_passed + 30 endif let i = i + 1 endwh let seconds = (days_passed - 1) * 24 * 60 * 60 let seconds = seconds + (strftime('%H') + g:tlib#date#TimeZoneShift) * 60 * 60 let seconds = seconds + strftime('%M') * 60 let seconds = seconds + strftime('%S') return seconds endf function! tlib#date#Shift(date, shift) abort "{{{3 let n = str2nr(matchstr(a:shift, '\d\+')) let ml = matchlist(a:date, g:tlib#date#date_rx) " TLogVAR a:date, a:shift, n, ml if a:shift =~ 'd$' let date = tlib#date#AddDays(a:date, n) elseif a:shift =~ 'b$' let n1 = n let secs = tlib#date#SecondsSince1970(a:date) while n1 > 0 let n1 -= 1 let secs += g:tlib#date#dayshift let uday = strftime('%u', secs) if uday == 6 let secs += g:tlib#date#dayshift * 2 elseif uday == 7 let secs += g:tlib#date#dayshift endif endwh let date = tlib#date#Format(secs) elseif a:shift =~ 'w$' let date = tlib#date#AddDays(a:date, n * 7) elseif a:shift =~ 'm$' let d = str2nr(ml[3]) let ms = str2nr(ml[2]) + n let m = (ms - 1) % 12 + 1 let yr = str2nr(ml[1]) + (ms - 1) / 12 let date = printf('%04d-%02d-%02d', yr, m, d) " TLogVAR d, ms, m, yr, date elseif a:shift =~ 'y$' let yr = str2nr(ml[1]) + n let date = substitute(a:date, '^\d\{4}', yr, '') else throw 'tlib#date#Shift: Unsupported arguments: '. string(a:shift) endif " if !empty(ml[4]) && date !~ '\s'. ml[4] .'$' " let date .= ' '. ml[4] " endif " TLogVAR date return date endf function! tlib#date#AddDays(date, n) abort "{{{3 let secs = tlib#date#SecondsSince1970(a:date) + g:tlib#date#dayshift * a:n " TLogVAR secs let date = tlib#date#Format(secs) return date endf