[Question]
  [
# Introduction
Some months are **completely symmetric**, meaning they have *central symmetry* as well as *reflection symmetry*, like `February of 2010`:
```
     February 2010
┌──┬──┬──┬──┬──┬──┬──┐ 
│  │  │  │  │  │  │  │ 
├──┼──┼──┼──┼──┼──┼──┤ 
│  │  │  │  │  │  │  │ 
├──┼──┼──┼──┼──┼──┼──┤ 
│  │  │  │  │  │  │  │ 
├──┼──┼──┼──┼──┼──┼──┤ 
│  │  │  │  │  │  │  │ 
└──┴──┴──┴──┴──┴──┴──┘ 
```
Some months have **only** central symmetry, like `February of 1996` or current month, the `April of 2018`:
```
      February 1996
          ┌──┬──┬──┬──┐
          │  │  │  │  │
 ┌──┬──┬──┼──┼──┼──┼──┤
 │  │  │  │  │  │  │  │
 ├──┼──┼──┼──┼──┼──┼──┤
 │  │  │  │  │  │  │  │
 ├──┼──┼──┼──┼──┼──┼──┤
 │  │  │  │  │  │  │  │
 ├──┼──┼──┼──┼──┴──┴──┘
 │  │  │  │  │
 └──┴──┴──┴──┘
       April 2018  ┌──┐
                   │  │
 ┌──┬──┬──┬──┬──┬──┼──┤
 │  │  │  │  │  │  │  │
 ├──┼──┼──┼──┼──┼──┼──┤
 │  │  │  │  │  │  │  │
 ├──┼──┼──┼──┼──┼──┼──┤
 │  │  │  │  │  │  │  │
 ├──┼──┼──┼──┼──┼──┼──┤
 │  │  │  │  │  │  │  │
 ├──┼──┴──┴──┴──┴──┴──┘
 │  │
 └──┘
```
And some are **asymmetric**, like the previous month, the `March of 2018`:
```
      March 2018
         ┌──┬──┬──┬──┐
         │  │  │  │  │
┌──┬──┬──┼──┼──┼──┼──┤
│  │  │  │  │  │  │  │
├──┼──┼──┼──┼──┼──┼──┤
│  │  │  │  │  │  │  │
├──┼──┼──┼──┼──┼──┼──┤
│  │  │  │  │  │  │  │
├──┼──┼──┼──┼──┼──┼──┘
│  │  │  │  │  │  │
└──┴──┴──┴──┴──┴──┘
```
# Task
Take an input in form of a **date**, e.g.:
* `2018.04`
* `2018.03`
* `2010.02`
* `1996.02`
Output the corresponding **symmetry**, e.g.
* `2018.04` -> `centrally symmetric`
* `2018.03` -> `asymmetric`
* `2010.02` -> `symmetric`
* `1996.02` -> `centrally symmetric`
# Rules
* This is code golf, so the smallest number of bytes wins.
* Standard loopholes are obviously not allowed.
* Assume that the week starts with [Monday](https://commons.wikimedia.org/wiki/File:First_Day_of_Week_World_Map.svg) (thanks to [Angs](https://codegolf.stackexchange.com/users/60340/angs) and [Arnauld](https://codegolf.stackexchange.com/users/58563/arnauld) for suggestion).
* Consider only years between 1900 and 2100 (**inclusive**).
* The input and output formatting rules are **permissive**, meaning you can use any equivalent format that is native to the language of your choice.
* Base your solution on the [Gregorian calendar](https://en.wikipedia.org/wiki/Gregorian_calendar).
  
[Answer]
# JavaScript (ES6), 55 bytes
*Saved 6 bytes thanks to @Neil*
Takes input in currying syntax `(year)(month)`. Returns `false` for asymmetric, `true` for centrally symmetric and `0` for completely symmetric.
```
y=>m=>(n=(g=_=>new Date(y,m--,7).getDay())()+g())&&n==7
```
[Try it online!](https://tio.run/##bcixCoMwEADQvV/hJHfUiNpSdbhM/kcJeoYWvYgGJV@flq51evDeZjdbv74Wr8QNHEeKgfRMGoTA0pO08JF0xjOEbFYqqzG37DsTABHwar@kqRDVsXeyuYnzyVkYoSrKBuGOeDn729kXCNXfl237@H38AA "JavaScript (Node.js) – Try It Online")
## How?
We define the function **g()** which returns the weekday of **yyyy/mm/01**, as an integer between **0** = Monday and **6** = Sunday.
```
g = _ => new Date(y, m--, 7).getDay()
```
Because **getDay()** natively returns **0** = Sunday to **6** = Saturday, we shift the result to the expected range by querying for the 7th day instead.
Then we define:
```
n = g() + g()
```
Because the constructor of *Date* expects a 0-indexed month and because **g()** decrements **m** *after* passing it to *Date*, we actually first compute the weekday of the first day of the *next* month and then add that of the current one.
### Completely symmetric months
Completely symmetric months start with a Monday and are followed by a month which also starts with a Monday. This is only possible for February of a non-leap year.
```
- Feb --------------    - Mar --------------
Mo Tu We Th Fr Sa Su    Mo Tu We Th Fr Sa Su
--------------------    --------------------
01 02 03 04 05 06 07    01 02 03 04 05 06 07
08 09 10 11 12 13 14    08 09 10 11 12 13 14
15 16 17 18 19 20 21    15 16 17 18 19 20 21
22 23 24 25 26 27 28    22 23 24 25 26 27 28
                        29 30 31
```
This leads to **n = 0**.
### Centrally symmetric months
Centrally symmetric months are months for which the sum of the weekday of their first day and that of the next month is **7**.
```
- M ----------------    - M+1 --------------
Mo Tu We Th Fr Sa Su    Mo Tu We Th Fr Sa Su
--------------------    --------------------
 0  1 [2] 3  4  5  6     0  1  2  3  4 [5] 6
--------------------    --------------------
      01 02 03 04 05                   01 02
06 07 08 09 10 11 12    03 04 05 06 07 07 09
13 14 15 16 17 18 19    ...
20 21 22 23 24 25 26
27 28 29 30 31
```
Hence the second test: **n == 7**.
---
# No built-in, 93 bytes
Uses [Zeller's congruence](https://en.wikipedia.org/wiki/Zeller%27s_congruence). Same I/O format as the other version.
```
y=>m=>(n=(g=_=>(Y=y,((m+(m++>2||Y--&&13))*2.6|0)+Y+(Y>>2)-6*~(Y/=100)+(Y>>2))%7)()+g())&&n==7
```
[Try it online!](https://tio.run/##bcjRCoIwFIDh@96jcY5rts3QvDh7j12FmI5Et8gIBOnV16jLhP/i5xuaVzO3j9v9KXy4drGnuJCZyIAncHRJY2k5AEw8xY1eVysEY6pAzHRerhK55WCN0SjK7A32SEom/BHuKwTkDhAZ80RVbIOfw9jlY3DQg5bqjHBC3G15seUSQf@5quvy6/ED "JavaScript (Node.js) – Try It Online")
[Answer]
# [T-SQL](https://www.microsoft.com/sql-server), 213 bytes (strict I/O rules)
```
SET DATEFIRST 1SELECT CASE WHEN a+b<>8THEN'a'WHEN a=1THEN''ELSE'centrally 'END+'symetric'FROM(SELECT DATEPART(DW,f)a,DATEPART(DW,DATEADD(M,1,f)-1)b FROM (SELECT CONVERT(DATETIME,REPLACE(s,'.','')+'01')f FROM t)y)x
```
The above query considers the strict input/output formatting rules. 
The input is taken from the column `s` of a table named `t`:
```
CREATE TABLE t (s CHAR(7))
INSERT INTO t VALUES ('2018.04'),('2018.03'),('2010.02'),('1996.02')
```
Ungolfed:
```
SET DATEFIRST 1
SELECT *, CASE WHEN a+b<>8 THEN 'a' WHEN a=1 AND b=7 THEN '' ELSE 'centrally ' END+'symetric'
FROM (
    SELECT *,DATEPART(WEEKDAY,f) a, 
        DATEPART(WEEKDAY,DATEADD(MONTH,1,f)-1) b 
    FROM (SELECT *,CONVERT(DATETIME,REPLACE(s,'.','')+'01')f FROM t)y
) x
```
[SQLFiddle 1](http://sqlfiddle.com/#!18/fecbd/1)
# [T-SQL](https://www.microsoft.com/sql-server), 128 bytes (permissive I/O rules)
```
SET DATEFIRST 1SELECT CASE WHEN a+b<>8THEN 1WHEN a=1THEN\END FROM(SELECT DATEPART(DW,d)a,DATEPART(DW,DATEADD(M,1,d)-1)b FROM t)x
```
If the format of the input and of the output can be changed, I would choose to input the first day of the month, in a `datetime` column named `d`:
```
CREATE TABLE t (d DATETIME)
INSERT INTO t VALUES ('20180401'),('20180301'),('20100201'),('19960201')
```
The output would be 1 for asymetric, 0 for symetric, NULL for centrally symetric.
If we can run it on a server (or with a login) configured for BRITISH language, we can remove `SET DATEFIRST 1` saving 15 more bytes.
[SQLFiddle 2](http://sqlfiddle.com/#!18/69377/1)
[Answer]
# Haskell, 170 bytes
```
import Data.Time.Calendar
import Data.Time.Calendar.WeekDate
a%b=((\(_,_,a)->a).toWeekDate.fromGregorian a b$1)!gregorianMonthLength a b
1!28=2
4!29=1
7!30=1
3!31=1
_!_=0
```
Returns 2 for centrally symmetric, 1 for symmetric and 0 for asymmetric
[Answer]
# Python 2, ~~118~~ 104 bytes
Thanks to Jonathan Allan and Dead Possum for the improvements!
```
from calendar import*
def f(*d):_=monthcalendar(*d);print all(sum(_,[]))+(_[0].count(0)==_[-1].count(0))
```
---
# Python 3, ~~122~~ 105 bytes
```
from calendar import*
def f(*d):_=monthcalendar(*d);print(all(sum(_,[]))+(_[0].count(0)==_[-1].count(0)))
```
---
### Input
* First is the **year**
* Second is the **month**
---
### Output
* 0 = no symmetry
* 1 = central symmetry
* 2 = complete symmetry
[Answer]
# [Red](http://www.red-lang.org), 199, 168 161 bytes
```
func[d][t: split d"."y: do t/1 m: do t/2 a: to-date[1 m y]b: a + 31
b/day: 1 b: b - 1 if(1 = s: a/weekday)and(7 = e: b/weekday)[return 1]if 8 - e = s[return 2]0]
```
[Try it online!](https://tio.run/##ZczNDoIwEATgO08x6QljgBaMQhNfwmvTQ7FtQlQgUGJ4elzjTzDeJt/O7ODscnJW6cjLxU/tWVmtgsTYX5sAy1I2S9gOIRO4vVMOIxG6xJrgFDFmXUsYbFGIqM6soYkAUY2EQuNjgSNGqmR35y5035jWxgdCR6UvqsGFaWghdONR0tY9Zx/NNddLPzRtgAfLuShTvmPRWoo/4SnPVyKqav8rrz8VWx4 "Red – Try It Online")
0 - asymmetric
1 - symmetric
2 - centrally symmetric
## More readable:
```
f: func[d][                  ; Takes the input as a string
    t: split d "."           ; splits the string at '.'
    y: do t/1                ; stores the year in y 
    m: do t/2                ; stores the month in m
    a: to-date[1 m y]        ; set date a to the first day of the month
    b: a + 31                ; set date b in the next month  
    b/day: 1                 ; and set the day to 1st
    b: b - 1                 ; find the end day of the month starting on a
    s: a/weekday             ; find the day of the week of a 
    e: b/weekday             ; find the day of the week of b
    if(s = 1) and (e = 7)    ; if the month starts at Monday and ends on Sunday
        [return 1]           ; return 1 fo symmetric
    if 8 - e = s             ; if the month starts and ends on the same day of the week
        [return 2]           ; return 2 for centrally symmetric  
    0                        ; else return 0 for assymetric
]
```
[Answer]
# Mathematica, 137 bytes
```
a=#~DateValue~"DayName"&;b=a/@{2}~DateRange~{3};Which[{##}=={0,6},1,+##>5,0,1>0,-1]&@@(Position[b,a@#][[1,1]]~Mod~7&)/@{{##},{#,#2+1,0}}&
```
Pure function. Takes the year and the month as input and returns `-1` for asymmetric months, `0` for centrally symmetric months, and `1` for fully symmetric months. Not sure why this language can't convert from a weekday to a number by default...
[Answer]
# [Bash](https://www.gnu.org/software/bash/) + GNU utilities, 70
```
date -f- +%u<<<"$1/1+1month-1day
$1/1"|dc -e??sad8*la-55-rla+8-d*64*+p
```
Input is formatted as `YYYY/MM`.
Output is numeric, as follows:
* less than 0: centrally symmetric
* exactly 0: symmetric
* greater than 0: asymmetric
I assume this output format is acceptable for this question.
[Try it online!](https://tio.run/##dVBda8MwDHz3rxDGAyfBJO7aktJk/SnDixUScOwSOw@h7W/P8rHC6JheDunuhE5fyjeTG8J1CJ9WdcijG4G52ho4ZxLKErIoOkNo0K7EUlg1Dqgfuw5D31Z0JdA8PcW/lgpt6JUxI/wxe3zRqhdJ3ZIHqV0PAX3QKiC0FnaZzNNs/4PvC2ZptgN5Oh1nPIN2xGMAIYA9fWSLWzI@rWtELSB5G4qioEymMpGds6ERUquRLAN61xUIvFy80nlslDgcRG9UkgsdH/dxcp0isp08ZxcfwPivfwLbmogS7SxO3w "Bash – Try It Online")
[Answer]
# C, 111 bytes
```
a;g(y,m){y-=a=m<3;return(y/100*21/4+y%100*5/4+(13*m+16*a+8)/5)%7;}f(y,m){a=g(y,m)+g(y,m+1);return(a>0)+(a==7);}
```
Invoke `f(year, month)`, 0 for completely symmetric, 1 for asymmetric, 2 for centrally symmetric.
[Answer]
# [Perl 6](https://perl6.org/), 74 bytes
```
{{{$_==30??2!!$_%7==2}(2*.day-of-week+.days-in-month)}(Date.new("$_-01"))}
```
Bare block, implicitly a function of 1 argument, a string like `"2012-02"`. Returns:
```
2     # Fully symmetric
True  # Centrally symmetric
False # Asymmetric
```
When the pattern is symmetric, as .day-of-week increases by 1, .days-in-month would need to move by 2 in order to still match (the month would be starting a day later but need to end a day earlier), so `2 * .day-of-week + .days-in-month` gives us a measure of that gap. Modulo 7 it should be 1 to get symmetry, but we can first cheaply check for the non-leap February by checking that total before modulo (Monday and 28 days per month is the minimum possible combination).
I'm surprised that this takes so many bytes, but fully 36 bytes are needed for just making a date and getting the day of the week and days in that month.
]