" dateconv.vim Miscelaneous date converters " Maintainer: Preben "Peppe" guldberg " Version: 1 " Date: " LeapYear() returns 1 if the year is a leap year, 0 otherwise fun! LeapYear(year) if a:year % 4 return 0 elseif a:year % 100 return 1 elseif a:year % 400 return 0 else return 1 endif endfun " DaysInYear() returns the number of days in any given year fun! DaysInYear(year) if a:year == 0 return 0 elseif a:year > 0 return 365 + LeapYear(a:year) else return 365 + LeapYear(a:year + 1) endif endfun " DaysInMonth() returns the number of days in a month (Jan = 1) of a year " Upon errors (including year 0), the function returns 0 fun! DaysInMonth(month, year) if a:year == 0 return 0 endif if a:month < 1 || a:month > 12 return 0 endif let feb = 28 + LeapYear(a:year) let arr = ',31,' . feb . ',31,30,31,30,31,31,30,31,30,31' return substitute(arr, '^\(\d*,\)\{' . a:month . '}\(\d\d\).*', '\2', '') endfun " JulianDay() returns the day of the year for a day/year/month combo " Returns 0 on errors fun! JulianDay(day, month, year) if a:day < 1 return 0 endif let days = a:day let m = 1 while m < a:month let days = days + DaysInMonth(m, a:year) let m = m + 1 endwhile if a:day > DaysInMonth(m, a:year) return 0 endif return days endfun " EpochTime() returns the number of seconds since the epoch. " The time argument is of the form [[[[[[cc]yy]mm]dd]HH]MM[.SS]] or "now" " An optional argument specifies if the epoch is counted from UTC (default) " If the optional arguments evaluates to 0, the result is adjusted to the " current timezone. " The function returns -1 on errors (including a time before the epoch) fun! EpochTime(time, ...) if a:0 > 0 let tzutc = a:1 + 0 else let tzutc = 1 endif if a:time ==? "now" " Some systems do not have the "%s" format for strftime :-( let time = strftime("%Y%m%d%H%M.%S") else let time = a:time endif if time !~ '^\(\d\d\)\{1,6}\(\.\d\d\)\=$' return -1 endif let sec = (time =~ '\.' ? substitute(time, '.*\.', '', '') : 0) let year = substitute(strpart(time, 0, 4), '^\(0*\)\(.\)', '\2', '') let month = substitute(strpart(time, 4, 2), '^\(0*\)\(.\)', '\2', '') let day = substitute(strpart(time, 6, 2), '^\(0*\)\(.\)', '\2', '') let hour = substitute(strpart(time, 8, 2), '^\(0*\)\(.\)', '\2', '') let min = substitute(strpart(time, 10, 2), '^\(0*\)\(.\)', '\2', '') if day == 1 let days = JulianDay(DaysInMonth(month - 1, year), month - 1, year) else let days = JulianDay(day - 1, month, year) endif let y = 1970 while y < year let days = days + DaysInYear(y) let y = y + 1 endwhile let sec = sec + 60 * min + 3600 * (24 * days + hour) if ! tzutc let tz = strftime("%z") let tzhour = substitute(strpart(tz, 1, 2), '^\(0*\)\(.\)', '\2', '') let tzmin = substitute(strpart(tz, 3, 2), '^\(0*\)\(.\)', '\2', '') let tzsec = 3600 * tzhour + 60 * tzmin if tz[0] == '+' let sec = sec - tzsec else let sec = sec + tzsec endif endif return sec endfun " SeptemberDay() returns the days since 31st August 1993 (localtime) " An optional date can be specified in seconds since the epoch (localtime). " If the optional date is before 1st Septembet 1993, 0 is returned. " On badly formed input, -1 is returned. fun! SeptemberDay(...) if a:0 > 0 if a:1 != '^\d\+$' return -1 endif let epochtime = a:1 else let epochtime = EpochTime("now", 0) endif let secs = epochtime - EpochTime("199308310000", 0) return secs / (24 * 3600) endfun