[Question]
  [
Write a function or program that takes string inputs, fully-spelled, English month names in title case: `January`, `February`, `March`, etc. (null/CR/LF terminated OK, delimited with some non-alpha character if you so choose) and either
* compares two inputs, returning a Truthy value if the second input is greater (in month order) than the first. Equal values result in a Falsey value
* or sorts an arbitrary sequence (list, delimited string, etc.) of them in chronological order
(The crux of the challenge is defining a method/expression that gives the correct lexicographical sort. Some languages might have a shorter answer with one or the other)
You cannot use any internal time parsing methods (e.g. `strptime`) to translate the month name into a number or a pre-canned mapping of month names. Use properties of the strings themselves, a parsimonious look-up table you define, or something clever.
# Example
Functioning examples, though the first is prohibited by the rules...
```
import datetime
def is_later_month(a, b):
    '''
    Example of prohibited code because it relies on language 
    features about how to parse month names
    '''
    return datetime.strptime(a, '%B') < datetime.strptime(b, '%B') 
```
The below versions are OK though, because we code that info
```
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,
}
def is_later_month(a, b):
    """
    Returns True/False when comparing two months.
    """
    return months[a] < months[b]
```
Or you could do a sorting function
```
months = {'as above...'}
def sort_months(l):
    """
    Sorts list and returns it. Different input and output than the above, 
    but equally valid. Sorting versus comparing might be shorter in your
    favorite language.
    """
    return sorted(l, key=lambda x: months[x]) 
```
Example tests
```
assert is_later_month('January', 'February')
assert is_later_month('January', 'December')
assert is_later_month('November', 'December')
assert not is_later_month('July', 'July')
assert not is_later_month('October', 'September')
```
  
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 19 [bytes](https://github.com/DennisMitchell/jelly/wiki/Code-page)
```
11ị“bMAanlseovc”iµÞ
```
This is a monadic link that takes a list as argument and sorts it. [Try it online!](http://jelly.tryitonline.net/#code=MTHhu4vigJxiTUFhbmxzZW92Y-KAnWnCtcOeCuG6isOHauKBtyAgICAgICAgICAgICAgICAgIOG4t-KAnCDhuoogc2h1ZmZsZXMgdGhlIGxpc3QsIMOHIGFwcGxpZXMgdGhlIGxpbmssIGrigbcgam9pbnM&input=&args=IkphbnVhcnkiLCAiRmVicnVhcnkiLCAiTWFyY2giLCAiQXByaWwiLCAiTWF5IiwgIkp1bmUiLCAiSnVseSIsICJBdWd1c3QiLCAiU2VwdGVtYmVyIiwgIk9jdG9iZXIiLCAiTm92ZW1iZXIiLCAiRGVjZW1iZXIi)
### Background
Jelly uses modular, 1-based indexing. If we repeat the months names often enough to obtain 11 characters, we get the following array.
```
J a n u a r y J a n u
F e b r u a r y F e b
M a r c h M a r c h M
A p r i l A p r i l A
M a y M a y M a y M a
J u n e J u n e J u n
J u l y J u l y J u l
A u g u s t A u g u s
S e p t e m b e r S e
O c t o b e r O c t o
N o v e m b e r N o v
D e c e m b e r D e c
```
In the 11th (last) column, all characters are different, so we can use them to identify the order of the months.
### How it works
```
11ị“bMAanlseovc”iµÞ  Monadic link. Argument: A (array of months)
                 µ   Combine the preceding chain into a link.
                  Þ  Sort A by that link.
11ị                    Select the 11th character of the month's name.
   “bMAanlseovc”       Find the index of that character in "bMAanlseovc".
                       For 'u' ("January"), this returns 0 (not found).
```
[Answer]
# x86 machine code, 26 25 bytes
Hexdump:
```
ff 32 8b 01 34 c0 68 30 5f 43 01 59 f7 e1 91 5a
80 f2 c0 f7 e2 3b c8 d6 c3
```
Assembly code:
```
    push dword ptr [edx];
    mov eax, [ecx];
    xor al, 0xc0;
    push 0x01435f30;
    pop ecx;
    mul ecx;
    xchg eax, ecx;
    pop edx;
    xor dl, 0xc0;
    mul edx;
    cmp ecx, eax;
    _emit 0xd6;
    ret;
```
The following hash function happens to put the month names in the proper order (found by brute force):
```
(x ^ 0xc0) * 0x01435f30
```
It is applied to the first 4 bytes (32 bits) of the input string, arranged in little-endian order. Then comparing the result and using `SALC` to set the result register (al):
* -1 (true) if the months are in order
* 0 (false) if the second month precedes the first month (or they are the same)
[Answer]
## [Jelly](https://github.com/DennisMitchell/jelly), 15 [bytes](https://github.com/DennisMitchell/jelly/wiki/Code-page)
```
Oḅ32 354*%991µÞ
```
No online interpreter link here because this is one *slow* submission. The program uses the hashing function `354^(input interpreted as base 32 int) % 991` as the sort key, which happens to give outputs in the right order. The program won't finish any time soon because the results of the exponentiation are giant - for "September", a number with 0.24 quadrillion digits needs to be calculated!
Jelly explanation:
```
              Þ         Sort by...
             µ          Monadic link consisting of...
O                       Convert month string to code points
 ḅ32                    Take base 32
     354*               Perform 354 to the power of the result
         %991           Take modulo 991
```
Python proof of concept script - note the use of `pow` for modular exponentiation, which is much more efficient:
```
import random
def base_convert(string, base):
    total = 0
    for c in string:
        total = total * base + ord(c)
    return total
def month_hash(month):
    return pow(354, base_convert(month, 32), 991)
months = ["January", "February", "March", "April", "May", "June", "July",
    "August", "September", "October", "November", "December"]
random.shuffle(months)
print(months)
print(sorted(months, key=month_hash))
```
[Answer]
# Python, ~~64~~ ~~61~~ 57 bytes
```
lambda x,y,g='bMAanlseovc'.find:g((x*4)[10])<g((y*4)[10])
```
The lambda takes two months as input and compares them. Test it on [Ideone](http://ideone.com/deFYC2).
*Thanks to @ljeabmreosn for golfing off 3 bytes and paving the way for 3 more!*
[Answer]
## Python, ~~81~~ 71 bytes
```
lambda x,y,m='anebarprayunulugepctovec':m.index(x[1:3])<m.index(y[1:3])
```
<https://repl.it/CluN/1>
Compares the index in `m` of the second and third letters of two months.
83 byte version to sort a list of months:
```
lambda x:sorted(x,key=lambda i:'JanFebMarAprMayJunJulAugSepOctNovDec'.index(i[:3]))
```
[Answer]
# [Julia 1.0](http://julialang.org/), 28 bytes
```
~m=hash("lWbAj"*m)
m^n=~m<~n
```
[Try it online!](https://tio.run/##dcwxa8MwEIbhXb9CvUlqJ3c0McTQekumQIcmhnNRqjPSOUh2my7@646dYhcK3u69D566c4TJdRh6n1mMVoF7q/IaHr0WvuSs95uehy4Sf8oXbE2UQlwCcavgELrWkompBC220TbfEp1T777h1jJ6o0iXf1FreW6CJEkskzR5vlc9FT1NfdIzXKCLd/cf/KBW6VU7SWmEf2XHCo78ekV/cSO/4JCPs4MS9s2X8ZUJMA@FqUKH4WfclnPedji9dxg@LIjhBg "Julia 1.0 – Try It Online")
This solution prepends a string to each month before calculating the hash. The magic values in this and the other solutions were found by brute force.
## Simple hash, 29 bytes
```
~m=hash(m)%69675331
m^n=~m<~n
```
[Try it online!](https://tio.run/##dczBa8IwFMfxe/6KLCAkeIqyjpUJCurNnXbbVnhKZl5JXiVptbv0X@/ajnYw8Pa@7wefvHIIum7bxq8sRCu9miXPydPjcqmZz2jV@JeG2ioinfkWShM5Y5eAVErxFqrSookpF4qtoy1uHJyT776g0hJ4I1Flf5Er/lUEjhyJ61Qvhsr7wnnfn2qE9@Di4P6DH@Rd@q6tU@zgX9mRFB@0q8FfXMdPuNh0sxOZeC2uxh9NEOOwN8dQQfjutukctwP07wOEkxWs/QE "Julia 1.0 – Try It Online")
## String repetition + modulo, 29 bytes
```
~m=hash(m^69)%22670
m*n=~m<~n
```
[Try it online!](https://tio.run/##dcwxa8MwEIbhXb9CEQQkd6k9pMQk0ELjzZ26JSmcg1Kdkc5Bstt08V93bQe7UMh2733wlI1FiK9d17qtgWCk@1it1TJJVk@PzEW0bd2mpa4JSJ/8FWodOGMXj1RL8e6b2qAOKReKPQdTfXOwVu5dRbUhcFqiiv6iVPxceY4cicdpnIxVDoUPQx/VBGdgw@j@gxfyLn3XjlPs4ZtsSYoD7a7gLrbnZ1y89LMVkXirvrQrtBfTkOnCN@B/@m0@py2H4Z2DPxnBul8 "Julia 1.0 – Try It Online")
[Answer]
# Ruby, 58 bytes
Uses the month sorting trick from [@atlasologist's answer](https://codegolf.stackexchange.com/a/89455/52194).
```
->a{a.sort_by{|i|"anebarprayunulugepctovec".index i[1,2]}}
```
The comparison function is a bit longer, at **63 bytes**
```
->a,b{m=->i{"anebarprayunulugepctovec".index i[1,2]};m[a]<m[b]}
```
[Answer]
# J, ~~66~~ 65 bytes
Uses the fact that f(m) = 2\*(ord(m[0])+ord(m[-1]))//len(m) is a valid function in the limited domain of the 12 months:
```
>/@:('7/HEäWa<+0'&i.@(3 :'u:<.(#>y)%~+:+/3&u:({.>y),({:>y)')"0)"1
```
Usage:
```
   bigger =: >/@:('7/HEäWa<+0'&i.@(3 :'u:<.(#>y)%~+:+/3&u:({.>y),({:>y)')"0)"1
   bigger ('May'; 'March')
1
   bigger ('May'; 'June')
0
```
(By no means is this the best idea, but I didn't want steal anyone's ranking trick!) 
Here is a shorter version using *@atlasologist's* method:
### J, 63 bytes
```
m=:[:}.3{.]
[:>/(12 2$'anebarprayunulugepctovec')i.([:m[),:[:m]
```
Usage:
```
   bigger =: [:>/(12 2$'anebarprayunulugepctovec')i.([:m[),:[:m]
   'January' bigger 'May'
0
   'June' bigger 'May'
1
```
And a much shorter version using *@Dennis's* clever method:
### J, 34 bytes
```
>&:('ubMAanlseov'&i.@:{.@:(10&|.))
```
[Answer]
# Haskell, 74 bytes
My first code golf, yay! The general idea of this one is inspired by the top answer in Jelly, and the fact that when the month names are cycled, the 11th character is always unique. 
```
e s=head.drop 10$cycle s;a#b=elem(e b)$tail$dropWhile(/=e a)"ubMAanlseovc"
```
Here is an ungolfed version to see how it works:
```
order :: String
order = "ubMAanlseovc"
eleventhChar :: String -> Char
eleventhChar
  = head . drop 10 $ cycle
inOrder :: String -> String -> Bool
inOrder m1 m2
  = elem (eleventhChar m2) (tail $ dropWhile (/= eleventhChar m1) order)
```
The `e` function represents the eleventhChar function (sadly can't strip off 4 bytes due to the monomorphism restriction I think) and the `#` infix function corresponds to the `inOrder` function.
A neat little solution, but there may be ways of shaving off more bytes (I found some just while writing this!)
[Answer]
# Java, ~~133~~ 123
Golfed:
```
boolean f(String a,String b){return h(a)<h(b);}int h(String s){return"anebarprayunulugepctovec".indexOf(s.substring(1,3));}
```
I was searching for a clever technique like in the assembler answer, but it was taking too long to figure out so I went with the same technique everyone else used.
Ungolfed:
```
import java.util.Random;
public class SortTheMonthsOfTheYear {
  public static void main(String[] args) {
    // @formatter:off
    String[] MONTHS = new String[] {
        "January", "February", "March",
        "April",   "May",      "June",
        "July",    "August",   "September",
        "October", "November", "December"
    };
    // @formatter:on
    Random r = new Random();
    for (int i = 0; i < 100; ++i) {
      int m1 = r.nextInt(MONTHS.length);
      int m2 = r.nextInt(MONTHS.length);
      System.out.println("Input: " + MONTHS[m1] + " < " + MONTHS[m2]);
      System.out.println("Expected: " + (m1 < m2));
      System.out.println("Actual:   " + new SortTheMonthsOfTheYear().f(MONTHS[m1], MONTHS[m2]));
      System.out.println();
    }
  }
  // Begin golf
  boolean f(String a, String b) {
    return h(a) < h(b);
  }
  int h(String s) {
    return "anebarprayunulugepctovec".indexOf(s.substring(1, 3));
  }
  // End golf
}
```
[Answer]
# ARM machine language on Linux ~~44~~ 40 bytes
```
e28fc001     add ip, pc, #1
e12fff1c     bx ip
6803         ldr r3, [r0, #0]
6808         ldr r0, [r1, #0]
4a05         ldr r2, [pc, #20]
f08303dd     eor.w r3, r3, #221
f08000dd     eor.w r0, r0, #221
4353         muls r3, r2
4350         muls r0, r2
4283         cmp r3, r0
bfac         ite ge
2000         movge r0, #0
2001         movlt r0, #1
4770         bx lr
2f68f24c
```
I used a different hash function than [anatolyg](https://codegolf.stackexchange.com/users/25315/anatolyg)'s [solution](https://codegolf.stackexchange.com/a/89541/52904) and tried to use thumb instructions to save a few bytes (though I blew 8 bytes entering thumb mode).
You can try this out on a Raspberry Pi or Android device with GNURoot.
```
int main(int argc,char**argv){
return ((int(*)(char*,char*))"\
\1\xc0\x8f\xe2\
\x1c\xff\x2f\xe1\
\3\x68\x8\x68\
\5\x4a\x83\xf0\
\xdd\3\x80\xf0\
\xdd\x43\x53\x43\
\x50\x4a\x83\x42\
\xac\bf\0\x20\
\1\x20\x70\x47\
\x4c\xf2\x68\x2f\
")(argv[1],argv[2]);}
```
To run enter something like
```
$ ./foo January February; echo $?
```
The current version now handles the equality case (and others) correctly.
[Answer]
# [Perl 6](http://perl6.org), 55 bytes
```
*.sort({index 'anebarprayunulugepctovec',.substr(1,2)})
```
It would require a few more bytes for the comparison versions:
```
{[<] @_».&{index 'anebarprayunulugepctovec',.substr(1,2)}}
{[<] .map: {index 'anebarprayunulugepctovec',.substr(1,2)}}
```
# Test:
```
#! /usr/bin/env perl6
use v6.c;
use Test;
my @months = <
  January February March April May June July
  August September October November December
>;
my &month-sort = *.sort({index 'anebarprayunulugepctovec',.substr(1,2)});
plan 100;
for ^100 {
  # ｢.pick(*)｣ returns all elements in random order
  is-deeply month-sort(@months.pick(*)), @months.List;
}
```
[Answer]
## Haskell, 118 characters
```
data M=Ju|Fr|Mc|Ai|My|Je|Jy|Au|St|Oo|Ne|De deriving(Ord,Eq,Read)
r=read.([head,last]<*>).lines.take 4
a#b=(r a::M)<r b
```
Uses the fact that each month name is unique in its first and fourth characters (or 3rd for May) to define a data type that can be automatically parsed and compared by the language. The 'r' function converts a string by grabbing the first four characters (or fewer), then just picking the first and last. Then 'a#b' is an operator to compare the values:
```
*Main> "June" # "March"
False
*Main> "June" # "July"
True
*Main> "January" # "July"
True
*Main> "January" # "November"
True
*Main> "December" # "November"
False
```
Could probably be done in a more efficient way, but I wanted to try doing it using a useful data type to represent the months.
[Answer]
# PowerShell, 96 88 63 bytes
```
$input|Sort{'anebarprayunulugepctovec'.IndexOf((-join$_[1,2]))}
```
e.g.
```
PS C:\Code> 'February', 'January', 'December', 'April' | .\monthsort.ps1
January
February
April
December
```
---
Now does the second challenge of sorting a list into order; previous versions did the comparison of two month test:
```
v2.
$l,$r=$args|%{-join$_[1,2]};($d='anebarprayunulugepctovec').indexof($l)-lt$d.IndexOf($r)
v1.
$l,$r=$args|%{-join$_[1,2]};$r-match('an|eb|ar|pr|ay|un|ul|ug|ep|ct|ov|ec'-split$l)[1].Trim('|')
e.g.
PS C:\code> .\Test-MonthsInOrder.ps1 January February
True
```
Based on the second two characters in the month name.
[Answer]
# Python 83 82 bytes
```
lambda x,y,m=(lambda a:'2&9<@FD6A?L%'.find(chr(sum(map(ord,a[:3]))%77))):m(x)<m(y)
```
Test: <https://repl.it/repls/TimelyDecimalBrowsers>
Gets the sum of the first 3 chars and creates a single char to search.
[Answer]
# awk, 73 bytes
```
function __(_){return index("=anebarprayunulugepctovec",substr(_,2,2))/2}
```
The full function, for any `awk` and any locale setting, **73 bytes**
```
echo -n 'function __(_){return index("=anebarprayunulugepctovec",substr(_,2,2))/2}' |
gwc -lcm
      0      73      73
```
The core components only, **50 bytes**
```
echo -n   'index("=anebarprayunulugepctovec",substr(_,2,2))/2' | 
gwc -lcm 
      0      50      50
```
This is better than the shorter trick involving the 11th letter, because that one requires all inputs to be full length names. this one works for ***both*** 3-letter abbreviated ones and their full length counterparts
[Answer]
# Javascript, 118 bytes
```
u=p=>{p=p.split` `.sort();c=[];for(i=0;i<12;i++){c.push(p["4 3 7 0 8 6 5 1 11 10 9 2".split` `[i]]);}return c.join` `}
```
Could be golfed more, probobly by getting rid of `c` and using `array.map`, but this is what I have for now...
[Answer]
# Bash, 101 bytes
this is function like is\_later
```
f(){ s=ubMAanlseovc a=$1$1$1 b=$2$2$2 c=${a:10:1} d=${b:10:1} e=${s%$c*} f=${s%$d*};((${#e}<${#f}));}
```
test
```
$ f January December && echo later || echo not later
not later
```
[Answer]
# k4, 29
```
{x@<"ubMAanlseovc"?(*|11#)'x}
```
A port of [*@Dennis's* Jelly answer](https://codegolf.stackexchange.com/a/89464/14217).
This is the sorter, not the comparator; interestingly, the comparator is trivially implementable by the same algorithm, and only one byte longer:
```
{(<)."ubMAanlseovc"?(*|11#)'x}
```
[Answer]
# Bash + coreutils, 94 bytes93 bytes
```
s(){ x=FMAyulgSOND;for y;{ rev<<<${y:0:3}|tr -d -C $x|tr $x C-M;echo B$y;}|sort|cut -f2 -dB;}
```
This is an attempt to come up with a transform that sorts lexicographically. If you look closely at the transform key `FMAyulgSOND` you can see the months February through December (January becomes empty after the transform; it's pulled to top by use of 'B' as the separator). Reversing, truncating, and removing non-keyed letters allow this trick to be pulled off.
## 90 bytes using C Locale
```
s(){ x=FMAyulgSOND;for y;{ rev<<<${y:0:3}|tr -d -C $x|tr $x C-M;echo \␉$y;}|sort|cut -f2;}
```
...where ␉ is the tab character.
## 80 bytes using C Locale
```
s(){ x=anebarprayunulugepctovec;for y;{ echo ${x%${y:1:2}*}\␉$y;}|sort|cut -f2;}
```
...using @atlasolog's method. Bound to be a way to use this approach to work with more locales.
**Test/Usage**
```
s December November October September August July June May April March February January
```
outputs:
```
January
February
March
April
May
June
July
August
September
October
November
December
```
[Answer]
# [Thunno](https://github.com/Thunno/Thunno), \$ 29 \log\_{256}(96) \approx \$ 23.87 bytes
```
De11AH"bMAanlseovc"AhEZZz:.AK
```
[Attempt This Online!](https://ato.pxeger.com/run?1=m72sJKM0Ly9_wYKlpSVpuhZ7XVINDR09lJJ8HRPzcopT88uSlRwzXKOiqqz0HL0haqBKF9ysilYPTi0oSc1NSi1S11FQ908uyYcyvUrzUkG0S2oyXNo3sRJCFSVngBiOpemlxSUgll9-GVyVY0FRZg7YiMS80sSiSohpOWDaLTWpCCwWC3ECAA)
Port of Dennis's Jelly answer.
#### Explanation
```
De          # Duplicate and map over the list
  11AH      # Get the 11th item of the string (1-indexed, modular)
      "..." # Push the string of each month's 11th letter
Ah          # Get the index in this string (January returns -1)
  E         # End map
   ZZ       # Zip with the original list
     z:     # Sort this list
       .AK  # And get the last item of each
            # Implicit output
```
]