יחידה:תאריך
מראה
יחידה זו מיועדת לביצוע פעולות נפוצות על תאריכים.
- #חשב - מקבלת תאריך טקסטואלי ופורמט ומחלצת את מהתאריך את הפורמט הרצוי
- #חשב טווח - מקבלת טווח תאריכים ומחשבת את ההפרש ביניהם
חשב
| פורמט | דוגמה | תוצאה |
|---|---|---|
| יום | {{#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-2-3 |
הערות:
- פורמט TS ניתן להעביר לפונקציות זמן של הוראות תנאי.
- ההמרה מתעלמת מסוגריים מרובעות של קישורים
- ניתן להוסיף פרמטר error והתוכן שלו יוצג במקרה של שגיאה בתאריך. (רצוי להכניס במקרה כזה את הדף לקטגוריה כלשהי שתאפשר מעקב אחרי דפים לא תקינים. ברירת המחדל היא קטגוריה:דפים עם שגיאות בתאריך)
חשב טווח
| דוגמה | תוצאה | |
|---|---|---|
| פורמט ברירת מחדל: אוטומטי | {{#invoke:תאריך|חשב טווח|[[3 בפברואר]] [[1947]] - [[15 בספטמבר]] [[2013]]}} | 66 שנים |
| פורמט ברירת מחדל: אוטומטי (דוגמה עם שנים וסימן מינוס) | {{#invoke:תאריך|חשב טווח|1947 - 2013}} | כ־66 שנים |
| פורמט ברירת מחדל: אוטומטי (דוגמה עם שנים וסימן קו מפריד) | {{#invoke:תאריך|חשב טווח|1947–2013}} | שגיאת תאריך: יחידה:תאריך:66: attempt to compare nil with number |
| שנים | {{#invoke:תאריך|חשב טווח|[[3 בפברואר]] [[1947]] - [[15 בספטמבר]] [[2013]]|שנים}} | 66 שנים |
| גיל | {{#invoke:תאריך|חשב טווח|1 במרץ 1922 - 4 בנובמבר 1995|גיל}} | 73 |
| גיל | {{#invoke:תאריך|חשב טווח|1 במרץ 1922{{הערה|ב}} - 4 בנובמבר 1995|גיל}} | 73 |
| גיל | {{#invoke:תאריך|חשב טווח|1 במרץ 1994{{הערה|ב}} - 4 בנובמבר 1995|גיל}} | שנה |
| גיל | {{#invoke:תאריך|חשב טווח|1 במרץ 1993{{הערה|ב}} - 4 בנובמבר 1995|גיל}} | שנתיים |
| מספר | {{#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]]|שנים}} | 79 שנים |
| לא כולל היום האחרון | {{#invoke:תאריך|חשב טווח|5 ביוני 1967 - 10 ביוני 1967}} | 5 ימים |
| כולל היום האחרון | {{#invoke:תאריך|חשב טווח|5 ביוני 1967 - 10 ביוני 1967|כולל=כן}} | 6 ימים |
| כולל היום האחרון | {{#invoke:תאריך|חשב טווח|14 ספטמבר 2014 - 14 ספטמבר 2014|כולל=כן}} | יום |
| שנה ויום | {{#invoke:תאריך|חשב טווח|14 ספטמבר 2014 - 15 ספטמבר 2015|כולל=כן}} | שנה |
הערות:
- כאשר לא ניתן תאריך יעד תאריך היעד נקבע כזמן הנוכחי
- הפרש - מציין את הפרש הזמנים בשניות וללא מילים. ניתן להשתמש בערך המוחזר בחלוקה מתאימה לקבלת יחידות זמן אחרות.
- ניתן להוסיף פרמטר כולל=כן, ואז נלקח בחשבון גם היום האחרון. כשמדובר על טווח זמן ארוך והפורמט נבחר אוטומטי או שמכיל שנים, מתקבלת תוצאה מקורבת.
- ניתן להוסיף פרמטר error והתוכן שלו יוצג במקרה של שגיאה בטווח התאריכים. (רצוי להכניס במקרה כזה את הדף לקטגוריה כלשהי שתאפשר מעקב אחרי דפים לא תקינים. ברירת המחדל היא קטגוריה:דפים עם שגיאות בתאריך)
- אם לא מצוין פורמט, הוא נבחר אוטומטית:
- עד ל-3 שבועות הוא מוצג בימים
- עד שנה הוא מוצג בימים ושבועות
- עד ל-10 שנים בשנים ושבועות
- מעבר לזה רק בשנים
בדיקות
דוגמאות לשימוש ביחידה ופלט לדוגמה מודגמים ביחידה:תאריך/בדיקות.
function parseStrDate(dateStr, dateType)
local dates = {
['ינואר']= 1,
['פברואר']= 2,
['מרץ']= 3,
['אפריל']= 4,
['מאי']= 5,
['יוני']= 6,
['יולי']= 7,
['אוגוסט']= 8,
['ספטמבר']= 9,
['אוקטובר']= 10,
['נובמבר']= 11,
['דצמבר']= 12
}
-- Remove instances of [ and ]
dateStr = mw.ustring.gsub( dateStr, "[%[%]]", "" )
-- Remove footnotes & directionality markers
dateStr = mw.text.killMarkers( dateStr )
dateStr = mw.ustring.gsub(dateStr, "‏","")
dateStr = mw.ustring.gsub(dateStr, "‎","")
mw.log('תאריך' .. ":" .. dateStr)
-- BC to minus
dateStr = mw.ustring.gsub( dateStr, "([0-9]+) לפנה\"ס" , "-%1")
-- replace month names to numbers. The month number will be 10000001..10000012,
-- in order to facilitate testing later on.
for a in pairs(dates) do
dateStr = mw.ustring.gsub(dateStr, 'ב?'..a, dates[a]+1e7)
end
-- if there are alphabet chars return nil (unexpected character)
assert(not mw.ustring.find(dateStr, '%a'), "Unexpected format")
local parts = mw.text.split(dateStr,' ')
local res
if #parts==3 then -- DMY date
local ye=tonumber(parts[3])
local mo=tonumber(parts[2])-1e7
local da=tonumber(parts[1])
assert(ye<1e7, "Could not recognize year")
assert(mo<13 and mo>0, "Could not recognize month number")
assert(da<32 and da>0, "Wrong date format")
if dateType=='Y' then
res = ye
elseif dateType=='M' then
res = mo
elseif dateType=='D' then
res = da
elseif dateType == 'TS' then
res = ye.."-"..mo.."-"..da
end
elseif #parts==2 then -- MY date
local ye=tonumber(parts[2])
local mo=tonumber(parts[1]) - 1e7
assert(ye<1e7, "Could not recognize year")
assert(mo<13 and mo>0, "Could not recognize month number")
if dateType=='Y' then
res = ye
elseif dateType=='M' then
res = mo
elseif dateType == 'TS' then
res = ye.."-"..mo
end
elseif #parts==1 then --Y date
local ye=tonumber(parts[1])
assert(ye<1e7, "Could not recognize year")
if dateType=='Y' then
res = ye
elseif dateType == 'TS' then
res = ye
end
else
error("Unexpected date format")
end
return res
end
function parseDateRange(dateRangeStr, diffFormat, inclusive )
-- remove footnotes
dateRangeStr = mw.ustring.gsub(dateRangeStr, "(\127UNIQ[^\127]+QINU\127)", "")
dateRangeStr = mw.ustring.gsub(dateRangeStr, "‏","")
mw.log("טווח תאריכים:" .. 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 res1 = parseStrDate(parts[1], 'TS' )
local year1, month1, day1
if mw.ustring.sub( res1, 0, 1 ) == '-' then
year1, month1, day1 = unpack(mw.text.split(mw.ustring.sub( res1, 2 ), '-'))
year1 = -(tonumber(year1))
else
year1, month1, day1 = unpack(mw.text.split( res1, '-'))
end
local origDay=day1
local origMonth=month1
local t2
local year2, month2, day2
if #parts==2 then
local res2 = parseStrDate( parts[2], 'TS' )
if mw.ustring.sub( res2, 0, 1 ) == '-' then
year2, month2, day2 = unpack(mw.text.split(mw.ustring.sub( res2, 2 ), '-'))
year2 = -(tonumber(year2))
else
year2, month2, day2 = unpack(mw.text.split( res2, '-'))
end
else
t2 = os.time()
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 ((month1 and not month2 and not t2) or (not month1 and month2)) then
return '' -- Ambiguous date range
end
local NO_GUESS, MONTH_GUESS, DAY_GUESS = 0, 1, 2
local guessLevel = NO_GUESS
if not month1 or (not t2 and not month2) then
guessLevel = MONTH_GUESS
inclusive=true
elseif not day1 or (not t2 and not day2) then
guessLevel = DAY_GUESS
end
--assign default value
month1 = month1 or 6
month2 = month2 or 6
day1 = day1 or 16
day2 = day2 or 16
local t1 = os.time({
year = year1,
month = month1,
day = day1
})
t2=t2 or os.time({
year = year2,
month = month2,
day = day2
})
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 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
dif = dif-((readableInterval['days']<30 and 1) or -1)*readableInterval['days']*(60*60*24)
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
return outputPrefix..lang:formatDuration(dif, diffFormat)
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 = "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")
str= mw.ustring.gsub(str,"וגם ([0-9])","ו-%1")
str= mw.ustring.gsub(str,"וגם ([א-ת])","ו%1");
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
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
return {
['חשב'] = parseStrDateSafe,
['חשב טווח'] = parseDateRangeSafe,
['parseDateRange'] = parseDateRange,
}