command line fun – juliane day number to gregorian

In a previous blog, I implemented a routine to convert a Gregorian date into a Juliane day number to allow simple math and comparisons on dates.

This was pretty cool but it is less useful if you cannot convert back into a user friendly version of the date.

The conversion routines in the wikipedia entry also cover converting back to a Gregorian day, month and year.  I have also implemented a routine to calculate the day of the week.

#!/bin/bash

# https://en.wikipedia.org/wiki/Julian_day#Converting_Julian_or_Gregorian_calendar_date_to_Julian_day_number

twodig()
{
  val=$1
  retval=$val

  if [ $val -lt 10 ]
  then
    retval=`echo 0${val} `
  fi
  echo $retval
}

# div = floor(dividend / divisor)
div()
{
  echo $(( $1 / $2 ))
}
# quotient = dividend / divisor
modulo()
{
 echo $(($1 % $2))
}

# the lowest whole number
floor()
{
  X=$1
  echo ${X%.*}
}

# day of week name
dayofweek()
{
  expr=$1

  case $expr in
   1) retval=mon;;
   2) retval=tue;;
   3) retval=wed;;
   4) retval=thr;;
   5) retval=fri;;
   6) retval=sat;;
   7) retval=sun;;
   esac

   echo $retval
}

# ordnal number of day of week
dayofweekIdx()
{ 
  idx=`modulo $1 7`
  idx=`echo "$idx + 1" | bc -l`
  echo $idx
}

#####################################################################################################
# calculate the actual gregorian day/month/year from the julian value                               #
#####################################################################################################
getGregorian()
{
  J=$1

  y=4716
  v=3
  j=1401
  u=5
  m=2
  s=153
  n=12
  w=2
  r=4
  B=274277
  p=1461
  C="(−38)"


  # 1.
  #
  # f = jd + j + ((   ( 4 * J + B)   div 146097) * 3) div 4 + C
  #echo "f = $J + $j + ((   ( 4 * $J + $B)   div 146097) * 3) div 4 + $C"
  tmp=`echo "4 * $J + $B" | bc -l`
  tmp=`div $tmp 146097`
  tmp=`echo "$tmp * 3" | bc -l`
  tmp=`div $tmp 4`
  tmp=`echo "$J + $j + $tmp - 38" | bc -l`
  f=$tmp
  #echo f $f


  # 2.
  #
  # e = r * f + v
  #echo "e= $r * $f + $v "
  e=`echo "$r * $f + $v " | bc -l`
  #echo e $e


  # 3.
  #
  # g = mod (e,p) div r
  #echo "g = mod ($e,$p) div $r"
  g=`modulo $e $p`
  g=`div $g $r`
  #echo g $g


  # 4.
  #
  # h = u * g + w
  #echo "h = $u * $g + $w"
  h=`echo "$u * $g + $w" | bc -l`
  #echo h $h

  # 5.
  #
  # D = (mod(h,s)) div u + 1
  #echo "D = (mod($h,$s)) div $u + 1"
  D=`modulo $h $s`
  D=`div $D $u`
  D=`expr $D + 1`
  D=`twodig $D`
  #echo D $D


  # 6.
  #
  # M = mod(h div s + m, n) + 1
  #echo "M =  mod($h div $s + $m,$n) + 1"
  M=`div $h $s`
  M=`expr $M + $m`
  M=`modulo $M $n`
  M=`expr $M + 1`
  M=`twodig $M`
  #echo M $M


  # 7.
  #
  # Y =  (e div p) - y + (n + m - M) div n
  #echo "Y =  ($e div $p) - $y + ($n + $m - $M) div $n"
  Y=`expr $n + $m - $M`
  Y=`div $Y $n`
  tmp=`div $e $p`
  Y=`expr $tmp - $y + $Y`
  #echo Y $Y

  echo $Y$M$D
}

JD=2451545
USERDATE=`getGregorian $JD`
IDX=`dayofweekIdx $JD`
DAYOFWEEK=`dayofweek $IDX`
echo $USERDATE is a $DAYOFWEEK

idx=0
while [ $idx -lt 15 ]
do
  JD=$((2451554 + $idx))
  IDX=`dayofweekIdx $JD`
  DAYOFWEEK=`dayofweek $IDX`
  echo $JD $IDX $DAYOFWEEK

  idx=$(($idx + 1))
done

 

This entry was posted in Command line, programming and tagged , . Bookmark the permalink.