#!/usr/bin/env python3 # --------------------------------------------------------------------- # # Module: cal.py # # Description: Calendar formulas # # Input: year-mm-dd [offset] # # Output: day of the week, date, Julian day number, # day of the year, week of the year # # Example: cal 1777-04-30 +84005 # Mon 2007-04-30 J# 2454221 D# 120 W# 18 # # Documentation: # http://berndt-schwerdtfeger.de/wp-content/uploads/pdf/calj.pdf # # --------------------------------------------------------------------- # Copyright (C) 2023 Berndt E. Schwerdtfeger # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # --------------------------------------------------------------------- # --------------------------------------------------------------------- # function definitions # --------------------------------------------------------------------- def leap(y): leap = False if y%4 == 0 : leap = True if (y > 1582 and y%100 == 0 and y%400 != 0): leap = False if leap: return 1 else: return 0 # --------------------------------------------------------------------- def date(n): global y,m,d while (n > 365 + leap(y)): # if offset larger than # of n -= 365 + leap(y) # ... days in a year y += 1 # ... find the correct year while (n <= 0): # if offset is negative y -= 1 # ... find the correct year n += 365 + leap(y) # ... and offset i = leap(y) # adjust for leap day m = 12 while (n <= e[m] + i): # searching for the month m -= 1 if (m<3): i=0 d = n - e[m] - i; # setting the day # --------------------------------------------------------------------- # main program # --------------------------------------------------------------------- import sys argc=len(sys.argv) if (argc==1 or sys.argv[1] == '?'): print("\ncal v1.3.2, 2023-12-25") print("-- Copyright (C) 2010-2023 Berndt E. Schwerdtfeger --\n") print("Input: year-mm-dd [offset]"); print("Output: {Mon|..|Sun} year-mm-dd J# jjjjjjj D# nnn W# ww"); else: s=sys.argv[1] # set constants -- move them to some spot below wd = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"] e = [0,0,31,59,90,120,151,181,212,243,273,304,334] if (argc >= 3): n=int(sys.argv[2]) else: # if no offset provided n=0 # ... initialize to 0 # parse the argument, should be in format y-m-d, with # y integer (so: may have a minus sign in front!) # m in the range 1 <= m <= 12 # d in the range 1 <= d <= 31 ymd = s.split('-') if (len(ymd[0])==0): # vorzeichen y = -int(ymd[1]) m = int(ymd[2]) d = int(ymd[3]) else: y = int(ymd[0]) m = int(ymd[1]) d = int(ymd[2]) if (y==1582 and m==10 and d>4 and d<15): print("Invalid date") sys.exit() # abort # test if we are in Julian or Gregorian era if (y < 1582 or y == 1582 and m*100+d < 1005): j = 1721423 + d + e[m] + (y-1)*365 + (y-1)//4 else: # Gregorian era x = y - 2001 j = 2451910 + d + e[m] + x*365 + x//4 - x//100 + x//400 if (m>2): j+=leap(y) # correction for leap year j += n # add offset if (j < 2299161): # Julian era y=1582 date(j-2298883) # calculate the date else: # Gregorian era y=1583 date(j-2299238) # calculate the date n = d + e[m] # offset into this year if (m > 2): n += leap(y) # adjust for leap day if (y==1582 and n>278): n-=10 # ten days dropped in 1582 w = j%7 # set weekday # if (w<0): w+=7 does not occur in Python print('%s %d-%d-%d J# %d D# %d W# %d' % (wd[w],y,m,d,j,n,(n-w+9)/7))