# Calculate the day number of the year

Seems like we do not have this one yet, so here we go:

# The Challenge

Write a program or function that takes a date as input and outputs the day number of the year. You may not use any builtins for that!

# Rules

• As usual you may write a full program or a function.
• The format of the input is up to you, but it has to contain a year, a month and a day. Make clear which one your solution uses!
• No date-related builtins allowed! You gotta do the work by yourself. Builtins which are not related to date operations are fine.
• Base for the calcultion is the gregorian calendar.
• You have to take account of leap-years.
• You only need to handle years in the range [1, 9999]
• Standard loopholes are forbidden.
• Lowest byte count wins!

# Testcases

Input format here is YYYY/MM/DD

2016/07/05 -> 187
2000/03/28 -> 88
0666/06/06 -> 157
6789/10/11 -> 284
0004/04/04 -> 95
1337/07/13 -> 194


Happy Coding!

• Can we use builtins for days since a certain date? What about for whether a year is a leap year? Jan 28, 2016 at 22:19
• @Thomas No date-related builtins allowed. Gonna clarify that in the challenge, thanks for the comment! :) Jan 28, 2016 at 22:22
• @DenkerAffe Why did you forbid all built-ins? Jul 17, 2016 at 18:07

## JavaScript ES6, 81 69 bytes

(y,m,d)=>d+parseInt("03479cehkmpr"[--m],36)+m*28-(y%(y%25?4:16)&&m>1)


Assuming months are 1-based, otherwise I could save 2 bytes.

Edit: Saved 12 bytes using @user81655's tip.

# C, 9610289 61 bytes

g(y,m,d){printf("%d",m/2*31+--m/2*30-(y%(y%25?4:16)?2:1)+d);}


## Pyth, 31 bytes

+s<X1+L28jC"3»î"4!%|F_jQ*TT4tEE


Thanks to @Dennis and @Jakube for the leap year portion. Input is YYYY, MM, DD on separate lines.

+                          add [day] to
s <                      sum of first [month]-1 values in the list
1                  the second element (January)...
+L                 \
28              |
j               }   lengths of all the months
C "3»î"       |
4             /
! %                ... if the year is a leap year; that is, 4 divides...
|F _ j         fold logical OR over reversed
Q       the year
*TT     converted to base 100
4
t E                 [month]-1
E                       [day]


# Python 3, 152148 150 bytes

m,d,y=map(int,input().split());n=[0,31,(59,60)[(y%4==0 and y%100!=0)or y%400==0]]
for i in range(m):n+=[n[-1]+(31,30)[i in[1,3,6,8]]]
print(n[-4]+d)


Takes dates in the format "M D YYYY".

• You should use Python 2, unless you need specific features from Python 3. Because then you don't need brackets in your prints which allows you to save one byte by wrinting your print as print n[m-1]+d Jan 29, 2016 at 9:37
• In the first line, you could write y%4==0and y%100!=0, I think Jul 16, 2016 at 8:38

# Python 2, 100 82 bytes

A Python port of @Neil's answer:

lambda d,m,y:d+int("03479cehkmpr"[m-1],36)+(m-1)*28-(y%(4if y%25 else 16)and m>2)


As with the previous answer, adding 17 bytes (99 bytes total) will yield a full program:

print(lambda d,m,y:d+int("03479cehkmpr"[m-1],36)+(m-1)*28-(y%(4if y%25 else 16)and m>2))(*input())


As an anonymous lambda:

lambda d,m,y:d+sum(31-(n in(3,5,8,10))for n in range(m-1))-(3if y%4 or(y%400!=0and y%100==0)else 2)


Can be converted to a named lambda for a 2 byte penalty. Alternatively, a full program (taking input in the format D,M,Y) can be achieved for 117 bytes:

print(lambda d,m,y:d+sum(31-(n in(3,5,8,10))for n in range(m-1))-(3if y%4 or(y%400!=0and y%100==0)else 2))(*input())

• A few small golfs gets 76 bytes Jun 12, 2019 at 17:07

# Nibbles, 28 bytes

+-=@\:0.@1370+30$+?-@2- 2%+.::4 100 400^0%_$~0


Attempt This Online!

Takes the year, month and day as command-line arguments.

Edit: Care to explain why this was downvoted?

