📄 date.awk
字号:
BEGIN{ # This is a sample driver for the package consisting of the routines# { yrmoda, curcal, integer}# It allows conversion of interactively entered year month day to# running date since the beginning of the calendar and the other way.while(1){# Obtain task to be done print("Enter (1) to convert year, month, day to running days \n", \ " (2) to convert running days to year, month, day \n", \ " (0) to exit this program \n") readline() if ($1==0){ print("Exit option chosen in program") exit 0} if ($1==1) {while(do_runday()==1); continue} if ($1==2) {while(do_calendar()==1); continue} print("Please enter one of: 0, 1, 2") } }# Option 1 - Convert year, month, day into running daysfunction do_runday(){# Convert year month day to running days and print answers# Return 0 if more problems of this type to be done# Else return 0while(1){print("Enter year month day separated by spaces. \n", \ "If first value is negative, this loop will exit") readline()if (NF != 3){ print("You must enter year month day \n", \ "You entered ",NF," values") continue }year=$1month=$2day=$3if (!isint(year) || !isint(month) || !isint(year)){ print("Year, month, and day must be numeric. \n", \ "Try again.") continue } break }if(year<0) return 0runday=yrmoda(year,month,day,1)+0if (runday<1) print("Illegal date entered. Try again.")else{ print(" Year: ",year," Month: ",month," Day: ",day,"\n", \ " Number of days since 15 Oct 1582 is: ",runday)} return 1 }# Option 2 - Convert running days into year month dayfunction do_calendar(){# Convert running days since beginning of calendar to year month day# Return 1 if more of these problems to be done# Else return 0while(1){print("Enter number of days since the beginning of the calendar.\n", \ "A negative number stops this program")readline()runday=$1if (!isint(runday)){ print("You must enter an integer number. \n", \ "Try again.") continue}break }if (runday<0) return 0# Define date as an arraydate["year"]=""curcal(runday,date)print("Days since the beginning of the calendar entered: ",runday,"\n", \ "Year: ", date["year"], "\n", \ "Month: ", date["month"], "\n", \ "Day: ", date["day"], "\n", \ "Day of the week: ", date["wkday"])return 1}function readline(){# Read a line from current input -- abort on eofok=getlineif (ok <= 0){print("Exit on end of file or read error")exit 1 } }function isint(x){# Returns 1 if x is an integer# Otherwise returns 0pattern1=" *[-+][0-9]+"pattern2=" *[0-9]+"if (x~pattern1 || x~pattern2) return 1else return 2}function yrmoda (year,month,day,checkopt,# local variables# The only way to have local variables in awk is to declare them in# the function definition. cyclyr,cyclda,adjust,yrs,rc,cycles,backmonth,backday,date){#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++## function yrmoda(year,month,day,[opt]checkopt)# # FUNCTION# # Returns the number of days from 14 Oct 1582 to the date# specified by year, month, day (so that 15 Oct 1582 is 1, for# example).# # ARGUMENTS# # year --> The year portion of the date. Must be an integer# greater than or equal to 1582.# # month --> The month: Jan=1, ..., Dec=12. A positive integer# between 1 and 12.# # day --> The day of the month. Range 1..31.# # checkopt --> If present in call and not zero or blank, the# input date is checked by converting the running day# calculated by this routine into a year, month, and day by a# call to curcal. If the back conversion matches the input,# the date is legal; otherwise, it is not. Catches such# errors as Feb 29 on a year that is not a leap year.# # If not present in call to yrmoda or if it is present but has# a value of blank or zero, the check will not be done.# # RETURN VALUE: If there is no range error and if there is no# error in the check indicated by checkopt, returns the number# of days between 14 Oct 1582 and the date specified.# # If some error is detected, returns zero.# # NOTES# # The earliest date for which this routine works is 15 Oct# 1582. Any earlier date causes a return value of zero.# # The Gregorian calendar became effective in parts of Europe# on 15 Oct 1582. Hence the choice of day 1.# #----------------------------------------------------------------------## check to see if we need to add 1900 to year# if(year < 100) year += 1900## preliminary input checking# if(year < 1582) return 0 if(month < 1 || month > 12) return 0 if(day < 1 || day > 31) return 0## data statements# cyclyr[1] = 1 cyclyr[2] = 4 cyclyr[3] = 100 cyclyr[4] = 400 cyclda[1] = 365 cyclda[2] = 4*cyclda[1] + 1 cyclda[3] = 25*cyclda[2] - 1 cyclda[4] = 4*cyclda[3] + 1# adjust = int((14 - month) / 12) # correction for Jan. & Feb. in # rational calendar adjust = - adjust yrs = year + adjust - 1200 rc = 0## number of days in various complete year cycles# for (i = 4;i >= 1;i--) { cycles = int( yrs / cyclyr[i] ) if (cycles > 0) { rc += cycles*cyclda[i] yrs -= cycles*cyclyr[i] } }## plus number of days in completed months in current rational year# rc += int((((month - 2) - 12*adjust) * 367)/ 12) - 30## plus number of days in current month# rc += day## minus correction for start of rational calendar to gregorian calendar# rc -= 139750# if (rc < 0) return 0 # this checks that the input was later # than Oct. 15 1582## if we want to check the input go backwards from the answer# if(checkopt == 1) { date["year"] = 0 stat = curcal(rc,date)## compare input to backward answers# if( date["year"] != year || date["month"] != month \ || date["day"] != day){ print("Flunked consistency check") print("From curcal: yr ",date["year"]," Mn ",date["month"], \ " Dy ",date["day"]) return 0 } } return rc}function curcal(ccdate,date,# local variables absdas,cyclyr,cyclda){#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++## function curcal( ccdate, date )# # FUNCTION# # Given a date in the form of the number of days since 14 Oct# 1582 (so that 15 Oct 1582 is 1, for example), calculates the# date in the form year, month, day. Returns these values and# the value of day of the week in array date.# # ARGUMENTS# # ccdate --> A positive integer, the number of days since 14# Oct 1582 to the date being specified.# # date <-- An array with subscripts "year", "month", "day",# and "wkday". See Notes.# # date["year"] The year portion of the date.# # date["month"] The month: Jan=1, ..., Dec=12.# # date["day"] The day of the month. Range 1..31.# # date{"wkday"] The day of the week. Sun=1, ..., Sat=7.# # RETURN VALUE: Zero if ccdate is negative; otherwise 1.# # NOTES# # By the rules of AWK (and GAWK), date must be an array# before curcal is invoked. Otherwise, AWK will think that it# is a scalar and pass it by value. Then curcal cannot modify# the calling value.# # To assure that date is an array, in the calling program# before the call to curcal include a statement,# # date["year"]=""# # The Gregorian calendar became effective in parts of Europe# on 15 Oct 1582. Hence the choice of day 1.# #----------------------------------------------------------------------## preliminary input checking# if(ccdate < 1) return 0## data statements# cyclyr[1] = 1 cyclyr[2] = 4 cyclyr[3] = 100 cyclyr[4] = 400 cyclda[1] = 365 cyclda[2] = 4*cyclda[1] + 1 cyclda[3] = 25*cyclda[2] - 1 cyclda[4] = 4*cyclda[3] + 1## correct for start of gregorian calendar to rational calendar# and off by one error because first day is 1 not 0# absdas = ccdate + 139750 - 1## number of years in various complete year cycles# date["year"] = 1200 for (i = 4;i >= 1;i--) { cycles = int(absdas / cyclda[i]) if (cycles > 0 ) { if(i != 4) { if(cycles == (cyclyr[i+1] /cyclyr[i])) { cycles-- if (cycles < 0) continue } } date["year"] += cycles * cyclyr[i] absdas -= cycles * cyclda[i] } } absdas++## month of rational year# date["month"] = int((((absdas + 30) * 12) - 1) / 367)# # day of rational year# date["day"] = absdas - int((date["month"] * 367) / 12) + 30## correction for Jan. & Feb. in rational calendar# date["month"] +=2 if (date["month"] > 12) { date["month"] -= 12 date["year"] += 1 }## week day of date# date["wkday"] = ((ccdate + 4)%7) + 1# return 1}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -