Home
Random
Recent changes
Special pages
Community portal
Preferences
About Stockhub
Disclaimers
Search
User menu
Talk
Contributions
Create account
Log in
Editing
Module:Sandbox/RexxS/CalcDate
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
--[[ CalcDate Modified from chunks of Module:Time Main function: getYearMonthDay takes a date string like "second Friday in June" as parameter |date= and a year as parameter |year= (uses current year if omitted) and returns the date in YYYY-MM-DD format, e.g. 2018-06-08 Other formats are possible. ]] require ('strict') --[[ is_set(var) Whether variable is set or not. A variable is set when it is not nil and not empty. ]] local function is_set(var) return var and var ~= '' end --[[ current_year() returns the current year ]] local function current_year() return os.date('%Y', os.time()) end --[[ decode_date_event(date_event_string) extract ordinal, day-name, and month from daylight saving start/end definition string as digits: Second Sunday in March returns 2 0 3 Case doesn't matter but the form of the string does: <ordinal> <day> <any single word> <month> β all are separated by spaces ]] local function decode_date_event(date_event_string) local ordinals = { ['1st'] = 1, ['first'] = 1, ['2nd'] = 2, ['second'] = 2, ['3rd'] = 3, ['third'] = 3, ['4th'] = 4, ['fourth'] = 4, ['5th'] = 5, ['fifth'] = 5, ['last'] = -1 } local days = { ['sunday'] = 0, ['monday'] = 1, ['tuesday'] = 2, ['wednesday'] = 3, ['thursday'] = 4, ['friday'] = 5, ['saturday'] = 6 } local months = { ['january'] = 1, ['february'] = 2, ['march'] = 3, ['april'] = 4, ['may'] = 5, ['june'] = 6, ['july'] = 7, ['august'] = 8, ['september'] = 9, ['october'] = 10, ['november'] = 11, ['december'] = 12 } date_event_string = date_event_string:lower() local ord, day, month = date_event_string:match ('([%a%d]+)%s+(%a+)%s+%a+%s+(%a+)') if is_set(ord) and is_set(day) and is_set(month) then return ordinals[ord], days[day], months[month] else -- if one or more of these not set, then pattern didn't match return nil end end --[[ get_days_in_month(year, month) Returns the number of days in the month where month is a number 1β12 and year is four-digit Gregorian calendar. Accounts for leap year. Throws an error if month and year are not numbers. ]] local function get_days_in_month(year, month) local days_in_month = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} year = tonumber (year) month = tonumber (month) if month == 2 and year%4 == 0 and (year%100 ~= 0 or year%400 == 0) then return 29 end return days_in_month [month] end --[[ get_date_month_day(date_event_string, year) Return the date for the day that is the ordinal (nth) day-name in month of the given year e.g. "second Friday in June", 2018 -> 2018-06-08 ]] local function get_date_month_day(date_event_string, year) local ord, weekday_num, month = decode_date_event(date_event_string) if not (is_set (ord) and is_set (weekday_num) and is_set (month)) then return nil end if ord == -1 then -- event occurs on the last day-name of the month -- j = t + 7Γ(n + 1) - (wt - w) mod 7 local days_in_month = get_days_in_month (year, month) local ostime = os.time ({['year']=year, ['month']=month, ['day']=days_in_month}) local last_day_of_month = os.date('%w', ostime) return month, days_in_month + 7 * (ord + 1) - ((last_day_of_month - weekday_num) % 7) else -- j = 7Γn - 6 + (w - w1) mod 7 local ostime = os.time({['year']=year, ['month']=month, ['day']=1}) local first_day_of_month = os.date('%w', ostime) return month, 7 * ord - 6 + (weekday_num - first_day_of_month) % 7 end end -- set up public functions for debugging local p = {} p.currentYear = current_year p.getDateMonth = function(frame) local m, d = get_date_month_day(frame.args.date, frame.args.year) return m .. "-" .. d end --[[ getYearMonthDay Takes a date string like "second Friday in June" as parameter |date= and a year as parameter |year= and returns the date in YYYY-MM-DD format, e.g. 2018-06-08 Other formats are easy to implement. ]] p.getYearMonthDay = function(frame) local args = frame.args or frame:getParent().args local date_event = args.date or mw.text.trim(args[1]) local year = args.year or args[2] or current_year() local month, day = get_date_month_day(date_event, year) month = (month<10 and "0" or "") .. month day = (day<10 and "0" or "") .. day return year .. "-" .. month .. "-" .. day end return p
Summary:
Please note that all contributions to Stockhub may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see
Stockhub:Copyrights
for details).
Do not submit copyrighted work without permission!
Cancel
Editing help
(opens in new window)
Template used on this page:
Module:Sandbox/RexxS/CalcDate/doc
(
edit
)