• Re downvote: probably for the same reason that all the other 8 answers except for the awk one were downvoted. Only the downvoter knows the reason, and nobody knows for sure who he/she is. Although it is somewhat intriguing that the author of the awk answer has placed 9 downvotes this week... Oct 6 at 13:17
• @DominicvanEssen Interesting observation. Hmmm… Oct 6 at 14:53

# Python 3, 125 bytes

print((lambda d,m,y:sum([3,not(y%400 and not y%100 or y%4),3,2,3,2,3,3,2,3,2,3][:m-1])+m*28-28+d)(*map(int,input().split())))


An another approach to this problem. The code takes advantages of the Python's boolean algebra execution priorities and since not is the last operation, conversion to boolean is automatic. When summation is done, the boolean is treated as 1 or 0. Input format is "YY MM DDDD" string. Input system inspired by @SteveEckert's similar one.

### Another form as a function, 91 bytes

def f(d,m,y):return sum([3,not(y%400 and not y%100 or y%4),3,2,3,2,3,3,2,3,2,3][:m])+m*28+d


In this case input is three integers, the month being between 0-11. This would work in Python 2 also.

# Excel, 106 bytes

=AND(C1>2,OR(MOD(A1,400)=0,AND(MOD(A1,4)=0,MOD(A1,100))))+30*B1-31+CHOOSE(B1,1,2,0,1,1,2,2,3,4,4,5,5,6)+C1


Takes input in three cells A1 = Year, B1 = Month, C1 = Day.

AND(C1>2,OR(MOD(A1,400)=0,AND(MOD(A1,4)=0,MOD(A1,100))))


1 if LeapYear, else 0

30*B1-31+CHOOSE(B1,1,2,0,1,1,2,2,3,4,4,5,5,6)+C1


Multiple of 30, CHOOSE for additional days, plus days in month

Evolution:

=IF(AND(C1>2,OR(MOD(A1,400)=0,AND(MOD(A1,4)=0,MOD(A1,100)))),1,0)+CHOOSE(B1,0,31,59,90,120,151,181,212,243,273,304,334,365)+C1
=IF(AND(C1>2,OR(MOD(A1,400)=0,AND(MOD(A1,4)=0,MOD(A1,100)))),1,0)+CHOOSE(B1-1,31,59,90,120,151,181,212,243,273,304,334,365)+C1
=IF(AND(C1>2,OR(MOD(A1,400)=0,AND(MOD(A1,4)=0,MOD(A1,100)))),1,0)+30*(B1-1)+CHOOSE(B1,0,1,-1,0,0,1,1,2,3,3,4,4,5)+C1
=IF(AND(C1>2,OR(MOD(A1,400)=0,AND(MOD(A1,4)=0,MOD(A1,100)))),1,0)+30*B1-30+CHOOSE(B1,0,1,-1,0,0,1,1,2,3,3,4,4,5)+C1
=IF(AND(C1>2,OR(MOD(A1,400)=0,AND(MOD(A1,4)=0,MOD(A1,100)))),1,0)+30*B1-31+CHOOSE(B1,1,2,0,1,1,2,2,3,4,4,5,5,6)+C1
=AND(C1>2,OR(MOD(A1,400)=0,AND(MOD(A1,4)=0,MOD(A1,100))))+30*B1-31+CHOOSE(B1,1,2,0,1,1,2,2,3,4,4,5,5,6)+C1


# Scala, 126 bytes

Port of @Neil's Javascript answer in Scala.

Golfed version. Try it online!

(y,m,d)=>d+Integer.parseInt("03479cehkmpr".toSeq(m-1).toString,36)+(m-1)*28-(if ((y%(if (y%25==0)16 else 4)!=0)&&m>1)1 else 0)


Ungolfed version. Try it online!

object Main {
def dayOfYear(y: Int, m: Int, d: Int): Int = {
val monthOffsets = "03479cehkmpr".toList
d + Integer.parseInt(monthOffsets(m - 1).toString, 36) + (m - 1) * 28 - (if ((y % (if (y % 25 == 0) 16 else 4) != 0) && m > 1) 1 else 0)
}

def main(args: Array[String]): Unit = {
println(dayOfYear(2016, 07, 05))  // 187
println(dayOfYear(2000, 03, 28))  // 88
println(dayOfYear(0666, 06, 06))  // 157
println(dayOfYear(6789, 10, 11))  // 284
println(dayOfYear(0004, 04, 04))  // 95
println(dayOfYear(1337, 07, 13))  // 194
}
}
`