[Question]
  [
Monday, October 31st, is Halloween. And it got me thinking -- I wonder what other months have the last day of the month *also* be a Monday?
### Input
* A positive integer [in any convenient format](http://meta.codegolf.stackexchange.com/q/2447/42963) representing a year, `10000 > y > 0`.
* The input can be padded with zeros (e.g., `0025` for year `25`) if
required.
### Output
* A list of the months of that year where the last day of the month is a Monday.
* This can be as month names (e.g., `January, March, October`), or shortnames (`Jan, Mar, Oct`), or numbers (`1, 3, 10`), as separate lines or a list or delimited, etc., just so long as it's unambiguous to the reader.
* The output format must be consistent:
	+ For all years input (meaning, you can't output month names for some inputs, and month numbers for other inputs)
	+ As well as consistent per output (meaning, you can't output `1` for `January` in the same output as `Jul` for `July`)
	+ Basically, pick one format and stick to it.
### Rules
* Assume the Gregorian calendar for input/output, even down to `y = 1`.
* Leap years must be properly accounted for (as a reminder: every year divisible by 4, except not years divisible by 100, unless also divisible by 400 -- 1700, 1800, 1900 all weren't leap years, but 2000 was).
* You may use any built-ins or other date calculation tools you like.
* Either a full program or a function are acceptable. If a function, you can return the output rather than printing it.
* [Standard loopholes](http://meta.codegolf.stackexchange.com/q/1061/42963) are forbidden.
* This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'") so all usual golfing rules apply, and the shortest code (in bytes) wins.
### Examples
```
   1 --> Apr, Dec
 297 --> May
1776 --> Sep
2000 --> Jan, Jul
2016 --> Feb, Oct
3385 --> Jan, Feb, Oct
```
---
### Leaderboard
```
var QUESTION_ID=97585,OVERRIDE_USER=42963;function answersUrl(e){return"https://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"https://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text()),s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}});var t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o]);t.sort(function(e,s){return e.lang>s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
```
```
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
```
```
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table>
```
  
[Answer]
# JavaScript (Firefox 30+), ~~112~~ ~~109~~ ~~103~~ 95 bytes
Look ma, no built-ins!
```
y=>[for(m of(i=0,y%4|y%400*!(y%100)&&6)+"63153042641")if((i++,y+(y>>2)-(y/100|0)*3/4|0)%7==m)i]
```
Here's a 107-byte ES6 version:
```
y=>[...(y%4|y%400*!(y%100)&&6)+"63153042641"].map((m,i)=>(y+(y>>2)-(y/100|0)*3/4|0)%7-m?0:i+1).filter(x=>x)
```
And here's my previous attempt, ~~123~~ 113 bytes of ES6:
```
y=>[(l=y%4|y%400*!(y%100))?[7]:[1,7],[4,12],[9],[3,6],[8,11],[5],l?[1,2,10]:[2,10]][(y+(y>>2)-(y/100|0)*3/4|0)%7]
```
## Explanation
The day of the week of a particular year is calculated like so:
```
y+(y>>2)-(y/100|0)*3/4|0)%7
```
In other words:
* Take `y`.
* Add the number of 4th years before `y` (`y>>2`).
* Subtract the number of 100th years before `y` (`y/100|0`).
* Add back in the number of 400th years before `y`; this is 1/4 of `y/100|0`, so we use `*3/4|0`.
Then we modulo the result by 7. If we let `0` mean Sunday, `1` mean Monday, etc., the result corresponds to the day of the week of December 31st of that year. Therefore, for December, we want to check if the result is `1`. This gives us the last char in the string.
The last day of November is 31 days before the last day of December. This means that for the last day of November to be a Monday, Dec 31 needs to be a `(1 + 31) % 7 = 4` = Thursday.
This procedure is repeated until we get back to March (a `3`). Whether or not there is a leap day, the last day of February is 31 days before the last day of March, so we can calculate that too (it's `(3 + 31) % 7 = 6`). The tricky part is finding the correct value for January:
* If it is a leap year, the last day of January is 29 days before the last day of Feb, resulting in `(6 + 29) % 7 = 0`.
* Otherwise, it is 28 days before the last day of Feb, resulting in `(6 + 28) % 7 = 6`.
We can calculate whether or not it is a leap year with the following snippet:
```
!(y%400)|y%100*!(y%4)
```
This gives `0` if `y` is not a leap year, and a positive integer otherwise. This leads us to
```
!(y%400)|y%100*!(y%4)?0:6
```
for calculating the day for January. However, we can do better by reversing the conditions:
```
y%4|y%400*!(y%100)?6:0
```
Since the falsy result is always 0 anyway, we can reduce it to
```
y%4|y%400*!(y%100)&&6
```
saving one more precious byte.
Putting it all together, we loop through each char in the string, checking if each is equal to the day of the week of Dec 31st. We keep the indexes of the ones that match, returning this array in the end. And that is how you do leap year calculations without built-ins.
[Answer]
## JavaScript (Firefox 30-57), ~~67~~ ~~65~~ ~~64~~ ~~63~~ 61 bytes
```
y=>[for(_ of(m='')+1e11)if(new Date(y+400,++m).getDay()==2)m]
```
Saved ~~2~~ ~~4~~ 6 bytes thanks to @ETHproductions. ~~Saved another byte by outputting the months in reverse order.~~
[Answer]
# MySQL, ~~183~~ ~~134~~ ~~129~~ 106 bytes
```
SET @y=2016;SELECT help_topic_id AS m FROM mysql.help_topic HAVING m BETWEEN 1 AND 12 AND 2=DAYOFWEEK(LAST_DAY(CONCAT(@y,-m,-1)))
```
Replace `2016` with the desired year. Run.
Rev. 2: Used the `help_topics` table in the default installation instead of creating a temporary table.
Rev.3: Adopted [aross´s `-` trick](https://codegolf.stackexchange.com/a/97697#97697) and noticed I can also omit the quotes for `"-1"`.  
However, `-1` is required in MySQL: I need a full date.
Rev.4: Restriction `m BETWEEN 1 AND 12` could be done as `m>0 AND m<13` (-6), but is not needed at all - invalid values will be ignored; warnings will be counted but not listed.
[Answer]
# Perl, 64 bytes
Includes +1 for `-n`
Give input on STDIN:
```
perl -M5.010 mon.pl <<< 2016
```
`mon.pl`:
```
#!/usr/bin/perl -n
map$b.=$/.gmtime$_.e4,-7e6..3e7;say$b=~/on (\S+ )\S.* $_.* 1 /g
```
[Answer]
## Batch, ~~160~~ 152 bytes
```
@set/ay=%1,m=0,j=6*!(!(y%%4)*(y%%100)+(y%%400)),y=(y*5/4-y/100*3/4)%%7
@for %%d in (%j% 6 3 1 5 3 0 4 2 6 4 1)do @set/am+=1&if %%d==%y% call echo %%m%%
```
Port of @ETHproduction's answer. With month abbreviations for ~~197~~ 189 bytes:
```
@set/ay=%1,j=6*!(!(y%%4)*(y%%100)+(y%%400)),y=(y*5/4-y/100*3/4)%%7
@for %%m in (Jan.%j% Feb.6 Mar.3 Apr.1 May.5 Jun.3 Jul.0 Aug.4 Sep.2 Oct.6 Nov.4 Dec.1)do @if %%~xm==.%y% call echo %%~nm
```
[Answer]
# Mathematica, ~~62~~ 57 bytes
```
DayName@DayRange[{#},{#+1},"EndOfMonth"]~Position~Monday&
```
Anonymous function. Takes a number as input and returns a list of single-element lists of numbers as output. I'm honestly not sure myself how it works anymore.
[Answer]
# Perl+cal, 46 bytes
```
say`cal $_ $ARGV[0]`=~/\n.{5}\n/&&$_ for 1..12
```
Example:
```
$ perl -E 'say`cal $_ $ARGV[0]`=~/\n.{5}\n/&&$_ for 1..12' 2016
2
10
$
```
[Answer]
# J, ~~48~~ ~~34~~ 33 bytes
```
[:I.(2=7|_2#@".@,@{.])&>@calendar
```
Saved 15 bytes with help from @[Adám](https://codegolf.stackexchange.com/users/43319/ad%c3%a1m).
Uses the calendar builtin to generate an array of strings representing the months, then parses each string to determine the whether the last Monday is the last day of the month. It outputs each month as the month number of each. That is, `Jan = 0`, `Feb = 1`, ..., `Dec = 11`.
The output of `calendar` is
```
   _3 ]\ calendar 2016
┌─────────────────────┬─────────────────────┬─────────────────────┐
│         Jan         │         Feb         │         Mar         │
│ Su Mo Tu We Th Fr Sa│ Su Mo Tu We Th Fr Sa│ Su Mo Tu We Th Fr Sa│
│                 1  2│     1  2  3  4  5  6│        1  2  3  4  5│
│  3  4  5  6  7  8  9│  7  8  9 10 11 12 13│  6  7  8  9 10 11 12│
│ 10 11 12 13 14 15 16│ 14 15 16 17 18 19 20│ 13 14 15 16 17 18 19│
│ 17 18 19 20 21 22 23│ 21 22 23 24 25 26 27│ 20 21 22 23 24 25 26│
│ 24 25 26 27 28 29 30│ 28 29               │ 27 28 29 30 31      │
│ 31                  │                     │                     │
├─────────────────────┼─────────────────────┼─────────────────────┤
│         Apr         │         May         │         Jun         │
│ Su Mo Tu We Th Fr Sa│ Su Mo Tu We Th Fr Sa│ Su Mo Tu We Th Fr Sa│
│                 1  2│  1  2  3  4  5  6  7│           1  2  3  4│
│  3  4  5  6  7  8  9│  8  9 10 11 12 13 14│  5  6  7  8  9 10 11│
│ 10 11 12 13 14 15 16│ 15 16 17 18 19 20 21│ 12 13 14 15 16 17 18│
│ 17 18 19 20 21 22 23│ 22 23 24 25 26 27 28│ 19 20 21 22 23 24 25│
│ 24 25 26 27 28 29 30│ 29 30 31            │ 26 27 28 29 30      │
│                     │                     │                     │
├─────────────────────┼─────────────────────┼─────────────────────┤
│         Jul         │         Aug         │         Sep         │
│ Su Mo Tu We Th Fr Sa│ Su Mo Tu We Th Fr Sa│ Su Mo Tu We Th Fr Sa│
│                 1  2│     1  2  3  4  5  6│              1  2  3│
│  3  4  5  6  7  8  9│  7  8  9 10 11 12 13│  4  5  6  7  8  9 10│
│ 10 11 12 13 14 15 16│ 14 15 16 17 18 19 20│ 11 12 13 14 15 16 17│
│ 17 18 19 20 21 22 23│ 21 22 23 24 25 26 27│ 18 19 20 21 22 23 24│
│ 24 25 26 27 28 29 30│ 28 29 30 31         │ 25 26 27 28 29 30   │
│ 31                  │                     │                     │
├─────────────────────┼─────────────────────┼─────────────────────┤
│         Oct         │         Nov         │         Dec         │
│ Su Mo Tu We Th Fr Sa│ Su Mo Tu We Th Fr Sa│ Su Mo Tu We Th Fr Sa│
│                    1│        1  2  3  4  5│              1  2  3│
│  2  3  4  5  6  7  8│  6  7  8  9 10 11 12│  4  5  6  7  8  9 10│
│  9 10 11 12 13 14 15│ 13 14 15 16 17 18 19│ 11 12 13 14 15 16 17│
│ 16 17 18 19 20 21 22│ 20 21 22 23 24 25 26│ 18 19 20 21 22 23 24│
│ 23 24 25 26 27 28 29│ 27 28 29 30         │ 25 26 27 28 29 30 31│
│ 30 31               │                     │                     │
└─────────────────────┴─────────────────────┴─────────────────────┘
```
## Usage
```
   f =: [:I.(2=7|_2#@".@,@{.])&>@calendar
   f 1
3 11
   f 297
4
   f 1776
8
   f 2000
0 6
   f 2016
1 9
   f 3385
0 1 9
```
## Explanation
```
[:I.(2=7|_2#@".@,@{.])&>@calendar  Input: year Y
                         calendar  Get 12 boxes each containing a month
    (                )&>@          Operate on each box
                    ]                Identity, get the box
         _2       {.                 Take the last two strings
                ,@                   Flatten it
             ".@                     Parse it into an array of integers
           #@                        Get the length
       7|                            Take it modulo 7
     2=                              Test if it equals 2 - it will either
                                     have two days or 9 days in the last
                                     two lines if the end is on a Monday
[:I.                               Return the indices containing a true value
```
[Answer]
# C, 119 bytes
```
t=1248700335,m;main(y){for(scanf("%d",&y),t+=y&3||y%25<1&&y&15;m++,(6+y+y/4-y/100+y/400+t)%7||printf("%d,",m),t;t/=7);}
```
This uses a table that contains the offset of the weekdays of the last day of every month for a leap year, encoded in a signed 32-bit word using base 7. If it is not a leap year we add 1 to the offset of January (as you can see `y&3||y%25<1&&y&15` is used to check for years without leap days). Then we simply loop through every month and check if its last day is a Monday. Quite simple actually, no ugly hacks or tricks. Here it is slightly ungolfed:
```
t=1248700335,m;
main(y){
  for(
    scanf("%d",&y),t+=y&3||y%25<1&&y&15;
    m++,(6+y+y/4-y/100+y/400+t)%7||printf("%d,",m),t;
    t/=7
  );
}
```
I might revisit this to rewrite it as a function to save a few characters. The `printf` also takes up a little too much space...
[Answer]
# Java 7 ,~~186 182~~ 172 bytes
*Thanks to kevin for saving 4 bytes*  
*Thanks to @cliffroot for saving 10 bytes*
```
int[]f(int n){int c=n-1,x=c*365+c/4+c/400-c/100,k=0,b[]={3,(n%4<1&n%100>0)|n%400<1?1:0,3,2,3,2,3,3,2,3,2,3},a[]=new int[12];for(int i:b)a[k++]=(x+=i+28)%7==1?1:0;return a;}
```
# ungolfed
```
int[] f(int n) {
 int c=n-1,x=c*365+(c/4)+(c/400)-(c/100),k=0,
   b[] = {3,(n % 4 < 1 & n % 100 > 0) | n % 400 < 1 ? 1 : 0
                                     ,3,2,3,2,3,3,2,3,2,3},a = new int[ 12 ];
 if ( (n % 4 < 1 & n % 100 > 1) | n % 400 < 1 )
     b[ 1 ] = -1;
 for (int i : b)
    a[ k++ ] = (x += i + 28) % 7 == 1 ? 1 : 0;
return a;
     }
```
This version is provide by [@cliffroot](https://codegolf.stackexchange.com/users/53197/cliffroot)(**168 bytes**)
```
 static int[] f(int n) {
 int b = 13561787 | ( (n%4 < 1 & n%100 > 0) | n%400 < 1 ? 1 << 20 : 0 ),
           x = --n*365 + n/4 + n/400 - n/100,a[]=new int[12],k=0;
    while (k < 12)
    a[k++] = (x += (b >> 24 - k*2&3 ) + 28) % 7 == 1 ? 1 : 0;
  return a;   }
    }
```
# output sample
```
1 1 0 0 0 0 0 0 0 1 0 0(for input 3385)
```
[Answer]
# [MATL](http://github.com/lmendo/MATL), 21 bytes
```
12:"G@QhO6(YO9XO77=?@
```
Months are displayed as numbers.
[Try it online!](http://matl.tryitonline.net/#code=MTI6IkdAUWhPNihZTzlYTzc3PT9A&input=MjAxNg) Or [verify all test cases](http://matl.tryitonline.net/#code=IkBYS3gKMTI6IktAUWhPNihZTzlYTzc3PT9ACl1dJmhE&input=WzEgMjk3IDE3NzYgMjAwMCAyMDE2IDMzODVd).
### Explanation
This uses date conversion builtin functions. For the given year it tests which months' last day is Monday.
Instead of explicitly specifying the last day of month `k` (which may be 28, 29, 30 or 31), we specify the `0`-th day of month `k+1`, which is equivalent and does not depend on month or year.
```
12:      % Push [1 2 ... 12] (months)
"        % For each month k
  G      %   Push input
  @Q     %   Push k+1
  h      %   Concatenate
  O6(    %   Postpend four zeros. For example, for input 2016 and month k=1 
         %   (first iteration) this gives [2016 2 0 0 0 0] (year, month, day,
         %   hour, min, sec). The 0-th day of month k+1 is the same as the
         %   last day of month k.
  YO     %   Convert the above 6-element date vector to date number
  9XO    %   Convert date number to date string with output format 9, which 
         %   is weekday as a capital letter
  77=    %   Is it an 'M'?
  ?      %   If so
    @    %     Push current month (will be implicitly displayed)
```
[Answer]
# Bash + GNU utilities, 56 bytes
```
seq -f1month-1day$1-%g-1 12|date -f- +%B%u|sed -n s/1//p
```
Appears to require `date` version 8.25. The 8.23 version in Ideone doesn't cut it.
[Answer]
# Excel, 537 bytes
Because – you know – Excel!
Takes input year in A1. Returns hexadecimal list of months; 1=January, C= December. Since each month is a single digit, no separator is needed.
```
=IF(2=WEEKDAY(EOMONTH(DATE(A1,1,1),0)),1,"")&IF(2=WEEKDAY(EOMONTH(DATE(A1,2,1),0)),2,"")&IF(2=WEEKDAY(EOMONTH(DATE(A1,3,1),0)),3,"")&IF(2=WEEKDAY(EOMONTH(DATE(A1,4,1),0)),4,"")&IF(2=WEEKDAY(EOMONTH(DATE(A1,5,1),0)),5,"")&IF(2=WEEKDAY(EOMONTH(DATE(A1,6,1),0)),6,"")&IF(2=WEEKDAY(EOMONTH(DATE(A1,7,1),0)),7,"")&IF(2=WEEKDAY(EOMONTH(DATE(A1,8,1),0)),8,"")&IF(2=WEEKDAY(EOMONTH(DATE(A1,9,1),0)),9,"")&IF(2=WEEKDAY(EOMONTH(DATE(A1,10,1),0)),"A","")&IF(2=WEEKDAY(EOMONTH(DATE(A1,11,1),0)),"B","")&IF(2=WEEKDAY(EOMONTH(DATE(A1,12,1),0)),"C","")
```
Example: A1 contains 2016. B1 contains the above formula, and displays as `2A`, meaning February and October.
[Answer]
## PHP, 109 180 159 bytes
```
for($z=$argv[1];$m++<12;)if(date(N,strtotime(sprintf("%04d-$m-",$z).cal_days_in_month(0,$m,$z)))<2)echo"$m,";
```
* Outputs the provided year, not all of them (... always read the question)
* Ignored notices (thanks Titus)
* Change `while` to `for` as it's now a single year (again, thanks Titus)
### Old 2
```
$z=0;while($z++<9999){$o=[];$m=0;while($m++<12)if(date("N",strtotime(sprintf("%04d-$m-","$z").cal_days_in_month(0,$m,$z)))<2)$o[]=$m;echo count($o)>0?"$z:".implode(",",$o)."
":"";}
```
Supports all years from dot to 10000, also got rid of an undefined var warning I wasn't aware of on one PC. Yes it's longer than the old version, but it's more robust.
### Old 1
```
while($z++<9999){$o=[];$m=0;while($m++<12)if(date("N",strtotime("$z-$m-".cal_days_in_month(0,$m,$z)))<2)$o[]=$m;echo count($o)>0?"$z:".implode(",",$o)."
":"";}
```
If running on Windows or a 32bit system there will be the dreaded 2038 bug, but on a 64bit linux system it's fine.
I did attempt to use `date("t"...` which is meant to represent the last date of the given month, but the results didn't match those previously mentioned in this thread.
[Answer]
# PHP, 92 Bytes
```
for($d=new DateTime("$argv[1]-1-1");$i++<12;)$d->modify("1month")->format(w)!=2?:print"$i,";
```
check 12 times 1 month after first day of a year is a tuesday. If it is then is the day before the last day in the month is a monday. 
[Answer]
# C, 214 bytes
```
main(int a,char *b[]){for(int x,y,d,m=12;m;m--){y=atoi(b[1]);x=m-1;d=x==1?(y%4==0?(y%100==0?(y%400==0?29:28):29):28):(x==3||x==5||x==10?30:31);if((d+=m<3?y--:y-2,23*m/9+d+4+y/4-y/100+y/400)%7==1)printf("%d\n",m);}}
```
# Compile
```
gcc -std=c99 -o foo foo.c
```
# Ungolfed
With credits to the relevant gurus. 
*Michael Keith* and *Tom Craver* for [C Program to find day of week given date](https://stackoverflow.com/questions/6054016/c-program-to-find-day-of-week-given-date).
*Collin Biedenkapp* for [Q&A: How do I figure out what the last day of the month is?](https://stackoverflow.com/questions/15630821/qa-how-do-i-figure-out-what-the-last-day-of-the-month-is)
```
/* credit to Collin Biedenkapp */
short _get_max_day(short x, int z) {
    if(x == 0 || x == 2 || x == 4 || x == 6 || x == 7 || x == 9 || x == 11)
        return 31;
    else if(x == 3 || x == 5 || x == 8 || x == 10)
        return 30;
    else {
        if(z % 4 == 0) {
            if(z % 100 == 0) {
                if(z % 400 == 0)
                    return 29;
                return 28;
            }
            return 29;
        }
        return 28;
    }
}
main(int argc,char *argv[]) {
 for(int y,d,m=12;m;m--) {
  y=atoi(argv[1]);
  d=_get_max_day(m-1,y);
  /* credit to Michael Keith and Tom Craver */
  if ((d+=m<3?y--:y-2,23*m/9+d+4+y/4-y/100+y/400)%7 == 1)
    printf("%d\n",m);
 }
}
```
[Answer]
# PHP, ~~96~~ ~~95~~ ~~76~~ ~~71~~ ~~69~~ ~~64~~ 61 bytes
Note: year numbers must be padded to 4 chars, like `0070`.
```
for(;13+$i-=1;)date(N,mktime(0,0,0,1-$i,0,$argn))-1||print$i;
```
Run like this:
```
echo 3385 | php -nR 'for(;13+$i-=1;)date(N,mktime(0,0,0,1-$i,0,$argn))-1||print$i;';echo
> -1-2-10
```
# Explanation
Iterates from -1 to -12. Create date using mktime, day `0` (the last day of the previous month) and month `2..13`. Format the date as **day number**, and if the result is 1, print the current number. The negative sign `-` is used as the delimiter.
# [The Millenium Bug Strikes Again!](https://en.wikipedia.org/wiki/Year_2000_problem)
Note that with this version, the range `0..100` is interpreted as `1970..2069`. This is no problem for the range `0..69`, as weeks have a pattern that repeats every 400 years (146097 days, exactly 20871 weeks), but for the range `70..99`, 1900 is added to the year number, which is not a multiple of 400. To fix that problem JUST for 30 year numbers in a range of 10k, the simplest way is to add 400 to the year number to prevent the 2-digit interpretation (**+4 bytes**):
```
for(;13+$i-=1;)date(N,mktime(0,0,0,1-$i,0,$argn+400))-1||print$i;
```
# Tweaks
* Saved a byte by using `!~-$i` to compare `$i` with `1` (`-1` binary negated is `0`, logically negated is `true`; every other number is `false`), so parentheses aren't needed
* Saved 19 bytes by using `last day ofYYYY-m` notation to create the date
* Saved 5 bytes by using `date` and `strtotime` instead of `date_create`
* Saved 2 bytes by counting from negative numbers, using the negative sign as output delimiter (negative month numbers don't exist) and also as delim in the `YYYY-m` part of the date
* Saved 5 bytes by using `mktime` instead of `strtotime`. Reverted to using day `0` (`mktime` also supports month 13, so `0-13`==`31-12`)
* Saved 3 bytes by using `-R` to make `$argn` available
[Answer]
# Excel, ~~428~~ ~~97~~ 96 bytes
Input in A1. Output un-separated Hexadecimal values (January = 0, December = B)
```
=IF(2=WEEKDAY(DATE(A1+2000,1,31)),0,"")&CHOOSE(WEEKDAY(DATE(A1+2000,3,0)),4,19,6,"3B",8,25,"7A")
```
Added 10 bytes ("+2000") to allow handling of pre-1990 dates.
Saved 11 bytes thanks to @[Engineer Toast](https://codegolf.stackexchange.com/users/38183/engineer-toast).
---
First attempt (428 bytes), borrowing heavily from @[Adám](https://codegolf.stackexchange.com/users/43319/ad%c3%a1m)'s solution.
```
=IF(2=WEEKDAY(DATE(A1,1,31)),1,"")&IF(2=WEEKDAY(EOMONTH(DATE(A1,2,1),0)),2,"")&IF(2=WEEKDAY(DATE(A1,3,31)),3,"")&IF(2=WEEKDAY(DATE(A1,4,30)),4,"")&IF(2=WEEKDAY(DATE(A1,5,31)),5,"")&IF(2=WEEKDAY(DATE(A1,6,30)),6,"")&IF(2=WEEKDAY(DATE(A1,7,31)),7,"")&IF(2=WEEKDAY(DATE(A1,8,31)),8,"")&IF(2=WEEKDAY(DATE(A1,9,30)),9,"")&IF(2=WEEKDAY(DATE(A1,10,31)),"A","")&IF(2=WEEKDAY(DATE(A1,11,30)),"B","")&IF(2=WEEKDAY(DATE(A1,12,31)),"C","")
```
[Answer]
# Python 2, 122 bytes
Ugh. Math with dates isn't as simple as I'd like.
```
from datetime import*
lambda y:[m+1for m in range(12)if(date(y,12,31)if m>10else(date(y,m+2,1)-timedelta(1))).weekday()<1]
```
[**Try it online**](https://repl.it/EHKa)
**Same length:**
```
from datetime import*
lambda y:[m-1for m in range(2,14)if(date(y,12,31)if m>12else(date(y,m,1)-timedelta(1))).weekday()<1]
```
[Answer]
# [Dyalog APL](http://goo.gl/9KrKoM) with [dfns](http://dfns.dyalog.com/)'s [cal](http://dfns.dyalog.com/n_cal.htm), Version 15.0: 22; Version 16.0: 19 [bytes](http://meta.codegolf.stackexchange.com/a/9429/43319)
The cal function comes with a default install, just enter `)copy dfns`.
### Version 15.0: `∊⎕{⍵/⍨2=≢⍎⊢⌿cal⍺⍵}¨⍳12`
`∊` enlist (flatten)
`⎕{`...`}¨` numeric input as left argument to the following anonymous function, taking each of the right side values as right argument in turn
 `⍵/⍨` the argument if (gives an empty list if not)
 `2=` two (namely Sunday and Monday) is equal to
 `≢` the tally of
 `⍎` the numbers in
 `⊢⌿` the bottom-most row of
 `cal` the calendar for
 `⍺⍵` year left-argument, month right-argument, the latter being
`⍳12` 1 to 12
### Version 16.0: `⍸2=⎕{≢⍎⊢⌿cal⍺⍵}¨⍳12`
`⍸` the indices where
`2=` two equals (namely Sunday and Monday)
`⎕{`...`}¨` numeric input as left argument to the following anonymous function, taking each of the right side values as right argument in turn
 `≢` the tally of
 `⍎` the numbers in
 `⊢⌿` the bottom-most row of
 `cal` the calendar for
 `⍺⍵` year left-argument, month right-argument, the latter being
`⍳12` 1 to 12
[Answer]
# Bash+cal, 58 bytes
```
$ cat t.sh
for A in {1..12};do cal $A $1|grep -qx .....&&echo $A;done
$ bash t.sh 2016
2
10
$
```
[Answer]
# Python 2, 94 bytes
```
from datetime import*
lambda y:[m for m in range(1,13)if date(y+(m>11),m%12+1,1).weekday()==1]
```
**[repl.it](https://repl.it/EHX5/1)**
An unnamed function, takes an integer year, outputs a list of the month numbers `[1-12]`.
I also tried to beat the byte count with arithmetic without success (110 bytes). :
```
lambda y:map(lambda x,v:(23*((x+2)%13or 1)/9+y-2*(0<x<11)+(x>10)+v/4-v/100+v/400)%7==4,range(12),[y-1]+[y]*11)
```
An unnamed function which returns a list of boolean values representing if the months [Jan-Dec] end in a Monday
[Answer]
# Java 7, ~~200~~ 249 bytes
```
import java.util.*;String c(int y){String r="";GregorianCalendar c=new GregorianCalendar();c.setGregorianChange(new Date(1L<<63));c.set(1,y);c.set(2,0);for(int i=0;i++<12;c.add(2,1)){c.set(5,c.getActualMaximum(5));if(c.get(7)==2)r+=i+" ";}return r;}
```
In Java, `GregorianCalendar` is a mix between a Gregorian and Julian calendar. Because of this, year `1` gave incorrect results. Changing `Calendar c=Calendar.getInstance();` to `GregorianCalendar c=new GregorianCalendar();c.setGregorianChange(new Date(1L<<63));` fixes this by forcing a use of the Gregorian calendar only. [Thanks to *@JonSkeet* on stackoverflow.com for explaining this to me.](https://stackoverflow.com/questions/40280182/calendar-giving-unexpected-results-for-year-1/40280292#40280292)
**Ungolfed & test code:**
[Try it here.](https://ideone.com/ZAwjCg)
```
import java.util.*;
class M{
  static String c(int year){
    String r = "";
    GregorianCalendar calendar = new GregorianCalendar();
    calendar.setGregorianChange(new Date(Long.MIN_VALUE));
    calendar.set(Calendar.YEAR, year);
    calendar.set(Calendar.MONTH, 0);
    for(int i = 0; i++ < 12; calendar.add(Calendar.MONTH, 1)){
      calendar.set(Calendar.DATE, calendar.getActualMaximum(Calendar.DATE));
      if(calendar.get(Calendar.DAY_OF_WEEK) == 2){
        r += i+" ";
      }
    }
    return r;
  }
  public static void main(String[] a){
    System.out.println(c(1));
    System.out.println(c(297));
    System.out.println(c(1776));
    System.out.println(c(2000));
    System.out.println(c(2016));
    System.out.println(c(3385));
  }
}
```
**Output:**
```
4 12
5 
9 
1 7 
2 10 
1 2 10 
```
[Answer]
# ~~C#6~~ C#, ~~171~~ ~~167~~ 135 bytes
```
using System;
void d(int n){for(int i=0;++i<13;)if((int)new DateTime(n,i,DateTime.DaysInMonth(n,i)).DayOfWeek==1)Console.Write(i+" ");}
```
*-32 bytes thanks to Shebang*
Print months as numbers; with space delimited; with trailing space. Now this answer also works for earlier versions of C#.
---
Old, 167 bytes
```
using System;using System.Linq;
c(int n)=>string.Join(",",Enumerable.Range(1,12).Where(i=>new DateTime(n,i,DateTime.DaysInMonth(n,i)).DayOfWeek==(DayOfWeek)1));
```
*-4 bytes thanks to TimmyD*
Output months are numbers in return string, comma delimited
Ungolfed
```
string c(int n)=>
    string.Join(",",                                        // Join them with commas
        Enumerable.Range(1,12)                              // For 1-12 inclusive
        .Where(                                             // Select only
            i=>new DateTime(n,i,DateTime.DaysInMonth(n,i)   // Get last day of that year-month
            ).DayOfWeek                                     // Get its day of week
            ==(DayOfWeek)1                              // Is Monday
        )
    )
;
```
[Answer]
## Ruby, 54 + 6 = 60 bytes
```
λ cat monday.rb
p (1..12).select{|m|Date.new($*[0].to_i,m,-1).monday?}
λ ruby -rdate monday.rb 2016
[2, 10]
```
6 bytes for `-rdate` on the command line to get the Date class from the standard library.
Explanation: pretty straightforward thanks to the Ruby stdlib's great `Date` class. Not only does it have methods like `monday?`, `tuesday?`, etc, the constructor will take negative numbers for any field past year to mean 'count this field backwards from the end of the period represented by the previous field'. `$*` is shorthand for `ARGV`, so `$*[0]` is a quick way to get the first command line argument.
[Answer]
# R, ~~106~~ ~~99~~ ~~95~~ ~~83~~ ~~78~~ ~~77~~ 74 bytes
```
g=function(x)which(format(seq(as.Date(paste0(x,-2,-1)),,'m',12)-1,"%u")<2)
```
The sequence of last days of each month is given by `seq(as.Date(paste0(x,-2,-1)),,'m',12)-1`:
* `paste0` coerces -2 and -1 to characters. If the `x` was 2016 for instance, `paste0(x,-2,-1)` gives `"2016-2-1"` which is then converted to the 1st of February 2016 by `as.Date`.
* `seq` applied to a POSIXct or a Date object is `seq(from, to , by, length.out)`: here `to` is not given, `by` is given as `'m'` which is matched to `'month'` thanks to partial matching, and `length.out` is of course 12.
* The resulting sequence is the first day of the 12 months starting with February of the year in question. `-1` gives us then the last day of the 12 months starting with January of the year in question.
Test cases:
```
> g(1)
[1]  4 12
> g(25)
[1] 3 6
> g(297)
[1] 5
> g(2000)
[1] 1 7
> g(2016)
[1]  2 10
> g(3385)
[1]  1  2 10
> g(9999)
[1] 5
```
**Old version at 95 bytes, outputting the month names instead of just their numbers:**
```
g=function(x)format(S<-seq(as.Date(sprintf("%04i-02-01",x)),,'m',12)-1,"%B")[format(S,"%u")==1]
```
[Answer]
# Japt, 24 bytes
```
Do1 £Ov"Ð400+U"+X e ¥2©X
```
[**Test it online!**](http://ethproductions.github.io/japt/?v=master&code=RG8xIKNPdiLQNDAwK1UiK1ggZSClMqlY&input=MjAxNg==) Outputs an array of numbers, with `false` in place of months that don't end in a Monday.
There was a bug in the interpreter that didn't allow me to use `Ð` in the function body `£`. After the bug fix and another feature addition, this is 18 bytes in the current commit:
```
Do1@Ð400+UX e ¥2©X
```
[Answer]
# Java, ~~143~~ 129 bytes
This uses the new time API of Java 8.
```
y->{String s="";for(int m=0;++m<13;)if(java.time.YearMonth.of(y,m).atEndOfMonth().getDayOfWeek().ordinal()==0)s+=m+" ";return s;}
```
## Output
Note that each line has an extra space at the end.
```
4 12 
5 
9 
1 7 
2 10 
1 2 10 
```
## Ungolfed and testing
```
import java.time.*;
import java.util.function.*;
public class Main {
    public static void main (String[] args) {
        IntFunction<String> func = year -> {
          String result = "";
          for (int month=1; month <= 12; month++) {
            if (YearMonth.of(year, month).atEndOfMonth().getDayOfWeek().ordinal() == 0) {
              result += month + " ";
            }
          }
          return result;
        };
        System.out.println(func.apply(1));
        System.out.println(func.apply(297));
        System.out.println(func.apply(1776));
        System.out.println(func.apply(2000));
        System.out.println(func.apply(2016));
        System.out.println(func.apply(3385));
    }
}
```
## Shaves
1. 143 to 129 bytes: use `DayOfWeek::ordinal` to compare with a numerical constant instead of the enum constant.  
Thanks @TimmyD for the general idea if not the exact solution! ;-)
[Answer]
# GNU awk, 80 bytes
```
{for(;m<13;a=mktime($0" "++m" 1 9 0 0")){if(strftime("%w",a-8e4)~1){print m-1}}}
```
Example
```
$ gawk '{for(;m<13;a=mktime($0" "++m" 1 9 0 0")){if(strftime("%w",a-8e4)~1){print m-1}}}' <<<2016
2
10
$
```
[Answer]
# PHP, 109 bytes
```
$y=$argv[1];for($i;++$i<13;)echo(date('N',strtotime($y."-$i-".date('t',strtotime("$y-$i-1"))))==1?"$i ":'');
```
The code produces a notice due to `for($i;` but the question mentions nothing about avoiding errors.
---
Outputs months numbers separated by a space.
```
   1 --> 1 12 
 297 --> 5 
1776 --> 9 
2000 --> 1 7 
2016 --> 2 10 
3385 --> 1 2 10 
```
---
Works in PHP 5.2.16 and onward at <http://sandbox.onlinephpfunctions.com/>
]