" ___vital___ " NOTE: lines between '" ___vital___' is generated by :Vitalize. " Do not modify the code nor insert new lines before '" ___vital___' function! s:_SID() abort return matchstr(expand(''), '\zs\d\+\ze__SID$') endfunction execute join(['function! vital#_gina#DateTime#import() abort', printf("return map({'now': '', '_vital_depends': '', 'from_julian_day': '', 'from_format': '', 'am_pm_names': '', 'delta': '', 'from_unix_time': '', 'month_names': '', 'is_leap_year': '', 'compare': '', 'weekday_names': '', 'from_date': '', 'timezone': '', '_vital_loaded': ''}, \"vital#_gina#function('%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n") delfunction s:_SID " ___vital___ " date and time library. let s:save_cpo = &cpo set cpo&vim function! s:_vital_loaded(V) abort let s:V = a:V let s:Prelude = s:V.import('Prelude') let s:Process = s:V.import('Process') let s:Bitwise = s:V.import('Bitwise') let s:NUM_SECONDS = 60 let s:NUM_MINUTES = 60 let s:NUM_HOURS = 24 let s:NUM_DAYS_OF_WEEK = 7 let s:NUM_MONTHS = 12 let s:SECONDS_OF_HOUR = s:NUM_SECONDS * s:NUM_MINUTES let s:SECONDS_OF_DAY = s:SECONDS_OF_HOUR * s:NUM_HOURS let s:ERA_TIME = s:_g2jd(1, 1, 1) let s:EPOC_TIME = s:_g2jd(1970, 1, 1) let s:MONTHS = map(range(1, 12), \ 's:from_date(1970, v:val, 1, 0, 0, 0, 0).unix_time()') let s:WEEKS = map(range(4, 10), \ 's:from_date(1970, 1, v:val, 0, 0, 0, 0).unix_time()') let s:AM_PM_TIMES = map([0, 12], \ 's:from_date(1970, 1, 1, v:val, 0, 0, 0).unix_time()') " default values call extend(s:DateTime, { \ '_year': 0, \ '_month': 1, \ '_day': 1, \ '_hour': 0, \ '_minute': 0, \ '_second': 0, \ '_timezone': s:timezone(), \ }) call extend(s:TimeDelta, { \ '_days': 0, \ '_seconds': 0, \ }) let s:tz_default_offset = s:timezone().offset() endfunction function! s:_vital_depends() abort return ['Prelude', 'Process', 'Bitwise'] endfunction " Creates a DateTime object with current time from system. function! s:now(...) abort let now = s:from_unix_time(localtime()) if a:0 let now = now.to(s:timezone(a:1)) endif return now endfunction " Creates a DateTime object from given unix time. function! s:from_unix_time(unix_time, ...) abort let tz = call('s:timezone', a:000) return call('s:from_date', \ map(split(strftime('%Y %m %d %H %M %S', a:unix_time)), \ 'str2nr(v:val, 10)')).to(tz) endfunction " Creates a DateTime object from given date and time. " @param year = 1970 " @param month = 1 " @param day = 1 " @param hour = 0 " @param minute = 0 " @param second = 0 " @param timezone = '' function! s:from_date(...) abort let o = copy(s:DateTime) let [o._year, o._month, o._day, o._hour, o._minute, o._second, tz] = \ a:000 + [1970, 1, 1, 0, 0, 0, ''][a:0 :] let o._timezone = s:timezone(tz) return o._normalize() endfunction " Creates a DateTime object from format. function! s:from_format(string, format, ...) abort let o = copy(s:DateTime) let locale = a:0 ? a:1 : '' let remain = a:string let skip_pattern = '' for f in s:_split_format(a:format) if s:Prelude.is_string(f) let pat = '^' . skip_pattern . '\V' . escape(f, '\') let matched_len = len(matchstr(remain, pat)) if matched_len == 0 throw join([ \ 'vital: DateTime: Parse error:', \ 'input: ' . a:string, \ 'format: ' . a:format, \ ], "\n") endif let remain = remain[matched_len :] else " if s:Prelude.is_list(f) let info = f[0] if info[0] ==# '#skip' let skip_pattern = info[1] else let remain = s:_read_format(o, f, remain, skip_pattern, locale) let skip_pattern = '' endif endif unlet f endfor return o._normalize() endfunction " @vimlint(EVL102, 1, l:locale) function! s:_read_format(datetime, descriptor, remain, skip_pattern, locale) abort " "o", "key", "value" and "locale" are used by parse_conv let o = a:datetime let locale = a:locale " for parse_conv let [info, flag, width] = a:descriptor let key = '_' . info[0] if !has_key(o, key) let key = '_' endif let Captor = info[1] if s:Prelude.is_funcref(Captor) let pattern = call(Captor, [a:locale], {}) if s:Prelude.is_list(pattern) let candidates = pattern unlet pattern let pattern = '\%(' . join(candidates, '\|') . '\)' endif elseif s:Prelude.is_list(Captor) if width ==# '' let width = Captor[1] endif let pattern = '\d\{1,' . width . '}' if flag ==# '_' let pattern = '\s*' . pattern endif else " if s:Prelude.is_string(Captor) let pattern = Captor endif let value = matchstr(a:remain, '^' . a:skip_pattern . pattern) let matched_len = len(value) if exists('candidates') let value = index(candidates, value) elseif s:Prelude.is_list(Captor) let value = str2nr(value, 10) endif if 4 <= len(info) let l:['value'] = eval(info[3]) endif if key !=# '_' let o[key] = value endif return a:remain[matched_len :] endfunction " @vimlint(EVL102, 0, l:locale) " Creates a DateTime object from Julian day. function! s:from_julian_day(jd, ...) abort let tz = call('s:timezone', a:000) let second = 0 if s:Prelude.is_float(a:jd) let jd = float2nr(floor(a:jd)) let second = float2nr(s:SECONDS_OF_DAY * (a:jd - jd)) else let jd = a:jd endif let [year, month, day] = s:_jd2g(jd) return s:from_date(year, month, day, 12, 0, second, '+0000').to(tz) endfunction " Creates a new TimeZone object. function! s:timezone(...) abort let info = a:0 ? a:1 : '' if s:_is_class(info, 'TimeZone') return info endif if info is# '' unlet info let info = s:_default_tz() endif let tz = copy(s:TimeZone) if s:Prelude.is_number(info) let tz._offset = info * s:NUM_MINUTES * s:NUM_SECONDS elseif s:Prelude.is_string(info) let list = matchlist(info, '\v^([+-])?(\d{1,2}):?(\d{1,2})?$') if !empty(list) let tz._offset = str2nr(list[1] . s:NUM_SECONDS) * \ (str2nr(list[2]) * s:NUM_MINUTES + str2nr(list[3])) else " TODO: TimeZone names throw 'vital: DateTime: Unknown timezone: ' . string(info) endif else throw 'vital: DateTime: Invalid timezone: ' . string(info) endif return tz endfunction " Creates a new TimeDelta object. function! s:delta(...) abort let info = a:0 ? a:1 : '' if s:_is_class(info, 'TimeDelta') return info endif let d = copy(s:TimeDelta) if a:0 == 2 && s:Prelude.is_number(a:1) && s:Prelude.is_number(a:2) let d._days = a:1 let d._seconds = a:2 else let a = copy(a:000) while 2 <= len(a) && s:Prelude.is_number(a[0]) && s:Prelude.is_string(a[1]) let [value, unit] = remove(a, 0, 1) if unit =~? '^sec\%(onds\?\)\?$' let d._seconds += value elseif unit =~? '^min\%(utes\?\)\?$' let d._seconds += value * s:NUM_SECONDS elseif unit =~? '^hours\?$' let d._seconds += value * s:SECONDS_OF_HOUR elseif unit =~? '^days\?$' let d._days += value elseif unit =~? '^weeks\?$' let d._days += value * s:NUM_DAYS_OF_WEEK else throw 'vital: DateTime: Invalid unit for delta(): ' . string(unit) endif endwhile if !empty(a) throw 'vital: DateTime: Invalid arguments for delta(): ' . string(a) endif endif return d._normalize() endfunction function! s:compare(d1, d2) abort return a:d1.compare(a:d2) endfunction " Returns month names according to the current or specified locale. " @param fullname = false " @param locale = '' function! s:month_names(...) abort return s:_names(s:MONTHS, a:0 && a:1 ? '%B' : '%b', get(a:000, 1, '')) endfunction " Returns weekday names according to the current or specified locale. " @param fullname = false " @param locale = '' function! s:weekday_names(...) abort return s:_names(s:WEEKS, a:0 && a:1 ? '%A' : '%a', get(a:000, 1, '')) endfunction " Returns am/pm names according to the current or specified locale. " @param lowercase = false " @param locale = '' function! s:am_pm_names(...) abort let [lowercase, locale] = a:000 + [0, ''][a:0 :] let names = s:_am_pm_names(lowercase, locale) if lowercase " Some environments do not support %P. " In this case, use tolower() of %p instead of. let failed = names[0] ==# '' || names[0] ==# 'P' if failed let names = s:_am_pm_names(0, locale) call map(names, 'tolower(v:val)') endif endif return names endfunction function! s:_am_pm_names(lowercase, locale) abort return s:_names(s:AM_PM_TIMES, a:lowercase ? '%P' : '%p', a:locale) endfunction " Returns 1 if the year is a leap year. function! s:is_leap_year(year) abort return a:year % 4 == 0 && a:year % 100 != 0 || a:year % 400 == 0 endfunction " ---------------------------------------------------------------------------- let s:Class = {} function! s:Class._clone() abort return filter(copy(self), 'v:key !~# "^__"') endfunction function! s:_new_class(class) abort return extend({'class': a:class}, s:Class) endfunction function! s:_is_class(obj, class) abort return s:Prelude.is_dict(a:obj) && get(a:obj, 'class', '') ==# a:class endfunction " ---------------------------------------------------------------------------- let s:DateTime = s:_new_class('DateTime') function! s:DateTime.year() abort return self._year endfunction function! s:DateTime.month() abort return self._month endfunction function! s:DateTime.day() abort return self._day endfunction function! s:DateTime.hour() abort return self._hour endfunction function! s:DateTime.minute() abort return self._minute endfunction function! s:DateTime.second() abort return self._second endfunction function! s:DateTime.timezone(...) abort if a:0 let dt = self._clone() let dt._timezone = call('s:timezone', a:000) return dt endif return self._timezone endfunction function! s:DateTime.day_of_week() abort if !has_key(self, '__day_of_week') let self.__day_of_week = self.timezone(0).days_from_era() % 7 endif return self.__day_of_week endfunction function! s:DateTime.day_of_year() abort if !has_key(self, '__day_of_year') let self.__day_of_year = self.timezone(0).julian_day() - \ s:_g2jd(self._year, 1, 1) + 1 endif return self.__day_of_year endfunction function! s:DateTime.days_from_era() abort if !has_key(self, '__day_from_era') let self.__day_from_era = self.julian_day() - s:ERA_TIME + 1 endif return self.__day_from_era endfunction function! s:DateTime.julian_day(...) abort let utc = self.to(0) let jd = s:_g2jd(utc._year, utc._month, utc._day) if a:0 && a:1 if has('float') let jd += (utc.seconds_of_day() + 0.0) / s:SECONDS_OF_DAY - 0.5 elseif utc._hour < 12 let jd -= 1 endif endif return jd endfunction function! s:DateTime.seconds_of_day() abort return (self._hour * s:NUM_MINUTES + self._minute) \ * s:NUM_SECONDS + self._second endfunction function! s:DateTime.quarter() abort return (self._month - 1) / 3 + 1 endfunction function! s:DateTime.unix_time() abort if !has_key(self, '__unix_time') if self._year < 1969 || \ (!has('num64') && (2038 < self._year)) let self.__unix_time = -1 else let utc = self.to(0) let self.__unix_time = (utc.julian_day() - s:EPOC_TIME) * \ s:SECONDS_OF_DAY + utc.seconds_of_day() if self.__unix_time < 0 let self.__unix_time = -1 endif endif endif return self.__unix_time endfunction function! s:DateTime.is_leap_year() abort return s:is_leap_year(self._year) endfunction function! s:DateTime.is(dt) abort return self.compare(a:dt) == 0 endfunction function! s:DateTime.compare(dt) abort return self.delta(a:dt).sign() endfunction function! s:DateTime.delta(dt) abort let left = self.to(0) let right = a:dt.to(0) return s:delta(left.days_from_era() - right.days_from_era(), \ (left.seconds_of_day() + left.timezone().offset()) - \ (right.seconds_of_day() + right.timezone().offset())) endfunction function! s:DateTime.to(...) abort let dt = self._clone() if a:0 == 1 && !s:_is_class(a:1, 'TimeDelta') let tz = s:timezone(a:1) let dt._second += tz.offset() - dt.timezone().offset() let dt._timezone = tz return dt._normalize() endif let delta = call('s:delta', a:000) let dt._day += delta._days let dt._second += delta._seconds return dt._normalize() endfunction " @vimlint(EVL102, 1, l:locale) function! s:DateTime.format(format, ...) abort let locale = a:0 ? a:1 : '' let result = '' for f in s:_split_format(a:format) if s:Prelude.is_string(f) let result .= f elseif s:Prelude.is_list(f) let [info, flag, width] = f let padding = '' if s:Prelude.is_list(info[1]) let [padding, w] = info[1] if width ==# '' let width = w endif endif if has_key(self, info[0]) let value = self[info[0]]() if 2 < len(info) let l:['value'] = eval(info[2]) endif elseif 2 < len(info) let value = info[2] else let value = '' endif if flag ==# '^' let value = toupper(value) elseif flag ==# '-' let padding = '' elseif flag ==# '_' let padding = ' ' elseif flag ==# '0' let padding = '0' endif let result .= printf('%' . padding . width . 's', value) unlet value endif unlet f endfor return result endfunction " @vimlint(EVL102, 0, l:locale) function! s:DateTime.strftime(format, ...) abort let tz = self.timezone() let ts = self.unix_time() + tz.offset() - s:tz_default_offset let locale = get(a:000, 0, '') let format = a:format =~? '%z' \ ? substitute(a:format, '%z', tz.offset_string(), 'g') \ : a:format if empty(locale) return strftime(format, ts) else let expr = printf('strftime(%s, %d)', string(format), ts) return s:_with_locale(expr, locale) endif endfunction function! s:DateTime.to_string() abort return self.format('%c') endfunction function! s:DateTime._normalize() abort let next = 0 for unit in ['second', 'minute', 'hour'] let key = '_' . unit let self[key] += next let [next, self[key]] = \ s:_divmod(self[key], s:['NUM_' . toupper(unit . 's')]) endfor let self._day += next let [self._year, self._month, self._day] = \ s:_jd2g(s:_g2jd(self._year, self._month, self._day)) return self endfunction let s:DateTime['+'] = s:DateTime.to let s:DateTime['-'] = s:DateTime.delta let s:DateTime['=='] = s:DateTime.is " ---------------------------------------------------------------------------- let s:TimeZone = s:_new_class('TimeZone') function! s:TimeZone.offset() abort return self._offset endfunction function! s:TimeZone.minutes() abort return self._offset / s:NUM_SECONDS endfunction function! s:TimeZone.hours() abort return self._offset / s:SECONDS_OF_HOUR endfunction function! s:TimeZone.sign() abort return self._offset < 0 ? -1 : 0 < self._offset ? 1 : 0 endfunction function! s:TimeZone.offset_string() abort return substitute(self.w3c(), ':', '', '') endfunction function! s:TimeZone.w3c() abort let sign = self._offset < 0 ? '-' : '+' let minutes = abs(self._offset) / s:NUM_SECONDS return printf('%s%02d:%02d', sign, \ minutes / s:NUM_MINUTES, minutes % s:NUM_MINUTES) endfunction " ---------------------------------------------------------------------------- let s:TimeDelta = s:_new_class('TimeDelta') function! s:TimeDelta.seconds() abort return self._seconds % s:NUM_SECONDS endfunction function! s:TimeDelta.minutes() abort return self._seconds / s:NUM_SECONDS % s:NUM_MINUTES endfunction function! s:TimeDelta.hours() abort return self._seconds / s:SECONDS_OF_HOUR endfunction function! s:TimeDelta.days() abort return self._days endfunction function! s:TimeDelta.weeks() abort return self._days / s:NUM_DAYS_OF_WEEK endfunction function! s:TimeDelta.months() abort return self._days / 30 endfunction function! s:TimeDelta.years() abort return self._days / 365 endfunction function! s:TimeDelta.total_seconds() abort return self._days * s:SECONDS_OF_DAY + self._seconds endfunction function! s:TimeDelta.is(td) abort return self.subtract(a:td).sign() == 0 endfunction function! s:TimeDelta.sign() abort if self._days < 0 || self._seconds < 0 return -1 elseif 0 < self._days || 0 < self._seconds return 1 endif return 0 endfunction function! s:TimeDelta.negate() abort let td = self._clone() let td._days = -self._days let td._seconds = -self._seconds return td._normalize() endfunction function! s:TimeDelta.duration() abort return self.sign() < 0 ? self.negate() : self endfunction function! s:TimeDelta.add(...) abort let n = self._clone() let other = call('s:delta', a:000) let n._days += other._days let n._seconds += other._seconds return n._normalize() endfunction function! s:TimeDelta.subtract(...) abort let other = call('s:delta', a:000) return self.add(other.negate()) endfunction function! s:TimeDelta.about() abort if self.sign() == 0 return 'now' endif let dir = self.sign() < 0 ? 'ago' : 'later' let d = self.duration() if d._days == 0 if d._seconds < s:NUM_SECONDS let val = d.seconds() let unit = val == 1 ? 'second' : 'seconds' elseif d._seconds < s:SECONDS_OF_HOUR let val = d.minutes() let unit = val == 1 ? 'minute' : 'minutes' else let val = d.hours() let unit = val == 1 ? 'hour' : 'hours' endif else if d._days < s:NUM_DAYS_OF_WEEK let val = d.days() let unit = val == 1 ? 'day' : 'days' elseif d._days < 30 let val = d.weeks() let unit = val == 1 ? 'week' : 'weeks' elseif d._days < 365 let val = d.months() let unit = val == 1 ? 'month' : 'months' else let val = d.years() let unit = val == 1 ? 'year' : 'years' endif endif return printf('%d %s %s', val, unit, dir) endfunction function! s:TimeDelta.to_string() abort let str = self.sign() < 0 ? '-' : '' let d = self.duration() if d._days != 0 let str .= d._days . (d._days == 1 ? 'day' : 'days') . ', ' endif let str .= printf('%02d:%02d:%02d', d.hours(), d.minutes(), d.seconds()) return str endfunction function! s:TimeDelta._normalize() abort let over_days = self._seconds / s:SECONDS_OF_DAY let self._days += over_days let self._seconds = self._seconds % s:SECONDS_OF_DAY if self._days < 0 && 0 < self._seconds let self._days += 1 let self._seconds -= s:SECONDS_OF_DAY elseif 0 < self._days && self._seconds < 0 let self._days -= 1 let self._seconds += s:SECONDS_OF_DAY endif return self endfunction " ---------------------------------------------------------------------------- " Converts Gregorian Calendar to Julian day function! s:_g2jd(year, month, day) abort let [next, month] = s:_divmod(a:month - 1, s:NUM_MONTHS) let year = a:year + next + 4800 - (month <= 1) let month += month <= 1 ? 10 : -2 return a:day + (153 * month + 2) / 5 + s:_div(1461 * year, 4) - 32045 \ - s:_div(year, 100) + s:_div(year, 400) endfunction " Converts Julian day to Gregorian Calendar function! s:_jd2g(jd) abort let t = a:jd + 68569 let n = s:_div(4 * t, 146097) let t -= s:_div(146097 * n + 3, 4) - 1 let i = (4000 * t) / 1461001 let t += -(1461 * i) / 4 + 30 let j = (80 * t) / 2447 let x = j / 11 let day = t - (2447 * j) / 80 let month = j + 2 - (12 * x) let year = 100 * (n - 49) + i + x return [year, month, day] endfunction function! s:_names(dates, format, locale) abort return s:_with_locale('map(copy(a:1), "strftime(a:2, v:val)")', \ a:locale, copy(a:dates), a:format) endfunction function! s:_with_locale(expr, locale, ...) abort let current_locale = '' if a:locale !=# '' let current_locale = v:lc_time execute 'language time' a:locale endif try return eval(a:expr) finally if a:locale !=# '' execute 'language time' current_locale endif endtry endfunction function! s:_div(n, d) abort return s:_divmod(a:n, a:d)[0] endfunction function! s:_mod(n, d) abort return s:_divmod(a:n, a:d)[1] endfunction function! s:_divmod(n, d) abort let [q, mod] = [a:n / a:d, a:n % a:d] return mod != 0 && (a:d < 0) != (mod < 0) ? [q - 1, mod + a:d] : [q, mod] endfunction " ---------------------------------------------------------------------------- function! s:_month_abbr(locale) abort return s:month_names(0, a:locale) endfunction function! s:_month_full(locale) abort return s:month_names(1, a:locale) endfunction function! s:_weekday_abbr(locale) abort return s:weekday_names(0, a:locale) endfunction function! s:_weekday_full(locale) abort return s:weekday_names(1, a:locale) endfunction function! s:_am_pm_lower(locale) abort return s:am_pm_names(1, a:locale) endfunction function! s:_am_pm_upper(locale) abort return s:am_pm_names(0, a:locale) endfunction " key = descriptor " value = string (format alias) " value = [field, captor, format_conv, parse_conv] " at format: " field = function name of source. " captor = [flat, width] for number format. " format_conv = expr for convert. some variables are available. " parse_conv = unused. " at parse: " field = param name (with "_") " if it doesn't exist, the descriptor can't use. " field = #skip " in this case, captor is a skipping pattern " captor = pattern to match. " captor = [flat, width] for number format. " captor = a function to return a pattern or candidates. " format_conv = unused. " parse_conv = expr for convert. some variables are available. let s:format_info = { \ '%': ['', '%', '%'], \ 'a': ['day_of_week', function('s:_weekday_abbr'), \ 's:_weekday_abbr(locale)[value]'], \ 'A': ['day_of_week', function('s:_weekday_full'), \ 's:_weekday_full(locale)[value]'], \ 'b': ['month', function('s:_month_abbr'), \ 's:_month_abbr(locale)[value - 1]', 'value + 1'], \ 'B': ['month', function('s:_month_full'), \ 's:_month_full(locale)[value - 1]', 'value + 1'], \ 'c': '%F %T %z', \ 'C': ['year', ['0', 2], '(value + 99) / 100', 'o[key] % 100 + value * 100'], \ 'd': ['day', ['0', 2]], \ 'D': '%m/%d/%y', \ 'e': '%_m/%_d/%_y', \ 'F': '%Y-%m-%d', \ 'h': '%b', \ 'H': ['hour', ['0', 2]], \ 'I': ['hour', ['0', 2], 's:_mod(value - 1, 12) + 1', 'value % 12'], \ 'j': ['day_of_year', ['0', 3]], \ 'k': '%_H', \ 'l': '%_I', \ 'm': ['month', ['0', 2]], \ 'M': ['minute', ['0', 2]], \ 'n': ['', '\_s*', "\n"], \ 'p': ['hour', function('s:_am_pm_upper'), \ 's:_am_pm_upper(locale)[value / 12]', 'o[key] + value * 12'], \ 'P': ['hour', function('s:_am_pm_lower'), \ 's:_am_pm_lower(locale)[value / 12]', 'o[key] + value * 12'], \ 'r': '%I:%M:%S %p', \ 'R': '%H:%M', \ 's': ['unix_time', ['', '']], \ 'S': ['second', ['0', 2]], \ 't': ['', '\_.*', "\t"], \ 'u': ['day_of_week', ['0', 1], 'value == 0 ? 7 : value'], \ 'U': 'TODO', \ 'T': '%H:%M:%S', \ 'w': ['day_of_week', ['0', 1]], \ 'y': ['year', ['0', 2], 'value % 100', \ '(o[key] != 0 ? o[key] : (value < 69 ? 2000 : 1900)) + value'], \ 'Y': ['year', ['0', 4]], \ 'z': ['timezone', '\v[+-]?%(\d{1,2})?:?%(\d{1,2})?', 'value.offset_string()', \ 's:timezone(empty(value) ? 0 : value)'], \ '*': ['#skip', '.\{-}', ''], \ } let s:DESCRIPTORS_PATTERN = '[' . join(keys(s:format_info), '') . ']' " 'foo%Ybar%02m' => ['foo', ['Y', '', -1], 'bar', ['m', '0', 2], ''] function! s:_split_format(format) abort let res = [] let pat = '\C%\([-_0^#]\?\)\(\d*\)\(' . s:DESCRIPTORS_PATTERN . '\)' let format = a:format while format !=# '' let i = match(format, pat) if i < 0 let res += [format] break endif if i != 0 let res += [format[: i - 1]] let format = format[i :] endif let [matched, flag, width, d] = matchlist(format, pat)[: 3] let format = format[len(matched) :] let info = s:format_info[d] if s:Prelude.is_string(info) let format = info . format else let res += [[info, flag, width]] endif unlet info endwhile return res endfunction if has('win32') " This means any versions of windows https://github.com/vim-jp/vital.vim/wiki/Coding-Rule#how-to-check-if-the-runtime-os-is-windows function! s:_default_tz() abort let hm = map(split(strftime('%H %M', 0), ' '), 'str2nr(v:val)') if str2nr(strftime('%Y', 0)) != 1970 let tz_sec = s:SECONDS_OF_DAY - hm[0] * s:SECONDS_OF_HOUR - hm[1] * s:NUM_SECONDS return printf('-%02d%02d', tz_sec / s:SECONDS_OF_HOUR, (tz_sec / s:NUM_SECONDS) % s:NUM_MINUTES) endif return printf('+%02d%02d', hm[0], hm[1]) endfunction else function! s:_default_tz() abort return strftime('%z') endfunction endif let &cpo = s:save_cpo unlet s:save_cpo " vim:set et ts=2 sts=2 sw=2 tw=0: