יחידה:תאריך: הבדלים בין גרסאות בדף
שקט הוא רפש שקט הוא רפש שקט הוא רפש שקט הוא רפש שקט הוא רפש שקט הוא רפש שקט הוא רפש שקט הוא רפש שקט הוא רפש שקט הוא רפש שקט הוא רפש שקט הוא רפש ש |
מ 3 גרסאות של הדף wikipedia:he:יחידה:תאריך יובאו |
||
| (45 גרסאות ביניים של 8 משתמשים אינן מוצגות) | |||
| שורה 1: | שורה 1: | ||
local Date = {} | 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 | --Internal functions | ||
| שורה 20: | שורה 29: | ||
local function validate(definition) | local function validate(definition) | ||
--Validate constants | --Validate constants | ||
if | if not Date.knowsPrecision(definition.precision) or | ||
(definition.calendar ~= Date.CALENDAR.GREGORIAN and definition.calendar ~= Date.CALENDAR.JULIAN) then | (definition.calendar ~= Date.CALENDAR.GREGORIAN and definition.calendar ~= Date.CALENDAR.JULIAN) then | ||
return false | return false | ||
| שורה 155: | שורה 164: | ||
end | end | ||
-- | --offset | ||
if offset ~= nil then | if offset ~= nil then | ||
if offset == 'Z' then | if offset == 'Z' then | ||
| שורה 199: | שורה 208: | ||
return ((year % 4) == 0) and | return ((year % 4) == 0) and | ||
(not (((year % 100) == 0) and ((year % 400) ~= 0))) | (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 | end | ||
| שורה 247: | שורה 263: | ||
end | end | ||
local function le(t1, t2) | -- 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 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 | end | ||
if t1.year < t2.year then | if t1.year < t2.year then | ||
| שורה 355: | שורה 444: | ||
['דצמבר']= 12 | ['דצמבר']= 12 | ||
} | } | ||
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 ] | -- Remove instances of [ and ] | ||
wikitext = mw.ustring.gsub( wikitext, "[%[%]]", "" ) | wikitext = mw.ustring.gsub( wikitext, "[%[%]]", "" ) | ||
| שורה 363: | שורה 456: | ||
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") | ||
for a in pairs(months) do | for a in pairs(months) do | ||
wikitext = mw.ustring.gsub(wikitext, 'ב?'..a, months[a]) | wikitext = mw.ustring.gsub(wikitext, ' ?ב?'..a, ' ' .. months[a]) | ||
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 | end | ||
-- if there are alphabet chars return nil (unexpected character) | -- if there are alphabet chars return nil (unexpected character) | ||
assert(not mw.ustring.find(wikitext, '%a'), "Unexpected format") | assert(not mw.ustring.find(wikitext, '%a'), "Unexpected format") | ||
local parts = mw.text.split(mw.text.trim(wikitext),' ') | |||
local parts = mw.text.split(wikitext,' ') | |||
local definition = {} | local definition = {} | ||
definition.calendar = calendar | |||
if #parts==3 then -- DMY date | if #parts==3 then -- DMY date | ||
definition.year = tonumber(parts[3]) | definition.year = tonumber(parts[3]) | ||
| שורה 451: | שורה 548: | ||
end | end | ||
return iso .. ':' .. prepend( self.second, '0', 2 ) .. formatUtcOffsetForIso( self.utcoffset ) | 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 | end | ||
| שורה 460: | שורה 644: | ||
function Date:toString( language ) | function Date:toString( language ) | ||
if language == nil then | if language == nil then | ||
language = | return self:toIso8601() | ||
end | |||
if language == 'he' then | |||
return self:toHebrewString() | |||
end | |||
--[[if type( language ) == 'string' then | |||
language = mw.language.new( language ) | language = mw.language.new( language ) | ||
end | end | ||
return language:formatDate( 'r', self:toIso8601() )]] | |||
return self:toIso8601() | return self:toIso8601() | ||
end | end | ||
| שורה 517: | שורה 705: | ||
return false | return false | ||
end | end | ||
function Date.age(time1, time2) | function Date.age(time1, time2) | ||
| שורה 530: | שורה 710: | ||
time2 = Date.newFromIso8601(mw.getContentLanguage():formatDate('c', nil, true), true) | time2 = Date.newFromIso8601(mw.getContentLanguage():formatDate('c', nil, true), true) | ||
end | 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 | if time1.year < 0 and time2.year > 0 then | ||
age = age - 1 | age.year = age.year - 1 | ||
end | end | ||
return age | |||
end | end | ||
function Date:formatDate(options) | function Date:formatDate(options) | ||
| שורה 610: | שורה 802: | ||
function parseDateRange(dateRangeStr, diffFormat, inclusive ) | function parseDateRange(dateRangeStr, diffFormat, inclusive ) | ||
-- remove footnotes | -- remove footnotes | ||
dateRangeStr = mw. | dateRangeStr = mw.text.killMarkers(dateRangeStr) | ||
dateRangeStr = mw.ustring.gsub(dateRangeStr, "‏","") | dateRangeStr = mw.ustring.gsub(dateRangeStr, "‏","") | ||
local outputPrefix = '' | local outputPrefix = '' | ||
local parts = mw.text.split(dateRangeStr,' | 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)") | assert(#parts==2 or #parts==1, "Date range expected format is from - to or from (e.g from - now)") | ||
| שורה 620: | שורה 812: | ||
local t1 = Date.newFromWikitext( parts[1] ) | local t1 = Date.newFromWikitext( parts[1] ) | ||
local t2 | local t2 | ||
local useCurrent = #parts<2 or (parts[2] == 'היום' or parts[2]=='הווה') | |||
if not useCurrent then | |||
t2 = Date.newFromWikitext( parts[2] ) | t2 = Date.newFromWikitext( parts[2] ) | ||
else | else | ||
| שורה 637: | שורה 831: | ||
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 | 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 | end | ||
local NO_GUESS, MONTH_GUESS, DAY_GUESS = 0, 1, 2 | local NO_GUESS, MONTH_GUESS, DAY_GUESS = 0, 1, 2 | ||
| שורה 647: | שורה 846: | ||
guessLevel = DAY_GUESS | guessLevel = DAY_GUESS | ||
end | end | ||
local t1 = os.time({ | local t1 = os.time({ | ||
year = t1.year, | year = t1.year, | ||
| שורה 671: | שורה 870: | ||
end | end | ||
if diffFormat=="auto" then | 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 | if guessLevel==MONTH_GUESS and readableInterval['years']==0 then | ||
return '' -- Ambiguous date range | return '' -- Ambiguous date range | ||
| שורה 679: | שורה 880: | ||
if readableInterval['years']>0 and (readableInterval['days']<30 or (365-readableInterval['days'])<30) then | if readableInterval['years']>0 and (readableInterval['days']<30 or (365-readableInterval['days'])<30) then | ||
-- around | -- around | ||
dif = dif- | if readableInterval['days']<30 then | ||
dif = dif - readableInterval['days']*(60*60*24) | |||
else | |||
dif = dif+((365-readableInterval['days'])*(60*60*24)) | |||
end | |||
diffFormat = {'years'} | diffFormat = {'years'} | ||
else | else | ||
| שורה 689: | שורה 894: | ||
end | end | ||
end | end | ||
end | end | ||
if diffFormat=="raw" then | if diffFormat=="raw" then | ||
return dif | return dif | ||
else | 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 | ||
end | end | ||
| שורה 704: | שורה 914: | ||
elseif frame.args[2] == 'שנים' then | 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" | ||
| שורה 711: | שורה 923: | ||
diffFormat = {'years'} | diffFormat = {'years'} | ||
end | end | ||
local inclusive= (frame.args["כולל"]=="כן") | local inclusive = (frame.args["כולל"]=="כן") | ||
local success, res = pcall(parseDateRange, frame.args[1], diffFormat, inclusive) | local success, res = pcall(parseDateRange, frame.args[1], diffFormat, inclusive) | ||
if success then | if success then | ||
local str=res | local str=res | ||
-- the following translations are needed because the underline function | -- the following translations are needed because the underline function | ||
-- local format is wierd | -- local format is wierd | ||
str = mw.ustring.gsub(str, | str = mw.ustring.gsub(str, "(כ)־([א-ת])", "%1%2") | ||
if frame.args[2] == "גיל" then | if frame.args[2] == "גיל" then | ||
| שורה 740: | שורה 949: | ||
str = 1 | str = 1 | ||
end | end | ||
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 | ||
| שורה 761: | שורה 971: | ||
dateType='D' | dateType='D' | ||
end | end | ||
local success, res = pcall( parseStrDate, frame.args[1], dateType ) | local success, res = pcall( parseStrDate, frame.args[1], dateType ) | ||
if success then | if success then | ||
| שורה 772: | שורה 982: | ||
end | 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 | end | ||
| שורה 777: | שורה 1,014: | ||
Date['חשב טווח'] = parseDateRangeSafe; | Date['חשב טווח'] = parseDateRangeSafe; | ||
Date['parseDateRange'] = parseDateRange; | Date['parseDateRange'] = parseDateRange; | ||
Date['מקושר'] = linkStrDateUnsafe; | |||
return Date | return Date | ||