#!/bin/sh # # $Id: dbd.awk,v 1.6 2005/10/06 18:42:28 hiram Exp $ # # Copyright (c) 1986-2005, Hiram Clawson - jday at hiram.ws # All rights reserved. # # Redistribution and use in source and binary forms, with or # without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above # copyright notice, this list of conditions and the # following disclaimer. # # Redistributions in binary form must reproduce the # above copyright notice, this list of conditions and # the following disclaimer in the documentation and/or # other materials provided with the distribution. # # Neither name of The Museum of Hiram nor the names of # its contributors may be used to endorse or promote products # derived from this software without specific prior # written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND # CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING # IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF # THE POSSIBILITY OF SUCH DAMAGE. # # # CalDate computes the day of the week, the day of the year # the gregorian (or julian) calendar date and the universal # time from the julian decimal date. # for astronomical purposes, The Gregorian calendar reform occurred # on 15 Oct. 1582. This is 05 Oct 1582 by the julian calendar. # # Input: a ut_instant structure pointer, where the j_date element # has been set. ( = 0 for 01 Jan -4712 12 HR UT ) # # output: will set all the other elements of the structure. # As a convienence, the function will also return the year. # # Reference: Astronomial formulae for calculators, meeus, p 23 # from fortran program by F. Espenak - April 1982 Page 277, # 50 Year canon of solar eclipses: 1986-2035 # # # # The structure of a date is: #typedef struct ut_instant { # double j_date; /* julian decimal date, 0 = 01 Jan -4712 12 HR UT */ # int year; /* year, valid range [-4,712, +2,147,483,647] */ # int month; /* [1-12] */ # int day; /* [1-31] */ # int i_hour; /* [0-23] */ # int i_minute; /* [0-59] */ # double second; /* [0-59.9999] */ # double d_hour; /* [0.0-23.9999] includes minute and second */ # double d_minute; /* [0.0-59.9999] includes second */ # int weekday; /* [0-6] */ # int day_of_year; /* [1-366] */ #} UTinstant, * UTinstantPtr; Version() { echo "dbd.awk - version 1.3 - 2002/11/11 11:11:11 UTC - JD 2452589.966100" echo "\t%Copyright(C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - jday at hiram.ws" } Usage() { echo "usage: dbd.awk " Version exit 0 } if [ $# -ne 1 ]; then JD=2440588.000000 # default is 1970/01/01 12:00:00 else JD=$1 fi while [ $# -gt 0 ] do case $1 in -h|--h|-help|--help) Usage ;; -v|--v|-version|--version) Version ;; *) JD=$1 ;; esac shift done TODAY=`./jday.awk 2>&1` echo "$TODAY" "$JD" | awk ' func CalDate( date_cd ) { jd_cd = int(date_cd[j_date_i] + 0.5); # /* integer julian date */ frac_cd = date_cd[j_date_i] + 0.5 - jd_cd + 1.0e-10; #/* day fraction */ ka_cd = int(jd_cd); if ( jd_cd >= 2299161 ) { ialp_cd = int(( jd_cd - 1867216.25 ) / ( 36524.25 )); ka_cd = int(jd_cd + 1 + ialp_cd - ( int(ialp_cd / 4) )); } kb_cd = ka_cd + 1524; kc_cd = int(( kb_cd - 122.1 ) / 365.25); kd_cd = int(kc_cd * 365.25); ke_cd = int(( kb_cd - kd_cd ) / 30.6001); date_cd[day_i] = kb_cd - kd_cd - int( ke_cd * 30.6001 ); if ( ke_cd > 13 ) { date_cd[month_i] = ke_cd - 13; } else { date_cd[month_i] = ke_cd - 1; } if ( (date_cd[month_i] == 2) && (date_cd[day_i] > 28) ) date_cd[day_i] = 29; if ( (date_cd[month_i] == 2) && (date_cd[day_i] == 29) && (ke_cd == 3) ) { date_cd[year_i] = kc_cd - 4716; } else { if ( date_cd[month_i] > 2 ) { date_cd[year_i] = kc_cd - 4716; } else { date_cd[year_i] = kc_cd - 4715; } } date_cd[d_hour_i] = frac_cd * 24.0; #/* hour */ date_cd[i_hour_i] = int(date_cd[d_hour_i]); date_cd[d_minute_i] = ( date_cd[d_hour_i] - date_cd[i_hour_i] ) * 60.0; # /* minute */ date_cd[i_minute_i] = int(date_cd[d_minute_i]); date_cd[second_i] = 60.0 * \ (date_cd[d_minute_i] - date_cd[i_minute_i] ); #/* second */ date_cd[weekday_i] = int((jd_cd + 1) % 7); # /* day of week */ if ( date_cd[year_i] == int(((int(date_cd[year_i] / 4)) * 4)) ) { date_cd[day_of_year_i] = ( ( 275 * date_cd[month_i] ) / 9) \ - ((date_cd[month_i] + 9) / 12) \ + date_cd[day] - 30; } else { date_cd[day_of_year_i] = int( ( 275 * date_cd[month_i] ) / 9) \ - int(((date_cd[month_i] + 9) / 12) * 2) \ + date_cd[day] - 30; } return( date_cd[year_i] ); } # /* end of int CalDate( date ) */ # # JulDate computes the julian decimal date (j_date) from # the gregorian (or Julian) calendar date. # for astronomical purposes, The Gregorian calendar reform occurred # on 15 Oct. 1582. This is 05 Oct 1582 by the julian calendar. # Input: a ut_instant structure pointer where Day, Month, Year and # i_hour, i_minute, second have been set for the date # in question. # # Output: the j_date and weekday elements of the structure will be set. # Also, the return value of the function will be the j_date too. # # Reference: Astronomial formulae for calculators, meeus, p 23 # from fortran program by F. Espenak - April 1982 Page 276, # 50 Year canon of solar eclipses: 1986-2035 # func JulDate( date_jd ) { # /* decimal day fraction */ frac_jd = (date_jd[i_hour_i]/ 24.0) \ + (date_jd[i_minute_i] / 1440.0) \ + (date_jd[second_i] / 86400.0); # /* convert date to format YYYY.MMDDdd */ gyr_jd = date_jd[year_i] + (0.01 * date_jd[month_i]) \ + (0.0001 * date_jd[day_i]) \ + (0.0001 * frac_jd) + 1.0e-9; # /* conversion factors */ if ( date_jd[month_i] <= 2 ) { iy0_jd = date_jd[year_i] - 1; im0_jd = date_jd[month_i] + 12; } else { iy0_jd = date_jd[year_i]; im0_jd = date_jd[month_i]; } ia_jd = int(iy0_jd / 100); ib_jd = int(2 - ia_jd + int(ia_jd / 4)); # /* calculate julian date */ if ( date_jd[year_i] <= 0 ) jd_jd = int(((365.25 * iy0_jd) - 0.75)) \ + int((30.6001 * (im0_jd + 1) )) \ + int(date_jd[day_i] + 1720994); else jd_jd = int((365.25 * iy0_jd)) \ + int((30.6001 * (im0_jd + 1))) \ + int(date_jd[day_i] + 1720994); if ( gyr_jd >= 1582.1015 ) # /* on or after 15 October 1582 */ jd_jd += ib_jd; date_jd[j_date_i] = jd_jd + frac_jd + 0.5; jd_jd = int((date_jd[j_date_i] + 0.5)); date_jd[weekday_i] = int((jd_jd + 1) % 7); return( date_jd[j_date_i] ); } # /* end of double JulDate( date ) */ func PrintDate ( d ) { printf( "jd: %.6f = ", d[j_date_i] ); printf( "%d/%02d/%02d %02d:%02d:%02d\n", d[year_i], d[month_i], \ d[day_i], d[i_hour_i], d[i_minute_i], \ int(d[second_i] + 0.5) ); } func ZeroDate ( d ) { d[j_date_i] = 0.0; d[year_i] = 0; d[month_i] = 0; d[day_i] = 0; d[i_hour_i] = 0; d[i_minute_i] = 0; d[second_i] = 0; d[d_hour_i] = 0.0 d[d_minute_i] = 0.0; d[weekday_i] = 0; d[day_of_year_i] = 0; } # # Define our structure with array indices # BEGIN { j_date_i = 1; year_i = 2; month_i = 3; day_i = 4; i_hour_i = 5; i_minute_i = 6; second_i = 7; d_hour_i = 8; d_minute_i = 9; weekday_i = 10; day_of_year_i = 11; test_jd[j_date_i] = 0.0; ZeroDate(test_jd); } { if ( $1 > $2 ) { now[j_date_i] = $1; then[j_date_i] = $2; ET = $1 - $2; } else { now[j_date_i] = $2; then[j_date_i] = $1; ET = $2 - $1; } CalDate(now); CalDate(then); printf ("%d days = %d weeks =", int(ET), int(ET/7) ); if ( now[day_i] < then[day_i] ) { previous_month[j_date_i] = now[j_date_i] - now[day_i]; CalDate(previous_month); ET_days = previous_month[day_i] + now[day_i] - then[day_i]; if ( previous_month[month_i] < then[month_i] ) { ET_months = 12 + previous_month[month_i] - then[month_i]; ET_years = previous_month[year_i] - then[year_i] - 1; } else { ET_months = previous_month[month_i] - then[month_i]; ET_years = previous_month[year_i] - then[year_i]; } } else { ET_days = now[day_i] - then[day_i]; if ( now[month_i] < then[month_i] ) { ET_months = 12 + now[month_i] - then[month_i]; ET_years = now[year_i] - then[year_i] - 1; } else { ET_months = now[month_i] - then[month_i]; ET_years = now[year_i] - then[year_i]; } } ET_weeks = int(ET_days/7); ET_days = ET_days - (ET_weeks*7); if ( ET_years ) { if ( 1 == ET_years ) { printf ( " %d year", ET_years ); } else { printf ( " %d years", ET_years ); } } if ( ET_years && ((ET_weeks == 0) && (ET_days == 0)) ) { printf " and" } if ( ET_months ) { if ( 1 == ET_months ) { printf ( " %d month", ET_months ); } else { printf ( " %d months", ET_months ); } } if ( ET_months && ET_weeks && (ET_days == 0) ) { printf " and" } if ( ET_weeks ) { if ( 1 == ET_weeks ) { printf ( " %d week", ET_weeks ); } else { printf ( " %d weeks", ET_weeks ); } } if ( ET_days ) { if ( 1 == ET_days ) { if ( ET_years || ET_months || ET_weeks ) { printf ( " and a day" ); } else { printf ( " one day" ); } } else { if ( ET_years || ET_months || ET_weekss ) { printf ( " and %d days", ET_days ); } else { printf ( " %d days", ET_days ); } } } printf (".\n"); }'