" Calendar functions " Author: Patrick Texier " Url: " Last modified: 2010 May 22 " Version: 0.3 " Vim Version: Vim 7.2 " Change Log {{{1 " 2008 Jul 01 " - Negative years handling " Init {{{1 if exists('g:loaded_datecalc') "finish endif scriptencoding latin1 let g:loaded_datecalc = 1 if !has("float") echo "Vim must be compiled with +float feature" finish endif let s:save_cpo = &cpo set cpo&vim let s:use_lang = 'fr' if !exists("s:use_lang") if strpart(v:lang, 0, 2) == 'fr' let s:use_lang = 'fr' else let s:use_lang = 'en' endif endif " Script variables {{{1 let s:LastJulien = 1582.1014 let s:LostDay = 2299161 if s:use_lang == 'en' let s:ListDays = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"] let s:ListMonth = ["", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"] let s:BeforeChrist = " B.C." else let s:ListDays = ["dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi"] let s:ListMonth = ["", "janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre"] let s:BeforeChrist = " avant J.C" endif let s:ListFrDays = ["décadi", "primedi", "duodi", "tridi", "quartidi", "quintidi", "sextidi", "septidi", "octidi", "nonidi"] let s:FrMonth = ["VEND", "BRUM", "FRIM", "NIVO", "PLUV", "VENT", "GERM", "FLOR","PRAI", "MESS", "THER", "FRUC", "COMP"] let s:FrLongMonth = {"VEND": "vendémiaire", "BRUM": "brumaire", "FRIM": "frimaire", "NIVO": "nivôse", "PLUV": "pluviôse", "VENT": "ventôse", "GERM": "germinal", "FLOR": "floréal", "PRAI": "prairial", "MESS": "messidor", "THER": "thermidor", "FRUC": "fructidor", "COMP": "jour complémentaire"} let s:FrYear = {"01": "I", "02": "II", "03": "III", "04": "IV", "05": "V", "06": "VI", "07": "VII", "08": "VIII", "09": "IX", "10": "X", "11": "XI", "12": "XII", "13": "XIII", "14": "XIV", "15": "XV" } let s:FrYearLen = [365, 365, 366, 365, 365, 365, 366, 365, 365, 365, 366, 365, 365, 365, 100] let s:FirstFr = 2375839.5 let s:LastFr = 2381051.5 " Functions {{{1 " AddDays(date DD/MM/YYYY, days) -> date {{{2 function! AddDays(date, days) let l:result = Jd2date(Date2jd(a:date) + a:days) return l:result endfunction " Date2fr (date DD/MM/YYYY) -> French republican date DD/MMMM/YY {{{2 function! Date2fr(date) let l:jd = Date2jd(a:date) if l:jd < s:FirstFr || l:jd > s:LastFr return a:date endif let l:jd2 = s:FirstFr let l:ar = 0 while l:jd2 + s:FrYearLen[l:ar] <= l:jd let l:jd2 += s:FrYearLen[l:ar] let l:ar += 1 endwhile " l:jd and l:jd2 are floats but reste is integer let l:reste = str2nr(printf("%3.0f", l:jd - l:jd2)) let l:mr = l:reste / 30 let l:jr = l:reste % 30 + 1 let l:ar += 1 let l:result = printf("%02d", l:jr) . "/" . s:FrMonth[l:mr] . "/" . printf("%02d", l:ar) return l:result endfunction " Date2jd(date DD/MM/AAAA) -> julian day {{{2 function! Date2jd(date) let l:jj = str2nr(strpart(a:date, 0, 2)) let l:mm = str2nr(strpart(a:date, 3, 2)) let l:aa = str2nr(strpart(a:date, 6, 5)) let l:m2 = l:mm let l:a = l:aa let l:jdd = 0.0 if (l:m2 < 3) let l:a -= 1 let l:m2 += 12 endif let l:jdd = floor(365.25 * l:a) let l:jdd += floor(30.6001 * (l:m2 + 1)) + l:jj + 1720994.5 " gregorian calendar if ((l:aa + l:mm/100.0 + l:jj/10000.0) > s:LastJulien) let l:jdd = l:jdd + 2.0 - floor(l:a/100.0) + floor(l:a/400.0) endif return l:jdd endfunction " DayOfWeek(Date DD/MM/YYYY) -> day of week (string) {{{2 function! DayOfWeek(date) let l:calc = Date2jd(a:date) + 1.5 - 7 * floor((Date2jd(a:date) + 1.5) / 7) "return l:calc let l:result = s:ListDays[float2nr(l:calc)] return l:result endfunction " Days(date1 DD/MM/YYYY, date2 DD/MM/YYYY) -> numbers of days {{{2 function! Days(date1, date2) let l:result = float2nr(Date2jd(a:date2) - Date2jd(a:date1)) return l:result endfunction " Easter(year AAAA) -> Easter date {{{2 function! Easter(year) " Easter uses only integers if a:year < 1582 let l:a = a:year % 4 let l:b = a:year % 7 let l:c = a:year % 19 let l:d = (19 * l:c + 15) % 30 let l:e = (2 * l:a + 4 * l:b - l:d + 34) % 7 let l:n = (l:d + l:e + 114) / 31 let l:p = ((l:d + l:e + 114) % 31) + 1 else let l:a = a:year % 19 let l:b = a:year / 100 let l:c = a:year % 100 let l:d = l:b / 4 let l:e = l:b % 4 let l:f = (l:b + 8) / 25 let l:g = (l:b - l:f + 1) / 3 let l:h = (19 * l:a + l:b - l:d - l:g + 15) % 30 let l:i = l:c / 4 let l:k = l:c % 4 let l:r = (32 + 2 * l:e + 2 * l:i - l:h - l:k) % 7 let l:m = (l:a + 11 * l:h + 22 * l:r) / 451 let l:n = (l:h + l:r - 7 * l:m + 114) / 31 let l:p = ((l:h + l:r - 7 * l:m + 114) % 31) + 1 endif let l:result = printf("%02d/%02d/%04d", l:p, l:n, a:year) return l:result endfunction " Fr2date (date DD/MMMM/YY) -> Gregorian date DD/MM/YYYY {{{2 function! Fr2date(date) let l:jd = s:FirstFr let l:jj = str2nr(strpart(a:date, 0, 2)) let l:mm = strpart(a:date, 3, 4) let l:aa = str2nr(strpart(a:date, 8, 2)) if l:jj < 1 || l:jj > 30 echo "Invalid day" return "" endif if l:aa < 0 || l:aa > 15 echo "Invalid year" return "" endif let l:ind = 0 while l:ind <= (l:aa - 2) let l:jd = l:jd + s:FrYearLen[l:ind] let l:ind += 1 endwhile let l:ind = 0 while l:mm != s:FrMonth[l:ind] && l:ind < 12 let l:ind += 1 endwhile if s:FrMonth[l:ind] != l:mm echo "Invalid month" return "" endif let l:jd += 30 * l:ind let l:jd += l:jj - 1 let l:result = Jd2date(l:jd) return l:result endfunction " Jd2date (julian day) julian day -> date DD/MM/AAAA {{{2 function! Jd2date(jd) let l:a = 0.0 let l:z = floor(a:jd + 0.5) let l:f = a:jd + 0.5 - l:z " Gregorian calendar if l:z >= s:LostDay let l:ab = floor((l:z-1867216.25)/36524.25) let l:a = l:z + 1.0 + l:ab - floor(l:ab / 4.0) else let l:a = l:z * 1.0 endif let l:b = l:a + 1524.0 let l:c = floor((l:b - 122.1) / 365.25) let l:d = floor(365.25 * l:c) let l:e = floor((l:b - l:d) / 30.6001) let l:jj = l:b - l:d - floor(30.6001 * l:e) + l:f if (l:e <= 13.0) let l:mm = l:e - 1.0 else let l:mm = l:e - 13.0 endif if (l:mm > 2.0) let l:aa = l:c - 4716.0 else let l:aa = l:c - 4715.0 endif if l:aa >= 0 let l:result = printf("%02.0f/%02.0f/%04.0f", l:jj, l:mm, l:aa) else let l:result = printf("%02.0f/%02.0f/-%04.0f", l:jj, l:mm, abs(l:aa)) endif return l:result endfunction " PrintDate (date DD/MM/YYYY or DD/MMMM/YY, day 0/1) -> Date {{{2 function! PrintDate(date, day) let l:bc = "" if a:date =~ "[A-Z]" " French republican calendar let l:dd = str2nr(strpart(a:date, 0, 2)) let l:mm = strpart(a:date, 3, 4) let l:yy = strpart(a:date, 8, 2) if a:day && l:mm != "COMP" let l:day = s:ListFrDays[l:dd % 10] . " " else let l:day = "" endif let l:result = l:day . l:dd . " " . s:FrLongMonth[l:mm] . " an " . s:FrYear[l:yy] else " Gregorian calendar let l:dd = str2nr(strpart(a:date, 0, 2)) let l:mm = str2nr(strpart(a:date, 3, 2)) let l:yy = strpart(a:date, 6, 5) if a:day let l:result = DayOfWeek(a:date) . " " else let l:result = "" endif let l:yy = str2nr(l:yy) if l:yy <= 0 let l:yy = -l:yy + 1 let l:bc = s:BeforeChrist endif let l:result .= l:dd . " " . s:ListMonth[l:mm] . " " . l:yy . l:bc endif return l:result endfunction " PtTest(date) TODO {{{2 function! PtTest(date) endfunction " Reset {{{1 let &cpo = s:save_cpo unlet s:save_cpo " }}}1 " vim:fdm=marker