# calculate days of a month [closed]

I would like to see the shortest expression to calculate the days (or the last day) of a month in any language.

Considering y as the number of year and m as month.

Basic rules

• without date / time functions.
• considering leap years.
• there is not other rule.

## C, 4033 31 characters

Reduced length in three ways:
1. Replaced m%2^m>7 with m^m>7. The first is 0/1 in 30/31 day months, the second is even/odd. But the high bits don't matter, because their all set in 30 anyway (months with 30/31 days look like a really good idea now).
2. Used mob's idea (y%(y%100?4:400) as a leap year test)
3. Used <1 instead of ! saves parenthesis.
4. y%(y%100?4:400) -> y%(y%25?4:16) - works the same.

m-2?30|m^m>7:28|y%(y%25?4:16)<1

• ...:28+!(y%(y%100?4:400)) shaves 3 more – mob Sep 13 '12 at 22:19
• Thanks @mob, I'm taking it a bit further, will update soon. – ugoren Sep 14 '12 at 7:30
• If you're going to use y%16, why not y%8? – mob Sep 14 '12 at 16:00
• In fact, (y%50?4:8) or (y%25?4:8) work as well. – mob Sep 14 '12 at 16:11
• Thanks @mob, %16 works. %8 fails on 2200. I thought about &15, which isn't good, and somehow missed the equivalent %16 – ugoren Sep 14 '12 at 17:58

## C, 47 45 characters

30+(m>7^m&1)-(m^2?0:2-!(y%100||(y/=100),y%4))


Taken from an answer to an earlier question where I borrowed a couple of tricks from another user. Returns the length of month m in year y for the Gregorian calendar. ugoren's answer to the same question is shorter and may give a shorter answer to this question.

With thanks to mob for his leap year calculation.

• Here's another trick: use the expression !(y%100||(y/=100),y%4) – mob Sep 13 '12 at 15:28
• @mob Wow. It's taken me a good fifteen minutes to figure out how that works (I even checked it on ideone to make sure it did). Clever. – Gareth Sep 13 '12 at 15:54
• Figured out a better one: !(y%(y%100?4:400)) – mob Sep 13 '12 at 16:18
• @mob I think I'll leave mine as it is now - there's no way I'll catch up with ugoren's answer. – Gareth Sep 14 '12 at 8:22

(62648012>>m*2&3)+28+(m==2&&y%4==0)


https://stackoverflow.com/questions/2675720/calculate-days-of-month/11675530#11675530

So, the simplest form will work until 2100... but to prevents the 2100 bug :) I've copied the Matt solution to leap year:

(62648012>>m*2&3)+28+(m==2&&(y%4==0&&(y%100!=0||y%400==0)))

• I'm not familiar with the language you are using so I may be incorrect, but I don't think you account for integer multiples of 100 (not leap years unless they are also integer multiples of 400) en.wikipedia.org/wiki/Leap_year#Gregorian_calendar for example: 2100 is not a leap year – Matt Sep 12 '12 at 12:06
• You are right! I will fix it. thanks. – olivecoder Sep 12 '12 at 14:06

# Python 6461 59

(62648012>>m*2&3)+28+(m==2and y%4==0*(y%100>0 or y%400==0))


Based on olivecoder's solution, but accounting for multiples of 100.

## VBA, 84

28+Val(Mid("303232332323",M,1))-(M=2 And Y Mod 4=0 And (Y Mod 100>0 Or Y Mod 400=0))


# Python 50 5457

29+{2:y%(y%25and 4or 16)and-1}.get(m,(1&m^m>>3)+1)


with inspiration from mob, and the interesting fact, that a dict saves 1 byte in contrast to m==2and(..)or(...)

# Mathematica 97 91 83 82 78 76

A bit long, but gets the job done.

d = y ~ Divisible ~ # & ; 30 + { 1 , Boole [ d @ 400 ∨ ( d @ 4 ∧ ¬ d @ 100 ) ] - 2 , 1 , 0 , 1 , 0 , 1 , 1 , 0 , 1 , 0 , 1 } [ [ m ] ]

### VB.net (89 81c)

shame about the date function restriction as VB.net at only (21c)

Date.DaysInMonth(y,m)


may have won one for a change. DAMN YOU!

So current best is 89c

{0,31,28,31,30,31,30,31,31,30,31,30,31}(m)+(If( m=2 AndAlso (y Mod 4)=0 AndAlso (y Mod 400)>0,1,0)

{0,31,28,31,30,31,30,31,31,30,31,30,31}(m)+(If( m=2 And (y Mod 4)=0 And (y Mod 400)>0,1,0)

• if we ignore the restriction on YDM, then I can beat that with Excel at only 19 characters with =DAY(DATE(y,m+1,0)) :) – SeanC Sep 17 '12 at 19:49
• Importing the Namespace System.Date would mean you can remove the first 5 chars, so that brings it down to 16c – Adam Speight Sep 17 '12 at 21:26