אונטערשייד צווישן ווערסיעס פון "יחידה:דאטום"
קפיצה לניווט
קפיצה לחיפוש
שרגא (שמועס | ביישטייערונגען) ק (1 רעוויזיע אימפארטירט: אימפארטירט פון די יידישע וויקיפעדיע, זע ביישטייערער ליסטע) |
(דיוק) |
||
(19 מיטלסטע ווערסיעס פון 4 באַניצער נישט געוויזן.) | |||
שורה 261: | שורה 261: | ||
return year, month, day | return year, month, day | ||
end | |||
--[[ get month name and day (as numeric string), in either order, and return their numbers as day, month | |||
if optional parameter 'reverse' is true, return month first | |||
]]-- | |||
local function monthDay(dateTable, reverse) | |||
local months = { | |||
['יאנואר']= 1, | |||
['פעברואר']= 2, | |||
['מערץ']= 3, | |||
['אפריל']= 4, | |||
['מאי']= 5, | |||
['יוני']= 6, | |||
['יולי']= 7, | |||
['אויגוסט']= 8, | |||
['סעפטעמבער']= 9, | |||
['אקטאבער']= 10, | |||
['נאוועמבער']= 11, | |||
['דעצעמבער']= 12 | |||
} | |||
local month = nil | |||
local day = nil | |||
for _, value in ipairs(dateTable) do | |||
if months[value] then | |||
month = months[value] | |||
else | |||
day = tonumber(value) | |||
end | |||
end | |||
if reverse then | |||
return month, day | |||
else | |||
return day, month | |||
end | |||
end | end | ||
שורה 337: | שורה 373: | ||
t2 = Date.julianToGregorian(t2) | t2 = Date.julianToGregorian(t2) | ||
else | else | ||
error(" | error("Calendars don't match", 2) | ||
end | end | ||
end | end | ||
שורה 422: | שורה 458: | ||
return Date.new( definition ) | return Date.new( definition ) | ||
end | |||
local function extractNumbers(inputString) | |||
local numbers = inputString:match("^(%d+[%s%d-]*)") | |||
return numbers or "" | |||
end | end | ||
שורה 430: | שורה 471: | ||
]] | ]] | ||
function Date.newFromWikitext( wikitext ) | function Date.newFromWikitext( wikitext ) | ||
local calendar = nil | local calendar = nil | ||
if mw.ustring.find( wikitext, '<small>%(%[%[ | if mw.ustring.find( wikitext, '<small>%(%[%[יוליאנישער קאלענדאר%|יוליאניש%]%]%)</small>' ) then | ||
calendar = Date.CALENDAR.JULIAN | calendar = Date.CALENDAR.JULIAN | ||
wikitext = mw.ustring.gsub( wikitext, "<small>%(%[%[ | wikitext = mw.ustring.gsub( wikitext, "<small>%(%[%[יוליאנישער קאלענדאר%|יוליאניש%]%]%)</small>", "" ) | ||
end | end | ||
שורה 456: | שורה 483: | ||
wikitext = mw.ustring.gsub(wikitext, "‏","") | wikitext = mw.ustring.gsub(wikitext, "‏","") | ||
wikitext = mw.ustring.gsub(wikitext, "‎","") | wikitext = mw.ustring.gsub(wikitext, "‎","") | ||
wikitext = mw.ustring.gsub(wikitext, ",","") | |||
-- BC to minus | -- BC to minus | ||
wikitext = mw.ustring.gsub( wikitext, "([0-9]+) לפנה[\"״]ס" , "-%1") | wikitext = mw.ustring.gsub( wikitext, "([0-9]+) לפנה[\"״]ס" , "-%1") | ||
wikitext = mw.ustring.gsub( wikitext, "([0-9]+) אא[\"״]ר" , "-%1") | |||
wikitext = mw.ustring.gsub( wikitext, "([0-9]+) בצ[\"״]ר" , "-%1") | |||
wikitext = mw.ustring.gsub( wikitext, "([0-9]+) פד[\"״]צ" , "-%1") | |||
if mw.ustring.match(wikitext, '^המאה ה[־-]%d+$') then | if mw.ustring.match(wikitext, '^המאה ה[־-]%d+$') then | ||
שורה 468: | שורה 495: | ||
return Date.new( { year=tonumber(yearStr)*100, month=0, day=0, precision= Date.PRECISION.YEAR100 } ) | return Date.new( { year=tonumber(yearStr)*100, month=0, day=0, precision= Date.PRECISION.YEAR100 } ) | ||
end | end | ||
if mw.ustring.match(wikitext, "%d+['ס]?ט[ען]ר? י") then | |||
local yearStr = mw.ustring.match(wikitext, "(%d+)['ס]?ט[ען]ר? י") | |||
return Date.new( { year=tonumber(yearStr)*100, month=0, day=0, precision= Date.PRECISION.YEAR100 } ) | |||
end | |||
local parts = mw.text.split(mw.text.trim(wikitext),' ') | local parts = mw.text.split(mw.text.trim(wikitext),' ') | ||
שורה 476: | שורה 507: | ||
if #parts==3 then -- DMY date | if #parts==3 then -- DMY date | ||
definition.year = tonumber(parts[3]) | definition.year = tonumber(parts[3]) | ||
definition.month = | definition.day, definition.month = monthDay({parts[1], parts[2]}) | ||
assert(definition.year, "Could not recognize year") | assert(definition.year, "Could not recognize year") | ||
assert(definition.month<13 and definition.month>0, "Could not recognize month number") | assert(definition.month<13 and definition.month>0, "Could not recognize month number") | ||
שורה 483: | שורה 513: | ||
definition.precision = Date.PRECISION.DAY | definition.precision = Date.PRECISION.DAY | ||
elseif #parts==2 then -- MY date | elseif #parts==2 then -- MY date | ||
definition. | definition.month, definition.year = monthDay(parts, true) | ||
definition.precision = Date.PRECISION.MONTH | definition.precision = Date.PRECISION.MONTH | ||
assert(definition.year<1e7, "Could not recognize year") | assert(definition.year<1e7, "Could not recognize year") | ||
שורה 561: | שורה 590: | ||
if (self.precision >= Date.PRECISION.MY100) and (self.precision <= Date.PRECISION.MY) then | if (self.precision >= Date.PRECISION.MY100) and (self.precision <= Date.PRECISION.MY) then | ||
if self.year>0 then | if self.year>0 then | ||
return (self.year/1000000) .. ' | return (self.year/1000000) .. ' מיליאן יאר צום ציילונג' | ||
else | else | ||
return (-self.year/1000000) ..' | return (-self.year/1000000) ..' מיליאן יאר פד"צ' | ||
end | end | ||
elseif (self.precision >=Date.PRECISION.KY100) and (self.precision <= Date.PRECISION.KY) then | elseif (self.precision >=Date.PRECISION.KY100) and (self.precision <= Date.PRECISION.KY) then | ||
שורה 598: | שורה 627: | ||
else | else | ||
if self.calendar == Date.CALENDAR.JULIAN and self.year > 1583 then | if self.calendar == Date.CALENDAR.JULIAN and self.year > 1583 then | ||
hebrewStr = mw.ustring.format('%d <small>([[ | hebrewStr = mw.ustring.format('%d <small>([[יוליאנישער קאלענדאר|יוליאניש]])</small>', (self.year)) | ||
else | else | ||
hebrewStr = mw.ustring.format('%d', self.year) | hebrewStr = mw.ustring.format('%d', self.year) | ||
שורה 609: | שורה 638: | ||
return hebrewStr | return hebrewStr | ||
end | end | ||
local months = { 'יאנואר','פעברואר', 'מערץ', 'אפריל', 'מאי', 'יוני', 'יולי', 'אויגוסט', 'סעפטעמבער', 'אקטאבער', 'נאוועמבער','דעצעמבער' } | |||
hebrewStr = months[self.month] .. ' ' .. hebrewStr | hebrewStr = months[self.month] .. ' ' .. hebrewStr | ||
שורה 616: | שורה 645: | ||
return hebrewStr | return hebrewStr | ||
end | end | ||
hebrewStr = mw.ustring.format('%d %s', self.day, hebrewStr) | |||
--hour | --hour | ||
שורה 737: | שורה 766: | ||
local fd = '' | local fd = '' | ||
if self.precision >= Date.PRECISION.DAY then | if self.precision >= Date.PRECISION.DAY then | ||
fd = self.year < 0 and (-1 * self.year) .. ' | fd = self.year < 0 and (-1 * self.year) .. ' פד"צ' or fd .. self.year | ||
if options.link then fd = '[[' .. fd .. ']]' end | if options.link then fd = '[[' .. fd .. ']]' end | ||
local d = '2000-' .. prepend(self.month, '0', 2) .. '-' .. prepend(self.day, '0', 2) | local d = '2000-' .. prepend(self.month, '0', 2) .. '-' .. prepend(self.day, '0', 2) | ||
שורה 743: | שורה 772: | ||
fd = fd .. '. ' .. lang:formatDate(options.link and '[[j xg]]' or 'j xg', d) | fd = fd .. '. ' .. lang:formatDate(options.link and '[[j xg]]' or 'j xg', d) | ||
elseif self.precision >= Date.PRECISION.MONTH then | elseif self.precision >= Date.PRECISION.MONTH then | ||
fd = self.year < 0 and (-1 * self.year) .. ' | fd = self.year < 0 and (-1 * self.year) .. ' פד"צ' or fd .. self.year | ||
local month = mw.getContentLanguage():formatDate('F', '2000-' .. self.month) | local month = mw.getContentLanguage():formatDate('F', '2000-' .. self.month) | ||
if options.link then fd = '[[' .. fd .. ']]' end | if options.link then fd = '[[' .. fd .. ']]' end | ||
fd = month .. ' ' .. fd | fd = month .. ' ' .. fd | ||
elseif self.precision >= Date.PRECISION.YEAR then | elseif self.precision >= Date.PRECISION.YEAR then | ||
fd = self.year < 0 and (-1 * self.year) .. ' | fd = self.year < 0 and (-1 * self.year) .. ' פד"צ' or fd .. self.year | ||
if options.link ~= 'nem' then fd = '[[' .. fd .. ']]' end | if options.link ~= 'nem' then fd = '[[' .. fd .. ']]' end | ||
elseif self.precision == Date.PRECISION.YEAR10 then | elseif self.precision == Date.PRECISION.YEAR10 then | ||
local year = math.floor((self.year < 0 and -1 * self.year or self.year) / 10) * 10 | local year = math.floor((self.year < 0 and -1 * self.year or self.year) / 10) * 10 | ||
fd = 'שנות ה-' .. tostring(year%100) .. ' של המאה ה-'.. tostring(ceil(year/100)) | fd = 'שנות ה-' .. tostring(year%100) .. ' של המאה ה-'.. tostring(ceil(year/100)) | ||
fd = self.year < 0 and year .. ' | fd = self.year < 0 and year .. ' פד"צ' or tostring(year) | ||
elseif self.precision == Date.PRECISION.YEAR100 then | elseif self.precision == Date.PRECISION.YEAR100 then | ||
if self.year < 0 then | if self.year < 0 then | ||
fd = 'המאה ה-' .. math.floor(-1 * self.year / 100) .. ' | fd = 'המאה ה-' .. math.floor(-1 * self.year / 100) .. ' פד"צ' | ||
else | else | ||
fd = 'המאה ה-' ..math.floor(self.year / 100) | fd = 'המאה ה-' ..math.floor(self.year / 100) | ||
שורה 812: | שורה 841: | ||
local t1 = Date.newFromWikitext( parts[1] ) | local t1 = Date.newFromWikitext( parts[1] ) | ||
local t2 | local t2 | ||
local useCurrent = #parts<2 or (parts[2] == ' | local useCurrent = #parts<2 or (parts[2] == 'היינט' or parts[2]=='הווה' or parts[2]=='אנגייענד' or parts[2]=='איצט') | ||
if not useCurrent then | if not useCurrent then | ||
שורה 864: | שורה 893: | ||
readableInterval['years'] = readableInterval['years'] or 0 | readableInterval['years'] = readableInterval['years'] or 0 | ||
if not (guessLevel==NO_GUESS) and not (guessLevel==DAY_GUESS and hasYears and #diffFormat==1 and readableInterval['days']>31) then | if not (guessLevel==NO_GUESS) and not (guessLevel==DAY_GUESS and hasYears and #diffFormat==1 and readableInterval['days']>31) then | ||
outputPrefix=' | outputPrefix='בערך ' | ||
end | end | ||
if inclusive then | if inclusive then | ||
שורה 912: | שורה 941: | ||
if frame.args[2] == 'ימים' then | if frame.args[2] == 'ימים' then | ||
diffFormat = {'days'} | diffFormat = {'days'} | ||
elseif frame.args[2] == ' | elseif frame.args[2] == 'יארן' then | ||
diffFormat = {'years'} | diffFormat = {'years'} | ||
elseif frame.args[2] == 'שנים וימים' then | |||
diffFormat = {'years', 'days'} | |||
elseif frame.args[2] == "הפרש" then | elseif frame.args[2] == "הפרש" then | ||
diffFormat = "raw" | diffFormat = "raw" | ||
שורה 940: | שורה 971: | ||
str= mw.ustring.gsub(str,"כ(.+)","%1"); | str= mw.ustring.gsub(str,"כ(.+)","%1"); | ||
str= mw.ustring.gsub(str,"־(.+)","%1"); | str= mw.ustring.gsub(str,"־(.+)","%1"); | ||
str= mw.ustring.gsub(str," | str= mw.ustring.gsub(str," יאָרן","") | ||
if str == "שנתיים" then | if str == "שנתיים" then | ||
str = 2 | str = 2 | ||
end | end | ||
if str == " | if str == "יאר" then | ||
str = 1 | str = 1 | ||
end | end | ||
str = mw.ustring.gsub(str," | str = mw.ustring.gsub(str," יאָר", "") | ||
if tonumber(str) > 0 and | if tonumber(str) > 0 and | ||
tonumber(parseDateRange(frame.args[1], "raw", inclusive)) < 0 then | tonumber(parseDateRange(frame.args[1], "raw", inclusive)) < 0 then | ||
שורה 956: | שורה 987: | ||
return str | return str | ||
else | else | ||
return frame.args['error'] or '<span class="scribunto-error"> | return frame.args['error'] or '<span class="scribunto-error">דאטום פעלער: '..res..'</span>[[קאטעגאריע:בלעטער מיט דאטום פעלערן]]' | ||
end | end | ||
end | end | ||
שורה 962: | שורה 993: | ||
function parseStrDateSafe(frame) | function parseStrDateSafe(frame) | ||
local dateType = frame.args[2] | local dateType = frame.args[2] | ||
if dateType ==' | if dateType =='יאר' then | ||
dateType = 'Y' | dateType = 'Y' | ||
elseif dateType==' | elseif dateType=='מאנאט' then | ||
dateType = 'M' | dateType = 'M' | ||
elseif dateType==' | elseif dateType=='טאג' then | ||
dateType='D' | dateType='D' | ||
end | end | ||
שורה 973: | שורה 1,004: | ||
if success then | if success then | ||
if dateType=='Y' and mw.ustring.sub( res, 0, 1)=='-' then | if dateType=='Y' and mw.ustring.sub( res, 0, 1)=='-' then | ||
res = mw.ustring.sub( res, 2).. ' | res = mw.ustring.sub( res, 2).. ' פד"צ' | ||
end | end | ||
return res | return res | ||
else | else | ||
return frame.args['error'] or '<span class="scribunto-error"> | return frame.args['error'] or '<span class="scribunto-error">דאטום פעלער: '..res..'</span>[[קאטעגאריע:בלעטער מיט דאטום פעלערן]]' | ||
end | end | ||
שורה 1,009: | שורה 1,040: | ||
end | end | ||
Date[' | Date['רעכן'] = parseStrDateSafe; | ||
Date[' | Date['רעכן אפשטאנד'] = parseDateRangeSafe; | ||
Date['parseDateRange'] = parseDateRange; | Date['parseDateRange'] = parseDateRange; | ||
Date['מקושר'] = linkStrDateUnsafe; | Date['מקושר'] = linkStrDateUnsafe; | ||
return Date | return Date |
יעצטיגע רעוויזיע זינט 00:29, 30 נאוועמבער 2023
דער מאדול איז געווידמעט אויסצופירן פארשידענע פעולות אויף דאטומען.
- #רעכן - מקבלת תאריך טקסטואלי ופורמט ומחלצת את מהתאריך את הפורמט הרצוי
- #רעכן אפשטאנד - מקבלת טווח תאריכים ומחשבת את ההפרש ביניהם
רעכן
פארמאט | ביישפיל | אויסקום |
---|---|---|
טאג | {{#invoke:דאטום|רעכן|[[3 פעברואר]] [[2013]]|טאג}} | 3 |
טאג | {{#invoke:דאטום|רעכן|[[3 פעברואר]] [[2013]]{{הערה|א}}|טאג}} | 3 |
מאנאט | {{#invoke:דאטום|רעכן|[[3 פעברואר]] [[2013]]|מאנאט}} | 2 |
יאר | {{#invoke:דאטום|רעכן|[[3 פעברואר]] [[2013]]|יאר}} | 2013 |
יאר | {{#invoke:דאטום|רעכן|[[פעברואר]] [[2013]]|יאר}} | 2013 |
TS | {{#invoke:דאטום|רעכן|[[3 פעברואר]] [[2013]]|TS}} | 2013-02-03 |
הערות:
- דעם פארמאט TS קען מען אריינגעבן אין צייט פונקציעס פון פארזער פונקציאנען.
- ההמרה מתעלמת מסוגריים מרובעות של קישורים
- מען קען צולייגן א פאראמעטער error והתוכן שלו יוצג במקרה של שגיאה בתאריך. (רצוי להכניס במקרה כזה את הדף לקטגוריה כלשהי שתאפשר מעקב אחרי דפים לא תקינים. ברירת המחדל היא קאטעגאריע:בלעטער מיט דאטום פעלערן)
רעכן אפשטאנד
ביישפיל | אויסקום | |
---|---|---|
דיפאלט פארמאט: אויטאמאטיש | {{#invoke:דאטום|רעכן אפשטאנד|[[3 פעברואר]] [[1947]] - [[15 סעפטעמבער]] [[2013]]}} | 66 יאָרן |
דיפאלט פארמאט: אויטאמאטיש (דוגמה עם שנים וסימן מינוס) | {{#invoke:דאטום|רעכן אפשטאנד|1947 - 2013}} | בערך 66 יאָרן |
דיפאלט פארמאט: אויטאמאטיש (דוגמה עם שנים וסימן קו מפריד) | {{#invoke:דאטום|רעכן אפשטאנד|1947–2013}} | בערך 66 יאָרן |
יארן | {{#invoke:דאטום|רעכן אפשטאנד|[[3 פעברואר]] [[1947]] - [[15 סעפטעמבער]] [[2013]]|יארן}} | 66 יאָרן |
גיל | {{#invoke:דאטום|רעכן אפשטאנד|1 מערץ 1922 - 4 נאוועמבער 1995|גיל}} | 73 יאָרן |
גיל | {{#invoke:דאטום|רעכן אפשטאנד|1 מערץ 1922{{הערה|ב}} - 4 נאוועמבער 1995|גיל}} | 73 יאָרן |
גיל | {{#invoke:דאטום|רעכן אפשטאנד|1 מערץ 1994{{הערה|ב}} - 4 נאוועמבער 1995|גיל}} | 1 יאָר |
גיל | {{#invoke:דאטום|רעכן אפשטאנד|1 מערץ 1993{{הערה|ב}} - 4 נאוועמבער 1995|גיל}} | 2 יאָרן |
מספר | {{#invoke:דאטום|רעכן אפשטאנד|1 מערץ 1922 - 4 נאוועמבער 1995|מספר}} | 73 |
מספר | {{#invoke:דאטום|רעכן אפשטאנד|1 מערץ 1922{{הערה|ב}} - 4 נאוועמבער 1995|מספר}} | 73 |
מספר | {{#invoke:דאטום|רעכן אפשטאנד|1 מערץ 1994{{הערה|ב}} - 4 נאוועמבער 1995|מספר}} | 1 |
מספר | {{#invoke:דאטום|רעכן אפשטאנד|1 מערץ 1993{{הערה|ב}} - 4 נאוועמבער 1995|מספר}} | 2 |
שנים לפנה"ס | {{#invoke:דאטום|רעכן אפשטאנד|[[3 פעברואר]] 1900 לפנה"ס - [[15 סעפטעמבער]] [[2013]]|יארן}} | 3,913 יאָרן |
טעג | {{#invoke:דאטום|רעכן אפשטאנד|[[3 פעברואר]] [[1947]] - [[15 סעפטעמבער]] [[2013]]|ימים}} | 24,331 טעג |
הפרש | {{#invoke:דאטום|רעכן אפשטאנד|[[3 פעברואר]] [[1947]] - [[15 סעפטעמבער]] [[2013]]|הפרש}} | 2102198400 |
ללא תאריך יעד | {{#invoke:דאטום|רעכן אפשטאנד|[[3 פעברואר]] [[1947]]|יארן}} | 77 יאָרן |
נישט כולל לעצטן טאג | {{#invoke:דאטום|רעכן אפשטאנד|5 יוני 1967 - 10 יוני 1967}} | 5 טעג |
כולל לעצטן טאג | {{#invoke:דאטום|רעכן אפשטאנד|5 יוני 1967 - 10 יוני 1967|כולל=כן}} | 6 טעג |
כולל לעצטן טאג | {{#invoke:דאטום|רעכן אפשטאנד|14 סעפטעמבער 2014 - 14 סעפטעמבער 2014|כולל=כן}} | |
יאר און טאג | {{#invoke:דאטום|רעכן אפשטאנד|14 סעפטעמבער 2014 - 15 סעפטעמבער 2015|כולל=כן}} | 1 יאָר |
הערות:
- אן א ציל דאטע ווערט די היינטיקע דאטע געניצט פאר דער ציל דאטע
- הפרש - מציין את הפרש הזמנים בשניות וללא מילים. ניתן להשתמש בערך המוחזר בחלוקה מתאימה לקבלת יחידות זמן אחרות.
- אז מען גיט איין דעם פאראמעטער כולל=כן, ואז נלקח בחשבון אויך דעם לעצטן טאג. כשמדובר על טווח זמן ארוך והפורמט נבחר אוטומטי או שמכיל שנים, מתקבלת תוצאה מקורבת.
- ניתן להוסיף פרמטר error והתוכן שלו יוצג במקרה של שגיאה בטווח התאריכים. (רצוי להכניס במקרה כזה את הדף לקטגוריה כלשהי שתאפשר מעקב אחרי דפים לא תקינים. ברירת המחדל היא קאטעגאריע:בלעטער מיט דאטום פעלערן)
- אם לא מצוין פורמט, הוא נבחר אוטומטית:
- ביז 3 וואכן ווערט אויסגעשטעלט אין טעג
- ביז א יאר ווערט אויסגעשטעלט אין וואכן און טעג
- ביז 10 יאר אין יארן און וואכן
- העכער פון דעם נאר אין יארן
local Date = {}
local maxDaysInMonth = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
--[[
Supported calendar models
]]--
Date.CALENDAR = {
GREGORIAN = 'Gregorian',
JULIAN = 'Julian'
}
--Internal functions
--[[
Check if a value is a number in the given range
@param mixed value
@param number min
@param number max
@return boolean
]]--
local function validateNumberInRange( value, min, max )
return type( value ) == 'number' and value >= min and value <= max
end
--[[
Validate a time defintion
@param table definition data
@return boolean
]]--
local function validate(definition)
--Validate constants
if not Date.knowsPrecision(definition.precision) or
(definition.calendar ~= Date.CALENDAR.GREGORIAN and definition.calendar ~= Date.CALENDAR.JULIAN) then
return false
end
--Validate year
if not (type( definition.year ) == 'number' or (definition.year == nil and precision == Date.PRECISION.DAY)) then
return false
end
if definition.precision <= Date.PRECISION.YEAR then
return true
end
--Validate month
if not validateNumberInRange( definition.month, 1, 12 ) then
return false
end
if definition.precision <= Date.PRECISION.MONTH then
return true
end
--Validate day
if not validateNumberInRange( definition.day, 1, 31 ) then
return false
end
if definition.precision <= Date.PRECISION.DAY then
return true
end
--Validate hour
if not validateNumberInRange( definition.hour, 0, 23 ) then
return false
end
if definition.precision <= Date.PRECISION.HOUR then
return true
end
--Validate minute
if not validateNumberInRange( definition.minute, 0, 59 ) then
return false
end
if definition.precision <= Date.PRECISION.MINUTE then
return true
end
--Validate second
if not validateNumberInRange( definition.second, 0, 60 ) then
return false
end
return true
end
--[[
Try to find the relevant precision for a time definition
@param table time definition
@return number the precision
]]--
local function guessPrecision(definition)
if definition.month == nil or (definition.month == 0 and definition.day == 0) then
return Date.PRECISION.YEAR
elseif definition.day == nil or definition.day == 0 then
return Date.PRECISION.MONTH
elseif definition.hour == nil then
return Date.PRECISION.DAY
elseif definition.minute == nil then
return Date.PRECISION.HOUR
elseif definition.second == nil then
return Date.PRECISION.MINUTE
else
return Date.PRECISION.SECOND
end
end
--[[
Try to find the relevant calendar for a time definition
@param table time definition
@return string the calendar name
]]--
local function guessCalendar( definition )
if definition.year ~= nil and definition.year < 1583 and definition.precision > Date.PRECISION.MONTH then
return Date.CALENDAR.JULIAN
else
return Date.CALENDAR.GREGORIAN
end
end
--[[
Parse an ISO 2061 string and return it as a time definition
@param string iso the iso datetime
@param boolean withoutRecurrence concider date in the format XX-XX as year-month and not month-day
@return table
]]--
local function parseIso8601( iso, withoutRecurrence )
local definition = {}
--Split date and time
iso = mw.text.trim( iso:upper() )
local beginMatch, endMatch, date, time, offset = iso:find( '([%+%-]?[%d%-]+)[T ]?([%d%.:]*)([Z%+%-]?[%d:]*)' )
if beginMatch ~= 1 or endMatch ~= iso:len() then --iso is not a valid ISO string
return {}
end
--date
if date ~= nil then
local isBC = false
if date:sub( 1, 1 ) == '-' then
isBC = true
date = date:sub( 2, date:len() )
end
local parts = mw.text.split( date, '-' )
if not withoutRecurrence and table.maxn( parts ) == 2 and parts[1]:len() == 2 then
--MM-DD case
definition.month = tonumber( parts[1] )
definition.day = tonumber( parts[2] )
else
if isBC then
definition.year = -1 * tonumber( parts[1] ) --FIXME - 1 --Years BC are counted since 0 and not -1
else
definition.year = tonumber( parts[1] )
end
definition.month = tonumber( parts[2] )
definition.day = tonumber( parts[3] )
end
end
--time
if time ~= nil then
local parts = mw.text.split( time, ':' )
definition.hour = tonumber( parts[1] )
definition.minute = tonumber( parts[2] )
definition.second = tonumber( parts[3] )
end
--offset
if offset ~= nil then
if offset == 'Z' then
definition.utcoffset = '+00:00'
else
definition.utcoffset = offset
end
end
return definition
end
--[[
Format UTC offset for ISO output
@param string offset UTC offset
@return string UTC offset for ISO
]]--
local function formatUtcOffsetForIso( offset )
if offset == '+00:00' then
return 'Z'
else
return offset
end
end
--[[
Prepend as mutch as needed the character c to the string str in order to to have a string of length length
@param mixed str
@param string c
@param number length
@return string
]]--
local function prepend(str, c, length)
str = tostring( str )
while str:len() < length do
str = c .. str
end
return str
end
-- LEAP_GREGORIAN -- Is a given year in the Gregorian calendar a leap year ?
local function leapGregorian(year)
return ((year % 4) == 0) and
(not (((year % 100) == 0) and ((year % 400) ~= 0)))
end
local isDateInLeapYear = function(indate)
if indate.calendar == Date.CALENDAR.JULIAN then
return 0 == indate.year % 4
end
return leapGregorian(indate.year)
end
-- GREGORIAN_TO_JD -- Determine Julian day number from Gregorian calendar date
local GREGORIAN_EPOCH = 1721425.5
local function gregorianToJd(year, month, day)
return (GREGORIAN_EPOCH - 1) +
(365 * (year - 1)) +
math.floor((year - 1) / 4) +
(-math.floor((year - 1) / 100)) +
math.floor((year - 1) / 400) +
math.floor((((367 * month) - 362) / 12) +
((month <= 2) and 0 or
(leapGregorian(year) and -1 or -2)
) +
day)
end
-- JD_TO_JULIAN -- Calculate Julian calendar date from Julian day
local function jdToJulian(td)
local z, a, alpha, b, c, d, e, year, month, day
td = td + 0.5
z = math.floor(td)
a = z
b = a + 1524
c = math.floor((b - 122.1) / 365.25)
d = math.floor(365.25 * c)
e = math.floor((b - d) / 30.6001)
month = math.floor((e < 14) and (e - 1) or (e - 13))
year = math.floor((month > 2) and (c - 4716) or (c - 4715))
day = b - d - math.floor(30.6001 * e)
--[[
If year is less than 1, subtract one to convert from
a zero based date system to the common era system in
which the year -1 (1 B.C.E) is followed by year 1 (1 C.E.).
--]]
if year < 1 then
year = year - 1
end
return year, month, day
end
--[[ get month name and day (as numeric string), in either order, and return their numbers as day, month
if optional parameter 'reverse' is true, return month first
]]--
local function monthDay(dateTable, reverse)
local months = {
['יאנואר']= 1,
['פעברואר']= 2,
['מערץ']= 3,
['אפריל']= 4,
['מאי']= 5,
['יוני']= 6,
['יולי']= 7,
['אויגוסט']= 8,
['סעפטעמבער']= 9,
['אקטאבער']= 10,
['נאוועמבער']= 11,
['דעצעמבער']= 12
}
local month = nil
local day = nil
for _, value in ipairs(dateTable) do
if months[value] then
month = months[value]
else
day = tonumber(value)
end
end
if reverse then
return month, day
else
return day, month
end
end
-- adapted from ro:Modul:GregorianDate
local initialOffset = -3
local limitDates = {
{year = 4, month = 3, day = 3, calendar = Date.CALENDAR.JULIAN },
{year = 100, month = 3, day = 2, calendar = Date.CALENDAR.JULIAN },
{year = 200, month = 3, day = 1, calendar = Date.CALENDAR.JULIAN },
{year = 300, month = 2, day = 29, calendar = Date.CALENDAR.JULIAN },
{year = 500, month = 2, day = 28, calendar = Date.CALENDAR.JULIAN },
{year = 600, month = 2, day = 27, calendar = Date.CALENDAR.JULIAN },
{year = 700, month = 2, day = 26, calendar = Date.CALENDAR.JULIAN },
{year = 900, month = 2, day = 25, calendar = Date.CALENDAR.JULIAN },
{year = 1000, month = 2, day = 24, calendar = Date.CALENDAR.JULIAN },
{year = 1100, month = 2, day = 23, calendar = Date.CALENDAR.JULIAN },
{year = 1300, month = 2, day = 22, calendar = Date.CALENDAR.JULIAN },
{year = 1400, month = 2, day = 21, calendar = Date.CALENDAR.JULIAN },
{year = 1500, month = 2, day = 20, calendar = Date.CALENDAR.JULIAN },
{year = 1700, month = 2, day = 19, calendar = Date.CALENDAR.JULIAN },
{year = 1800, month = 2, day = 18, calendar = Date.CALENDAR.JULIAN },
{year = 1900, month = 2, day = 17, calendar = Date.CALENDAR.JULIAN },
{year = 2100, month = 2, day = 16, calendar = Date.CALENDAR.JULIAN },
{year = 2200, month = 2, day = 15, calendar = Date.CALENDAR.JULIAN },
{year = 2300, month = 2, day = 14, calendar = Date.CALENDAR.JULIAN }
}
function Date.julianToGregorian(indate)
if indate.calendar ~= Date.CALENDAR.JULIAN then
return indate
end
local outputDate
if indate.precision > Date.PRECISION.MONTH then
local offset = initialOffset
local limitDateIdx = 1
while limitDateIdx < #limitDates and Date.le(limitDates[limitDateIdx], indate) do
limitDateIdx = limitDateIdx + 1
offset = offset + 1
end
outputDate = Date.addDaysToDate(indate, offset)
else
outputDate = mw.clone(indate)
end
outputDate.calendar = Date.CALENDAR.GREGORIAN
outputDate.calendarmodel = 'http://www.wikidata.org/entity/Q1985727'
return Date.new(outputDate)
end
function Date.addDaysToDate(indate, days)
local outdate = mw.clone(indate)
outdate.day = outdate.day + days
local lastDayOfMonth = maxDaysInMonth[outdate.month]
while outdate.day > lastDayOfMonth do
lastDayOfMonth = maxDaysInMonth[outdate.month]
if outdate.month == 2 and isDateInLeapYear(outdate) then lastDayOfMonth = 29 end
outdate.month = outdate.month + 1
outdate.day = outdate.day - lastDayOfMonth
end
while outdate.month > 12 do
outdate.year = outdate.year + 1
outdate.month = outdate.month - 12
end
return outdate
end
function Date.le(t1, t2, correct_calender)
if t1.calendar ~= t2.calendar then
if correct_calender then
t1 = Date.julianToGregorian(t1)
t2 = Date.julianToGregorian(t2)
else
error("Calendars don't match", 2)
end
end
if t1.year < t2.year then
return true
end
if t1.year == t2.year then
if t1.month < t2.month then
return true
end
if t1.month == t2.month and t1.day <= t2.day then
return true
end
end
return false
end
--Public interface
--[[
Build a new Date
@param table definition definition of the time
@return Date|nil
]]--
function Date.new( definition )
--Default values
if definition.precision == nil then
definition.precision = guessPrecision( definition )
end
if definition.calendar == nil then
definition.calendar = guessCalendar( definition )
end
if not validate( definition ) then
return nil
end
local time = {
year = definition.year or nil,
month = definition.month or 1,
day = definition.day or 1,
hour = definition.hour or 0,
minute = definition.minute or 0,
second = definition.second or 0,
utcoffset = definition.utcoffset or '+00:00',
calendar = definition.calendar or Date.CALENDAR.GREGORIAN,
precision = definition.precision or 0
}
setmetatable( time, {
__index = Date,
__le = le,
__tostring = function( self ) return self:toString() end
} )
return time
end
--[[
Build a new Date from an ISO 8601 datetime
@param string iso the time as ISO string
@param boolean withoutRecurrence concider date in the format XX-XX as year-month and not month-day
@return Date|nil
]]--
function Date.newFromIso8601( iso, withoutRecurrence )
return Date.new( parseIso8601( iso, withoutRecurrence ) )
end
--[[
Build a new Date from a Wikidata time value
@param table wikidataValue the time as represented by Wikidata
@return Date|nil
]]--
function Date.newFromWikidataValue( wikidataValue )
local definition = parseIso8601( wikidataValue.time )
definition.precision = wikidataValue.precision
if wikidataValue.calendarmodel == 'http://www.wikidata.org/entity/Q1985727' then
definition.calendar = Date.CALENDAR.GREGORIAN
elseif wikidataValue.calendarmodel == 'http://www.wikidata.org/entity/Q1985786' then
definition.calendar = Date.CALENDAR.JULIAN
else
return nil
end
return Date.new( definition )
end
local function extractNumbers(inputString)
local numbers = inputString:match("^(%d+[%s%d-]*)")
return numbers or ""
end
--[[
Build a new Date from a wiki string
@param string wikitext string
@return Date|nil
]]
function Date.newFromWikitext( wikitext )
local calendar = nil
if mw.ustring.find( wikitext, '<small>%(%[%[יוליאנישער קאלענדאר%|יוליאניש%]%]%)</small>' ) then
calendar = Date.CALENDAR.JULIAN
wikitext = mw.ustring.gsub( wikitext, "<small>%(%[%[יוליאנישער קאלענדאר%|יוליאניש%]%]%)</small>", "" )
end
-- Remove instances of [ and ]
wikitext = mw.ustring.gsub( wikitext, "[%[%]]", "" )
-- Remove footnotes & directionality markers
wikitext = mw.text.killMarkers( wikitext )
wikitext = mw.ustring.gsub(wikitext, "‏","")
wikitext = mw.ustring.gsub(wikitext, "‎","")
wikitext = mw.ustring.gsub(wikitext, ",","")
-- BC to minus
wikitext = mw.ustring.gsub( wikitext, "([0-9]+) לפנה[\"״]ס" , "-%1")
wikitext = mw.ustring.gsub( wikitext, "([0-9]+) אא[\"״]ר" , "-%1")
wikitext = mw.ustring.gsub( wikitext, "([0-9]+) בצ[\"״]ר" , "-%1")
wikitext = mw.ustring.gsub( wikitext, "([0-9]+) פד[\"״]צ" , "-%1")
if mw.ustring.match(wikitext, '^המאה ה[־-]%d+$') then
local yearStr = mw.ustring.match(wikitext, '^המאה ה[־-](%d+)$')
return Date.new( { year=tonumber(yearStr)*100, month=0, day=0, precision= Date.PRECISION.YEAR100 } )
end
if mw.ustring.match(wikitext, "%d+['ס]?ט[ען]ר? י") then
local yearStr = mw.ustring.match(wikitext, "(%d+)['ס]?ט[ען]ר? י")
return Date.new( { year=tonumber(yearStr)*100, month=0, day=0, precision= Date.PRECISION.YEAR100 } )
end
local parts = mw.text.split(mw.text.trim(wikitext),' ')
local definition = {}
definition.calendar = calendar
if #parts==3 then -- DMY date
definition.year = tonumber(parts[3])
definition.day, definition.month = monthDay({parts[1], parts[2]})
assert(definition.year, "Could not recognize year")
assert(definition.month<13 and definition.month>0, "Could not recognize month number")
assert(definition.day<32 and definition.day>0, "Wrong date format")
definition.precision = Date.PRECISION.DAY
elseif #parts==2 then -- MY date
definition.month, definition.year = monthDay(parts, true)
definition.precision = Date.PRECISION.MONTH
assert(definition.year<1e7, "Could not recognize year")
assert(definition.month<13 and definition.month>0, "Could not recognize month number")
elseif #parts==1 then --Y date
definition.precision = Date.PRECISION.YEAR
definition.year=tonumber(parts[1])
assert(definition.year<1e7, "Could not recognize year")
else
error("Unexpected date format")
end
return Date.new( definition )
end
--[[
Return a Date as a ISO 8601 string
@return string
]]--
function Date:toIso8601()
local iso = ''
if self.year ~= nil then
if self.year < 0 then
--Years BC are counted since 0 and not -1
iso = '-' .. prepend(string.format('%.0f', -1 * self.year), '0', 4)
else
iso = prepend(string.format('%.0f', self.year), '0', 4)
end
end
--month
if self.precision < Date.PRECISION.MONTH then
return iso
end
if self.iso ~= '' then
iso = iso .. '-'
end
iso = iso .. prepend( self.month, '0', 2 )
--day
if self.precision < Date.PRECISION.DAY then
return iso
end
iso = iso .. '-' .. prepend( self.day, '0', 2 )
--hour
if self.precision < Date.PRECISION.HOUR then
return iso
end
iso = iso .. 'T' .. prepend( self.hour, '0', 2 )
--minute
if self.precision < Date.PRECISION.MINUTE then
return iso .. formatUtcOffsetForIso( self.utcoffset )
end
iso = iso .. ':' .. prepend( self.minute, '0', 2 )
--second
if self.precision < Date.PRECISION.SECOND then
return iso .. formatUtcOffsetForIso( self.utcoffset )
end
return iso .. ':' .. prepend( self.second, '0', 2 ) .. formatUtcOffsetForIso( self.utcoffset )
end
--[[
Return a hebrew representation of Date as a string
@return string
]]--
function Date:toHebrewString()
local hebrewStr = ''
local year = self.year
if (self.precision >= Date.PRECISION.MY100) and (self.precision <= Date.PRECISION.MY) then
if self.year>0 then
return (self.year/1000000) .. ' מיליאן יאר צום ציילונג'
else
return (-self.year/1000000) ..' מיליאן יאר פד"צ'
end
elseif (self.precision >=Date.PRECISION.KY100) and (self.precision <= Date.PRECISION.KY) then
if self.year>0 then
return 'האלף ה־'.. (self.year/1000)
else
return 'האלף ה־'.. (-self.year/1000) ..' לפנה״ס'
end
elseif self.precision == Date.PRECISION.YEAR100 then
if year>0 then
return 'המאה ה־'.. math.ceil(self.year/100)
else
return 'המאה ה־'.. math.ceil(-self.year/100) ..' לפנה״ס'
end
elseif self.precision == Date.PRECISION.YEAR10 then
local year = math.floor((self.year < 0 and -1 * self.year or self.year) / 10) * 10
if self.year>0 then
if year%100==0 then
return 'העשור הראשון של המאה ה־'.. tostring((year/100)+1)
else
return 'שנות ה־' .. tostring(year%100) .. ' של המאה ה־'.. tostring(math.ceil(year/100))
end
else
if year%100==0 then
return 'העשור הראשון של המאה ה־'.. tostring((year/100))..' לפנה״ס'
else
return 'שנות ה־' .. tostring(year%100) .. ' של המאה ה־'.. tostring(math.ceil(year/100))..' לפנה״ס'
end
end
end
if self.year ~= nil then
if self.year < 0 then
hebrewStr = mw.ustring.format('%d לפנה״ס', (-1*self.year))
else
if self.calendar == Date.CALENDAR.JULIAN and self.year > 1583 then
hebrewStr = mw.ustring.format('%d <small>([[יוליאנישער קאלענדאר|יוליאניש]])</small>', (self.year))
else
hebrewStr = mw.ustring.format('%d', self.year)
end
end
end
--month
if self.precision>=Date.PRECISION.YEAR and self.precision < Date.PRECISION.MONTH then
return hebrewStr
end
local months = { 'יאנואר','פעברואר', 'מערץ', 'אפריל', 'מאי', 'יוני', 'יולי', 'אויגוסט', 'סעפטעמבער', 'אקטאבער', 'נאוועמבער','דעצעמבער' }
hebrewStr = months[self.month] .. ' ' .. hebrewStr
--day
if self.precision < Date.PRECISION.DAY then
return hebrewStr
end
hebrewStr = mw.ustring.format('%d %s', self.day, hebrewStr)
--hour
if self.precision < Date.PRECISION.HOUR then
return hebrewStr
end
hebrewStr = mw.ustring.format('%s בשעה %d', hebrewStr, self.hour)
--minute
if self.precision < Date.PRECISION.MINUTE then
return hebrewStr .. formatUtcOffsetForIso( self.utcoffset )
end
hebrewStr = hebrewStr .. ':' .. prepend( self.minute, '0', 2 )
--second
if self.precision < Date.PRECISION.SECOND then
return hebrewStr .. formatUtcOffsetForIso( self.utcoffset )
end
return hebrewStr .. ':' .. prepend( self.second, '0', 2 ) .. formatUtcOffsetForIso( self.utcoffset )
end
--[[
Return a Date as a string
@param mw.language|string|nil language to use. By default the content language.
@return string
]]--
function Date:toString( language )
if language == nil then
return self:toIso8601()
end
if language == 'he' then
return self:toHebrewString()
end
--[[if type( language ) == 'string' then
language = mw.language.new( language )
end
return language:formatDate( 'r', self:toIso8601() )]]
return self:toIso8601()
end
--[[
Return a Date in HTMl (with a <time> node)
@param mw.language|string|nil language to use. By default the content language.
@param table|nil attributes table of attributes to add to the <time> node.
@return string
]]--
function Date:toHtml( language, attributes )
if attributes == nil then
attributes = {}
end
attributes['datetime'] = self:toIso8601()
return mw.text.tag( 'time', attributes, self:toString( language ) )
end
--[[
All possible precisions for a Date (same ids as Wikibase)
]]--
Date.PRECISION = {
GY = 0, --Gigayear
MY100 = 1, --100 Megayears
MY10 = 2, --10 Megayears
MY = 3, --Megayear
KY100 = 4, --100 Kiloyears
KY10 = 5, --10 Kiloyears
KY = 6, --Kiloyear
YEAR100 = 7, --100 years
YEAR10 = 8, --10 years
YEAR = 9,
MONTH = 10,
DAY = 11,
HOUR = 12,
MINUTE = 13,
SECOND = 14
}
--[[
Check if the precision is known
@param number precision ID
@return boolean
]]--
function Date.knowsPrecision( precision )
for _,id in pairs( Date.PRECISION ) do
if id == precision then
return true
end
end
return false
end
function Date.age(time1, time2)
if time2 == nil then
time2 = Date.newFromIso8601(mw.getContentLanguage():formatDate('c', nil, true), true)
end
local age = {year, month, day}
age.year = time2.year - time1.year
age.month = time2.month - time1.month
age.day = time2.day - time1.day
if age.day < 0 then
local lastMonth = time2.month - 1
if lastMonth == 0 then
lastMonth = 12
end
age.day = age.day + maxDaysInMonth[lastMonth]
age.month = age.month - 1
end
if age.month < 0 then
age.month = age.month + 12
age.year = age.year - 1
end
if time1.year < 0 and time2.year > 0 then
age.year = age.year - 1
end
return age
end
function Date:formatDate(options)
options = options or {}
local fd = ''
if self.precision >= Date.PRECISION.DAY then
fd = self.year < 0 and (-1 * self.year) .. ' פד"צ' or fd .. self.year
if options.link then fd = '[[' .. fd .. ']]' end
local d = '2000-' .. prepend(self.month, '0', 2) .. '-' .. prepend(self.day, '0', 2)
local lang = mw.getContentLanguage()
fd = fd .. '. ' .. lang:formatDate(options.link and '[[j xg]]' or 'j xg', d)
elseif self.precision >= Date.PRECISION.MONTH then
fd = self.year < 0 and (-1 * self.year) .. ' פד"צ' or fd .. self.year
local month = mw.getContentLanguage():formatDate('F', '2000-' .. self.month)
if options.link then fd = '[[' .. fd .. ']]' end
fd = month .. ' ' .. fd
elseif self.precision >= Date.PRECISION.YEAR then
fd = self.year < 0 and (-1 * self.year) .. ' פד"צ' or fd .. self.year
if options.link ~= 'nem' then fd = '[[' .. fd .. ']]' end
elseif self.precision == Date.PRECISION.YEAR10 then
local year = math.floor((self.year < 0 and -1 * self.year or self.year) / 10) * 10
fd = 'שנות ה-' .. tostring(year%100) .. ' של המאה ה-'.. tostring(ceil(year/100))
fd = self.year < 0 and year .. ' פד"צ' or tostring(year)
elseif self.precision == Date.PRECISION.YEAR100 then
if self.year < 0 then
fd = 'המאה ה-' .. math.floor(-1 * self.year / 100) .. ' פד"צ'
else
fd = 'המאה ה-' ..math.floor(self.year / 100)
end
if options.link then fd = '[[' .. fd .. ']]' end
else
fd = tostring(self.year)
end
return fd
end
function parseStrDate(dateStr, dateType)
local datetime = Date.newFromWikitext( dateStr )
if datetime.precision >= Date.PRECISION.DAY then -- DMY date
if dateType=='Y' then
res = datetime.year
elseif dateType=='M' then
res = datetime.month
elseif dateType=='D' then
res = datetime.day
elseif dateType == 'TS' then
res = datetime:toIso8601()
end
elseif datetime.precision >= Date.PRECISION.MONTH then -- MY date
if dateType=='Y' then
res = datetime.year
elseif dateType=='M' then
res = datetime.month
elseif dateType == 'TS' then
res = datetime:toIso8601()
end
else --Y date
if dateType=='Y' then
res = datetime.year
elseif dateType == 'TS' then
res = datetime:toIso8601()
end
end
return res
end
function parseDateRange(dateRangeStr, diffFormat, inclusive )
-- remove footnotes
dateRangeStr = mw.text.killMarkers(dateRangeStr)
dateRangeStr = mw.ustring.gsub(dateRangeStr, "‏","")
local outputPrefix = ''
local parts = mw.text.split(dateRangeStr,' *[–%-] *')
assert(#parts==2 or #parts==1, "Date range expected format is from - to or from (e.g from - now)")
-- parse dates
local t1 = Date.newFromWikitext( parts[1] )
local t2
local useCurrent = #parts<2 or (parts[2] == 'היינט' or parts[2]=='הווה' or parts[2]=='אנגייענד' or parts[2]=='איצט')
if not useCurrent then
t2 = Date.newFromWikitext( parts[2] )
else
t2 = Date.newFromIso8601(mw.getContentLanguage():formatDate('c', nil, true), true)
end
local hasYears = (diffFormat=='auto')
local hasDays = (diffFormat=='auto')
for i=1,#diffFormat do
if (diffFormat[i]=='years') then
hasYears=true
elseif diffFormat[i]=='days' then
hasDays =true
end
end
if hasDays and ((t1.precision>=Date.PRECISION.MONTH and t2.precision<Date.PRECISION.MONTH) or (t1.precision<Date.PRECISION.MONTH and t2.precision>=Date.PRECISION.MONTH)) then
-- Ambiguous date range
if t2.year - t1.year > 2 then
diffFormat = {'years'}
else
return ''
end
end
local NO_GUESS, MONTH_GUESS, DAY_GUESS = 0, 1, 2
local guessLevel = NO_GUESS
if t1.precision<Date.PRECISION.MONTH or t2.precision<Date.PRECISION.MONTH then
guessLevel = MONTH_GUESS
inclusive=true
elseif t1.precision<Date.PRECISION.DAY or t2.precision<Date.PRECISION.DAY then
guessLevel = DAY_GUESS
end
local t1 = os.time({
year = t1.year,
month = t1.month or 6,
day = t1.day or 16
})
t2= os.time({
year = t2.year,
month = t2.month or 6,
day = t2.day or 16
})
local dif = os.difftime (t2, t1)
local lang = mw.getContentLanguage()
local readableInterval = lang:getDurationIntervals(dif, {'years', 'days'})
readableInterval['days'] = readableInterval['days'] or 0
readableInterval['years'] = readableInterval['years'] or 0
if not (guessLevel==NO_GUESS) and not (guessLevel==DAY_GUESS and hasYears and #diffFormat==1 and readableInterval['days']>31) then
outputPrefix='בערך '
end
if inclusive then
dif = dif+60*60*24 -- include last day
end
if diffFormat=="auto" then
if dif<=60*60*24 then
return '' -- Ambiguous date range - we arent handling preceision of less than 1 day (hours, minutes, seconds)
end
if guessLevel==MONTH_GUESS and readableInterval['years']==0 then
return '' -- Ambiguous date range
end
--for intervals of around year
if readableInterval['years']>0 and (readableInterval['days']<30 or (365-readableInterval['days'])<30) then
-- around
if readableInterval['days']<30 then
dif = dif - readableInterval['days']*(60*60*24)
else
dif = dif+((365-readableInterval['days'])*(60*60*24))
end
diffFormat = {'years'}
else
local diffDays = dif/(60*60*24)
if diffDays<7*3 then diffFormat = { 'days' }
elseif diffDays<364 then diffFormat = {'weeks', 'days'}
elseif diffDays<10*365 then diffFormat = {'years', 'weeks'}
else diffFormat = {'years'}
end
end
end
if diffFormat=="raw" then
return dif
else
local res = outputPrefix..lang:formatDuration(dif, diffFormat)
-- post process formatDuration which is not good enough
res= mw.ustring.gsub(res,"כ־([א-ת])","כ%1")
res= mw.ustring.gsub(res,"וגם ([0-9])","ו־%1")
res= mw.ustring.gsub(res,"וגם ([א-ת])","ו%1")
return res
end
end
function parseDateRangeSafe(frame)
local diffFormat = 'auto'
if frame.args[2] == 'ימים' then
diffFormat = {'days'}
elseif frame.args[2] == 'יארן' then
diffFormat = {'years'}
elseif frame.args[2] == 'שנים וימים' then
diffFormat = {'years', 'days'}
elseif frame.args[2] == "הפרש" then
diffFormat = "raw"
elseif frame.args[2] == "גיל" then
diffFormat = {'years'}
elseif frame.args[2] == "מספר" then
diffFormat = {'years'}
end
local inclusive = (frame.args["כולל"]=="כן")
local success, res = pcall(parseDateRange, frame.args[1], diffFormat, inclusive)
if success then
local str=res
-- the following translations are needed because the underline function
-- local format is wierd
str = mw.ustring.gsub(str, "(כ)־([א-ת])", "%1%2")
if frame.args[2] == "גיל" then
str= mw.ustring.gsub(str,"כ־(.+) שנים","%1 בערך")
str= mw.ustring.gsub(str," שנים","")
end
-- This parameter returns the difference as number of years, without any text.
if frame.args[2] == "מספר" then
str= mw.ustring.gsub(str,"כ(.+)","%1");
str= mw.ustring.gsub(str,"־(.+)","%1");
str= mw.ustring.gsub(str," יאָרן","")
if str == "שנתיים" then
str = 2
end
if str == "יאר" then
str = 1
end
str = mw.ustring.gsub(str," יאָר", "")
if tonumber(str) > 0 and
tonumber(parseDateRange(frame.args[1], "raw", inclusive)) < 0 then
str = -1 * str
end
end
return str
else
return frame.args['error'] or '<span class="scribunto-error">דאטום פעלער: '..res..'</span>[[קאטעגאריע:בלעטער מיט דאטום פעלערן]]'
end
end
function parseStrDateSafe(frame)
local dateType = frame.args[2]
if dateType =='יאר' then
dateType = 'Y'
elseif dateType=='מאנאט' then
dateType = 'M'
elseif dateType=='טאג' then
dateType='D'
end
local success, res = pcall( parseStrDate, frame.args[1], dateType )
if success then
if dateType=='Y' and mw.ustring.sub( res, 0, 1)=='-' then
res = mw.ustring.sub( res, 2).. ' פד"צ'
end
return res
else
return frame.args['error'] or '<span class="scribunto-error">דאטום פעלער: '..res..'</span>[[קאטעגאריע:בלעטער מיט דאטום פעלערן]]'
end
end
function linkStrDateUnsafe(frame)
local dateStr = frame.args[1]
local linkedDateStr = dateStr
-- Strip [ and ] chars
linkedDateStr = mw.ustring.gsub(linkedDateStr, '%[', '')
linkedDateStr = mw.ustring.gsub(linkedDateStr, '%]', '')
-- Link D M Y, return [[D M]] [[Y]]
linkedDateStr = mw.ustring.gsub(linkedDateStr, '^(%d+ %a+) (%d+)$', '[[%1]] [[%2]]')
-- Link D M, return [[D M]]
if mw.ustring.find(linkedDateStr, '%[') == nil then
linkedDateStr = mw.ustring.gsub(linkedDateStr, '^(%d+) (%a+)$', '[[%1 %2]]')
end
-- Link M Y, return [[M]] [[Y]]
if mw.ustring.find(linkedDateStr, '%[') == nil then
linkedDateStr = mw.ustring.gsub(linkedDateStr, '^(%a+) (%d+)$', '[[%1]] [[%2]]')
end
-- Link Y, return [[Y]]
if mw.ustring.find(linkedDateStr, '%[') == nil then
linkedDateStr = mw.ustring.gsub(linkedDateStr, '^(%d+)$', '[[%1]]')
end
-- Unknown date string format, return the original string
if mw.ustring.find(linkedDateStr, '%[') == nil then
linkedDateStr = dateStr
end
return linkedDateStr
end
Date['רעכן'] = parseStrDateSafe;
Date['רעכן אפשטאנד'] = parseDateRangeSafe;
Date['parseDateRange'] = parseDateRange;
Date['מקושר'] = linkStrDateUnsafe;
return Date