<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
	<id>https://stockhub.co/index.php?action=history&amp;feed=atom&amp;title=Module%3ADeployment_schedule</id>
	<title>Module:Deployment schedule - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://stockhub.co/index.php?action=history&amp;feed=atom&amp;title=Module%3ADeployment_schedule"/>
	<link rel="alternate" type="text/html" href="https://stockhub.co/index.php?title=Module:Deployment_schedule&amp;action=history"/>
	<updated>2026-05-26T18:39:29Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://stockhub.co/index.php?title=Module:Deployment_schedule&amp;diff=135976&amp;oldid=prev</id>
		<title>imported&gt;Pemaksa: fix</title>
		<link rel="alternate" type="text/html" href="https://stockhub.co/index.php?title=Module:Deployment_schedule&amp;diff=135976&amp;oldid=prev"/>
		<updated>2022-10-16T10:36:21Z</updated>

		<summary type="html">&lt;p&gt;fix&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;local p = {}&lt;br /&gt;
&lt;br /&gt;
local timezones = {&lt;br /&gt;
    -- Add timezone offsets here!&lt;br /&gt;
    Z = 0,&lt;br /&gt;
    UTC = 0,&lt;br /&gt;
    PST = -8,&lt;br /&gt;
    PDT = -7,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function us_in_dst( time )&lt;br /&gt;
    -- Determine if the United States is in Daylight Savings Time (as of 2022)&lt;br /&gt;
    month = tonumber( os.date( &amp;quot;!%m&amp;quot;, time ) )&lt;br /&gt;
    day = tonumber( os.date( &amp;quot;!%d&amp;quot;, time ) )&lt;br /&gt;
    &lt;br /&gt;
    if ( month == 3 and day &amp;gt;= 10 ) then&lt;br /&gt;
        return true&lt;br /&gt;
    elseif ( month == 11 and day &amp;lt;= 3 ) then&lt;br /&gt;
        return true&lt;br /&gt;
    elseif ( month &amp;gt; 3 and month &amp;lt; 11 ) then&lt;br /&gt;
        return true&lt;br /&gt;
    else&lt;br /&gt;
        return false&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function trim( str )&lt;br /&gt;
    -- Trims a string because Wikipedia apparently doesn&amp;#039;t have this library...&lt;br /&gt;
    str = string.gsub( str, &amp;quot;%s+$&amp;quot;, &amp;quot;&amp;quot; )&lt;br /&gt;
    str = string.gsub( str, &amp;quot;^%s+&amp;quot;, &amp;quot;&amp;quot; )&lt;br /&gt;
    return str&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.row( frame )&lt;br /&gt;
    -- Produces a raw row to be reconsumed by this script for sorting&lt;br /&gt;
    -- Expects:&lt;br /&gt;
    --- when, string, like YYYY-MM-DD HH:mm XXX where XXX is a valid timezone listed in timezones&lt;br /&gt;
    --- length, number, of hours the deploy will take&lt;br /&gt;
    --- window, string, what deployment window this is (e.g. SWAT, parsoid, MediaWiki)&lt;br /&gt;
    --- who, string, who is performing the deploy&lt;br /&gt;
    --- what, string, what will be deployed&lt;br /&gt;
    -- &lt;br /&gt;
    -- Outputs: UTC Timestamp,Length,Who,What&lt;br /&gt;
    --- commas in strings are replaced with &amp;amp;#44;&lt;br /&gt;
    &lt;br /&gt;
    local when = frame.args[&amp;#039;when&amp;#039;]&lt;br /&gt;
    local length = ( tonumber( frame.args[&amp;#039;length&amp;#039;] ) or 2 ) * 60 * 60&lt;br /&gt;
    local window = frame.args[&amp;#039;window&amp;#039;] or &amp;quot;N/A&amp;quot;&lt;br /&gt;
    local who = frame.args[&amp;#039;who&amp;#039;] or &amp;quot;Anonymous Cowards (must provide &amp;#039;who=&amp;#039;)&amp;quot;&lt;br /&gt;
    local what = frame.args[&amp;#039;what&amp;#039;] or &amp;quot;Nothing? Then why is this an entry!? (must provide &amp;#039;what=&amp;#039;)&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
    who = string.gsub( who, &amp;quot;,&amp;quot;, &amp;quot;&amp;amp;#44;&amp;quot; )&lt;br /&gt;
    what = string.gsub( what, &amp;quot;,&amp;quot;, &amp;quot;&amp;amp;#44;&amp;quot; )&lt;br /&gt;
    &lt;br /&gt;
    if when == nil then&lt;br /&gt;
        utc_time = 0&lt;br /&gt;
        what = &amp;quot;No time given (must provide &amp;#039;when&amp;#039; and &amp;#039;tz&amp;#039;, e.g.: &amp;#039;when=YYYY-MM-DD HH:mm XXX&amp;#039;&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
        year, month, day, hour, minute, tz = string.match( when, &amp;#039;^(%d+)-(%d+)-(%d+) (%d+):(%d+) ([A-Z]+)$&amp;#039; )&lt;br /&gt;
        ts = os.time({&lt;br /&gt;
            year = year or 1980,&lt;br /&gt;
            month = month or 1,&lt;br /&gt;
            day = day or 1,&lt;br /&gt;
            hour = hour or 1,&lt;br /&gt;
            min = minute or 1&lt;br /&gt;
        })&lt;br /&gt;
        tz = timezones[tz]&lt;br /&gt;
        &lt;br /&gt;
        if tz == nil then&lt;br /&gt;
            utc_time = 0&lt;br /&gt;
            what = &amp;quot;Unknown timezone in &amp;#039;when&amp;#039; string! -- add it to the module :)&amp;quot;&lt;br /&gt;
        else&lt;br /&gt;
            utc_time = ts - ( tz * 60 * 60 )&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    return string.format( &amp;quot;%s,%s,%s,%s,%s&amp;quot;, utc_time, length, window, who, what )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.formatTable( frame )&lt;br /&gt;
    -- Formats a bunch of rows from p.row()&lt;br /&gt;
    local rows = {}&lt;br /&gt;
    local row&lt;br /&gt;
    local count = 1&lt;br /&gt;
    local retval = {}&lt;br /&gt;
    local sflocal&lt;br /&gt;
    local sfdatestr&lt;br /&gt;
    local showdate = not ( frame.args[&amp;#039;hidedate&amp;#039;] == &amp;#039;true&amp;#039; )&lt;br /&gt;
    local tzoffset = 0&lt;br /&gt;
    local cutcday&lt;br /&gt;
    local sftz = &amp;quot;No data&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
    -- Load and sort the arguments&lt;br /&gt;
    row = frame.args[count]&lt;br /&gt;
    while not ( row == nil ) do&lt;br /&gt;
        utc, length, window, who, what = string.match( row, &amp;#039;^(.*),(.*),(.*),(.*),(.*)$&amp;#039; )&lt;br /&gt;
        utc = tonumber( trim ( utc ) )&lt;br /&gt;
        length = tonumber( trim( length ) )&lt;br /&gt;
        who = trim( who )&lt;br /&gt;
        what = trim( what )&lt;br /&gt;
        &lt;br /&gt;
        table.insert( rows, { utc=utc, length=length, window=window, who=who, what=what } )&lt;br /&gt;
        count = count + 1&lt;br /&gt;
        row = frame.args[count]&lt;br /&gt;
    end&lt;br /&gt;
    table.sort( rows, function( a, b ) return a.utc &amp;lt; b.utc end )&lt;br /&gt;
    &lt;br /&gt;
    -- For each entry create the final row&lt;br /&gt;
    for count = 1, #rows do&lt;br /&gt;
        local datestr&lt;br /&gt;
        &lt;br /&gt;
        utc = rows[count].utc&lt;br /&gt;
        length = rows[count].length&lt;br /&gt;
        window = rows[count].window&lt;br /&gt;
        who = rows[count].who&lt;br /&gt;
        what = rows[count].what&lt;br /&gt;
        &lt;br /&gt;
        if ( cutcday ~= os.date( &amp;#039;%x&amp;#039;, utc ) ) then&lt;br /&gt;
        	-- Create a new date header in the table&lt;br /&gt;
        	table.insert( retval, &amp;quot;|-\n| colspan=&amp;#039;4&amp;#039; class=&amp;#039;deploycal-dayrow&amp;#039; | &amp;quot; .. os.date( &amp;quot;!%A,&amp;amp;nbsp;%B&amp;amp;nbsp;%d&amp;quot;, utc ) )&lt;br /&gt;
        	cutcday = os.date( &amp;#039;%x&amp;#039;, utc )&lt;br /&gt;
        end&lt;br /&gt;
        &lt;br /&gt;
        sftz = us_in_dst( utc ) and &amp;#039;PDT&amp;#039; or &amp;#039;PST&amp;#039;&lt;br /&gt;
        tzoffset = timezones[sftz]&lt;br /&gt;
        sflocal = utc + ( tzoffset * 60 * 60 )&lt;br /&gt;
        &lt;br /&gt;
        -- Determine if the SF day is different from the UTC day&lt;br /&gt;
        if os.date( &amp;quot;!%A&amp;quot;, utc ) ~= os.date( &amp;quot;!%A&amp;quot;, sflocal ) then&lt;br /&gt;
			sfdatestr = os.date( &amp;quot;!&amp;lt;small&amp;gt;(%a)&amp;lt;/small&amp;gt; &amp;quot;, sflocal )&lt;br /&gt;
		else&lt;br /&gt;
			sfdatestr = &amp;quot;&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
        &lt;br /&gt;
        table.insert( retval, string.format( [[ |- id=&amp;quot;deploycal-item-%s&amp;quot; class=&amp;quot;deploycal-item&amp;quot;&lt;br /&gt;
        		| &amp;lt;span class=&amp;quot;deploycal-time-utc&amp;quot;&amp;gt;%s&amp;amp;ndash;%s&amp;amp;nbsp;UTC&amp;lt;/span&amp;gt; &amp;lt;br/&amp;gt; &amp;lt;span class=&amp;quot;deploycal-time-sf&amp;quot;&amp;gt;%s %s&amp;amp;ndash;%s&amp;amp;nbsp;%s&amp;lt;/span&amp;gt;&lt;br /&gt;
        		| &amp;lt;span class=&amp;quot;deploycal-window&amp;quot;&amp;gt;%s&amp;lt;/span&amp;gt;&lt;br /&gt;
        		| %s&lt;br /&gt;
        		| %s&lt;br /&gt;
        	]],&lt;br /&gt;
        	os.date( &amp;quot;!%Y%m%dT%H%M&amp;quot;, utc ),&lt;br /&gt;
            &amp;#039;&amp;lt;time class=&amp;quot;deploycal-starttime&amp;quot; datetime=&amp;quot;&amp;#039; .. os.date( &amp;quot;!%Y-%m-%dT%H:%M+00:00&amp;quot;, utc ) .. &amp;#039;&amp;quot;&amp;gt;&amp;#039; ..&lt;br /&gt;
            	os.date( &amp;quot;!%H:%M&amp;quot;, utc ) .. &amp;#039;&amp;lt;/time&amp;gt;&amp;#039;,&lt;br /&gt;
            &amp;#039;&amp;lt;time class=&amp;quot;deploycal-endtime&amp;quot; datetime=&amp;quot;&amp;#039; .. os.date( &amp;quot;!%Y-%m-%dT%H:%M+00:00&amp;quot;, utc + length ) .. &amp;#039;&amp;quot;&amp;gt;&amp;#039; ..&lt;br /&gt;
            	os.date( &amp;quot;!%H:%M&amp;quot;, utc + length ) .. &amp;quot;&amp;lt;/time&amp;gt;&amp;quot;,&lt;br /&gt;
            sfdatestr,&lt;br /&gt;
            &amp;#039;&amp;lt;time class=&amp;quot;deploycal-starttime&amp;quot;  datetime=&amp;quot;&amp;#039; .. os.date( &amp;quot;!%Y-%m-%dT%H:%M+&amp;quot; .. tzoffset .. &amp;quot;:00&amp;quot;, sflocal ) .. &amp;#039;&amp;quot;&amp;gt;&amp;#039; ..&lt;br /&gt;
            	os.date( &amp;quot;!%H:%M&amp;quot;, sflocal ) .. &amp;quot;&amp;lt;/time&amp;gt;&amp;quot;,&lt;br /&gt;
            &amp;#039;&amp;lt;time class=&amp;quot;deploycal-endtime&amp;quot; datetime=&amp;quot;&amp;#039; .. os.date( &amp;quot;!%Y-%m-%dT%H:%M+&amp;quot; .. tzoffset .. &amp;quot;:00&amp;quot;, sflocal + length ) .. &amp;#039;&amp;quot;&amp;gt;&amp;#039; ..&lt;br /&gt;
            	os.date( &amp;quot;!%H:%M&amp;quot;, sflocal + length ) .. &amp;quot;&amp;lt;/time&amp;gt;&amp;quot;,&lt;br /&gt;
            sftz,&lt;br /&gt;
            window,&lt;br /&gt;
            who,&lt;br /&gt;
            what&lt;br /&gt;
        ))&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    return string.format( [[&lt;br /&gt;
	    {| class=&amp;#039;wikitable deploycal&amp;#039;&lt;br /&gt;
	        !Time&lt;br /&gt;
	        !Component&lt;br /&gt;
	        !Deployer&lt;br /&gt;
	        !Changes&lt;br /&gt;
    	]], sftz ) .. table.concat( retval, &amp;quot;\n&amp;quot; ) .. &amp;quot;\n|}&amp;quot;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.dateOf( frame )&lt;br /&gt;
    local requestedday = frame.args[1] or &amp;#039;Sun&amp;#039;&lt;br /&gt;
    local tdelta = 0&lt;br /&gt;
    local weekstart = 0&lt;br /&gt;
    local adddays = 0&lt;br /&gt;
    &lt;br /&gt;
    day, hour, minute, sec = string.match( os.date(&amp;#039;!%w %H %m %S&amp;#039;), &amp;#039;^(%d+) (%d+) (%d+) (%d+)$&amp;#039; )&lt;br /&gt;
    tdelta = ( tonumber( day ) * 24 * 60 * 60 ) + ( tonumber( hour) * 60 * 60 ) + ( tonumber( minute ) * 60 ) + tonumber( sec )&lt;br /&gt;
    weekstart = os.time() - tdelta&lt;br /&gt;
    &lt;br /&gt;
    if ( requestedday == &amp;#039;Mon&amp;#039; ) then&lt;br /&gt;
        adddays = 1&lt;br /&gt;
    elseif ( requestedday == &amp;#039;Tue&amp;#039; ) then&lt;br /&gt;
        adddays = 2&lt;br /&gt;
    elseif ( requestedday == &amp;#039;Wed&amp;#039; ) then&lt;br /&gt;
        adddays = 3&lt;br /&gt;
    elseif ( requestedday == &amp;#039;Thu&amp;#039; ) then&lt;br /&gt;
        adddays = 4&lt;br /&gt;
    elseif ( requestedday == &amp;#039;Fri&amp;#039; ) then&lt;br /&gt;
        adddays = 5&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    return os.date( &amp;#039;%Y-%m-%d&amp;#039;, weekstart + ( adddays * 24*60*60 ) )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.header( frame )&lt;br /&gt;
    -- In my young and dumb days, this created a header for formatTable.&lt;br /&gt;
    -- We still need it because the archive page calls it (though it no longer needs to)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.footer( frame )&lt;br /&gt;
    -- In my young and dumb days, this created a footer for formatTable.&lt;br /&gt;
    -- We still need it because the archive page calls it (though it no longer needs to)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>imported&gt;Pemaksa</name></author>
	</entry>
</feed>