Skip to content

Instantly share code, notes, and snippets.

@abdalla-alothman
Created August 22, 2019 11:29
Show Gist options
  • Select an option

  • Save abdalla-alothman/bd0b865eb1277598e4ce846bbfae6355 to your computer and use it in GitHub Desktop.

Select an option

Save abdalla-alothman/bd0b865eb1277598e4ce846bbfae6355 to your computer and use it in GitHub Desktop.
Week Day Calculator
#!/usr/bin/env python3
# Find name of week day from a provided date (day/month/year)
# Abdalla S. Alothman, 2014
# For details, please see:
# https://cs.uwaterloo.ca/~alopez-o/math-faq/node73.html
# http://en.wikipedia.org/wiki/Determination_of_the_day_of_the_week#Other_variations
###############################################################################
import re, math
def computeWeekDay(d, m, y):
# Map result from formula to possible days
days = {0:"Sunday", 1:"Monday", 2:"Tuesday", 3:"Wednesday", 4:"Thursday", 5:"Friday", 6:"Saturday"}
# Formaula:
# W = (d + floor((2.6 * m) - 0.2) + Y + floor(Y/4) + floor(C/4) - 2C) mod 7
# Note: When computing by hand:
# If we end up with a negative number: -x mod 7, we find the closest multiple of 7 greater to or equal to |x| if x > 7
# then subtract. Else, we subtract x from 7 if x < 7. Thus, if -x=-2: 7-5 = 5=Friday. If -x = -8: 14 - 8 = 6=Saturday.
# Then subtract. Thus, when D, in D mod B is -D: -D mod B is equivalent to kB - D. Where kB is a multiple of B.
# so -19 becomes: 21 - 19 = 2 {Tues}. (21 = 3*7). Negatives appear in any year for any century where year y <= 7.
# BY CALCULATOR:
# To get remainder after dividing D / 7:
# Multiply quotient by divisor (7) and subtract from divident (D).
if m == 1 or m == 2: # shift January to month 11 and February to 12 and reduce year by 1.
m += 10
y -= 1 # reduce year by 1, if Jan or Feb.
else: m -= 2 # If not January or February, shift by -2 (March becomes month 1)
cent = int(y / 100) # isolate the century
year = y % 100 # isolate the year
monthFloor = math.floor((2.6 * m) - 0.2)
yearFloor = math.floor(year/4)
centuryFloor = math.floor(cent/4)
weekdayNum = ( d + monthFloor + year + yearFloor + centuryFloor - (2 * cent) ) % 7
return days[weekdayNum]
###############################################################################
def pythonCheck(d, m, y): # Check results with Python's datetime module.
import datetime
x = datetime.datetime(y, m, d)
d = datetime.datetime.weekday(x)
days = {0:"Monday", 1:"Tuesday", 2:"Wednesday", 3:"Thursday", 4:"Friday", 5:"Saturday", 6:"Sunday"}
return days[d]
###############################################################################
def printCal(m, y): # Visualize result.
import calendar
print(calendar.TextCalendar().formatmonth(y, m))
###############################################################################
if __name__ == "__main__":
import sys
if len(sys.argv) > 1:
date = sys.argv[1]
else:
print("Input Date (dd/mm/yyy)")
date = input("Date:> ")
# dports - Date Portions
dports = re.split(r"[\ \,\./:-]", date)
d = int(dports[0])
m = int(dports[1])
y = int(dports[2])
# Print calendar
printCal(m, y)
print("Date {} matches: {}".format(date, computeWeekDay(d, m, y)))
# Verify by checking results with python's datetime module:
print("Result from Python's datetime module: {}".format(pythonCheck(d, m, y)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment