HP OpenVMS Systemsask the wizard 
The Question is: How do you convert Gregorian time to Julian time using DCL. The Answer is : There are no less than three different daterelated constructs confusingly all refered to as "Julian": o The Julian Day that is the number of days since Julian Day One began at 12:00 noon, January 1, 4713 BC, this was a construct of Joseph Scaliger and dates to the sixteenth century. (This scheme was named for Julius Caesar Scaliger, Joseph Scaliger's father.) o The Julian Day that is the year and the number of days that have passed in the specified year. o The Julian Calendar, named for the Roman Emporer Julius Caesar (not Scaliger). The Julian calendar eliminated the need for the month of Mercedonius, but was roughly 11.5 minutes off sideral time. The Julian calendar precedes the Gregorian Calendar. (The Gregorian calendar is better by roughly 11.5 minutes per year, and also now the calendar that is in common use in many countries.) For details of time and timekeeping and some background on Scaliger's Julian , please see the OpenVMS FAQ. For a C tool that uses the number of days since the OpenVMS System base date 17Nov1858  this tool uses the first definition of Julian Day listed above  and it works within a DCL command procedure, please see: http://www.openvms.compaq.com/freeware/srh_examples/dsbd.c http://www.openvms.compaq.com/freeware/srh_examples/dsbd.com The third meaning of Julian  the calendar  requires details on where the date was recorded, as various countries switched from the Julian Calendar to the Gregorian Calendar at different dates. Spain and Spanish colonies (including the US state of Florida) followed 4Oct1582 with 15Oct1582. Catholic German states adopted the calendar in 1583, while Protestant German states switched in 1699. England and colonies (Canada, nonFrench, non Spanish US) followed 2Sep1752 with 14Sep1752, Sweden in 1753, Alaska switched when the territory was purchased in 1867 (dropped 10 days), Japan in 1873, China in 1912 (13 days), the Soviet Union in 1918 (13 days), Greece in 1923 (also 13 days). Switzerland used both calendars in parallel between 1583 and 1812, before fully adopting the Gregorian Calendar. The Russian Orthodox church and a few other organizations reportedly still use the Julian Calendar. Each conversion required removing a different number of days. A somewhat more complex (and DCLonly) solution  for the second meaning of Julian above  follows:  1) JULIAN.COM  which converts the Gregorian date, in the format of DDMMMYYYY (1JAN1992) into a Julian date, in the format of YYYYddd (1992001). The Julian date here is a 4 character year followed by a three character day of the year. 2) GREGORIAN.COM  which converts the Julian date into a Gregorian date, the reverse of JULIAN.COM. 3) DAY_OF_WEEK.COM  which takes a Gregorian date and tells which day of the week it fell on (Monday, Tuesday, etc). This routine also provides a unique "factor" number which can be used in calculating the days between two dates. 4) DAYS_BETWEEN_DATES.COM  uses DAY_OF_WEEK.COM to calculate the number of days that occur between two Gregorian dates. Thus to use this routine you must also have DAY_OF_WEEK.COM available as well. These command procedures are intended to be starting points on how these type of operations might be done. Extensive error checking and validation are not performed by these example procedures. Dates in different formats would have to have the algorithms modified slightly for proper execution, as the command procedures currently only support the DDMMMYYYY Gregorian date and the YYYYddd Julian Date.  JULIAN.COM  $! JULIAN.COM $!  $! This example DCL Command Procedure takes a date in the format $! of DDMMMYYYY (1JAN1991) and converts it into a "Julian" type $! date of the style YYYYddd (1991001), where "ddd" is the number $! of days since the beginning of the year. If no input is provided $! then the "Julian" date for TODAY is displayed. It is unsupported $! and provided as is, and is meant to serve as a general guide to $! how the date could be transformed with DCL. $! $! To invoke this DCL Command Procedure you can enter the command $! $ @JULIAN 13DEC1991 $! The Julian Date for 13DEC1991 is 1991347 . $! $! INPUTS: $! P1  the input date. If none is specified then the current $! date is used. $! P2  if it contains the string "SUPPRESS" the normal output $! of this command procedure will be suppressed. Any errors $! will be returned though. $! $! OUTPUTS: $! Text may be written to the screen, and two global symbols $! will be set up and used: $! $! JULIAN_DATE <> "" contains the Julian date as a text string $! JULIAN_DATE == "" indicates an error was encountered $! LEAP_YEAR == 0 indicates the input year was not a leap year $! LEAP_YEAR == 1 indicates the input year was a leap year $! $ if p1 .eqs. "" then p1 = f$element(0," ",f$time()) $ say := write sys$output $ mon_text = "JAN/FEB/MAR/APR/MAY/JUN/JUL/AUG/SEP/OCT/NOV/DEC/" $ mon_days = "31/28/31/30/31/30/31/31/30/31/30/31/" $ leap_days= "31/29/31/30/31/30/31/31/30/31/30/31/" $ day_temp = f$integer(f$element(0,"",p1)) $ mon_temp = f$element(1,"",p1) $ if f$locate(mon_temp,mon_text) .eq. f$length(mon_text) then goto CONT4 $ year_temp = f$extract(0,4,f$element(2,"",p1)) $! $! Now we must consider leap year. If the year is divisible by $! 4 then it may be a leap year, unless it is a century year $! in which case it must be divisible by 400 (the year 2000 is $! a leap year, but the year 1900 was not). $! $ year = f$integer(year_temp) $! $! Now that we have the year as an integer we do another check. $! The Gregorian calendar as we now it today was implemented by $! Pope Gregory XIII who decreeded that Thursday, Oct 4, 1582 $! was the last day of the Julian calendar and the next day would $! be Friday Oct 15, 1582. The missing days were to correct the $! centuries of uncorrected leap years that had slowly added up $! and set the calendar off. Under the current calendar implemetation $! it would take about 3323 years finally be off a single day again. $! But this also means that years before 1583 may not be accurately $! represented by this algorithm. Different countries also decided $! to implement the Gregorian calendar at different times in history. $! The Germans and Dutch did not change to the new calendar until $! 1698. The English shift took place in 1752, and in Russia it $! was not adopted until 1918. $! $ leap_year == 0 $ if day_temp .le. 0 then goto ERROROUT $ if day_temp .gt. 31 then goto ERROROUT $ if year .lt. 1583 then goto ERROROUT ! Take care of calendar conversion time $ if year .gt. 4905 then goto ERROROUT ! 1582+3323 = year 4905 $ if (year/4)*4 .ne. year then goto CONT2 ! Leap years divisble by 4 $ if (year/100)*100 .ne. year then goto CONT1 ! Centuries divisible by 100 $ if (year/400)*400 .ne. year then goto CONT2 ! Century leap year by 400 $CONT1: $ leap_year == 1 $ mon_days = leap_days $CONT2: $ num = 0 $ julian_days = 0 $COUNT_DAYS: $ if mon_temp .eqs. f$element(num,"/",mon_text) then goto CONT3 $ julian_days = julian_days + f$element(num,"/",mon_days) $ num = num + 1 $ if num .gt. 11 then goto CONT4 $ goto COUNT_DAYS $CONT3: $ if day_temp .gt. f$integer(f$element(num,"/",mon_days)) then goto ERROROUT $ julian_days = julian_days + day_temp $! $! The "Julian" date provided has the "ddd", day of year, formated $! with leading zeros. If this is not desired change the following $! "!3ZL" to some other format, such as "!UL" which is currently $! commented out. $! text = f$fao("!UL ",julian_days) $ text = f$fao("!3ZL ",julian_days) $ julian_date == year_temp + text ! Make a Global Symbol $ if p2 .eqs. "SUPPRESS" then exit $ say "The Julian Date for ",p1," is ",julian_date,"." $ exit $ERROROUT: $ say "The Date provided ",p1," is invalid or out of range." $ julian_date == "" ! Make error condition $ exit  GREGORIAN.COM  $! GREGORIAN.COM $!  $! This example DCL command procedure takes a "Julian" date of $! the form "YYYYddd" (1991001) and converts it into a Gregorian $! style date (1JAN1991). Is is unsupported and meant to be $! an example. A more detailed explanation of some of the algorithm $! appears in a "sister" DCL command procedure named JULIAN.COM, $! that translates the Gregorian Date into a Julian Date. $! $! This command procedure can be invoked with: $! $ @GREGORIAN 1991001 $! The Julian Date 1991001 is 1JAN1991 $! $! INPUTS: $! P1  the input Julian date, if none is specified you will be $! prompted for one. $! P2  if it contains the string "SUPPRESS" then the normal $! output of this command procedure will be suppressed. $! Any errors will be returned though. $! $! OUTPUTS: $! Text may be written out to the screen, and two global $! symbols will be set up and used: $! $! GREGORIAN_DATE <> "" contains the Gregorian date $! GREGORIAN_DATE == "" indicates an error was encountered $! LEAP_YEAR == 0 indicates the input year was not a leap year $! LEAP_YEAR == 1 indicates the input year was a leap year $! $ if p1 .eqs. "" then inquire p1 "Enter the Julian Date " $ say := write sys$output $ mon_text = "JAN/FEB/MAR/APR/MAY/JUN/JUL/AUG/SEP/OCT/NOV/DEC/" $ mon_days = "31/28/31/30/31/30/31/31/30/31/30/31/" $ leap_days= "31/29/31/30/31/30/31/31/30/31/30/31/" $ year_text = f$extract(0,4,p1) $ year = f$integer(year_text) $ days = f$integer(f$extract(4,3,p1)) $ if year .lt. 1583 then goto ERROROUT ! validate ranges $ if year .gt. 4905 then goto ERROROUT $ if days .le. 0 then goto ERROROUT $ if days .gt. 366 then goto ERROROUT $ julian_days = days $ days = 0 $ mon = 0 $ leap_year == 0 $ if (year/4)*4 .ne. year then goto COUNT_J_DAYS ! take care leap years $ if (year/100)*100 .ne. year then goto CONT1 $ if (year/400)*400 .ne. year then goto COUNT_J_DAYS $CONT1: $ leap_year == 1 $ mon_days = leap_days $COUNT_J_DAYS: $ days = days + f$element(mon,"/",mon_days) $ if days .ge. julian_days then goto EXIT_COUNT_J $ mon = mon + 1 $ if mon .gt. 11 then goto ERROROUT $ goto COUNT_J_DAYS $EXIT_COUNT_J: $ days = days  f$element(mon,"/",mon_days) $ day = julian_days  days $ month_text = f$element(mon,"/",mon_text) $ Gregorian_date == "''day'" + "" + month_text + "" + year_text $ if p2 .eqs. "SUPPRESS" then exit $ say "The Julian date ",p1," is Gregorian ",Gregorian_date $ exit $ERROROUT: $ say "The input Julian date of ",p1," is invalid or out of range" $ Gre gorian_date == "" $ exit  DAY_OF_WEEK.COM  $! DAY_OF_WEEK.COM $!  $! This command procedure takes an alternative method to calculate $! the day of the week. The easy method with VMS DCL would be to $! simply use the lexical function $! $! DAY_OF_WEEK = F$CVTIME(input_time,,"WEEKDAY") $! $! This routine is being used to test the FACTOR produced by the $! following DCL command procedure before using it to calculate $! the number of days between dates in DCL command procedure $! DAYS_BETWEEN_DATES.COM. It also gives a simple algorithm that $! could be implemented in other programming languages. It is $! unsupported and provided as is. Additional date validation $! could be performed (but is not at this time). If you do want $! to valiate the date further look at the more extensive error $! checking in JULIAN.COM. $! $! You can use this DCL command procedure as follows: $! $ @DAY_OF_WEEK 13DEC1991 $! 13DEC1991 is a Friday. $! $! INPUTS: $! P1  if no date is specified then TODAYs date is used $! P2  if it contains the string "SUPPRESS" then the normal $! output of this command procedure will be suppressed. $! Any errors will be printed though. $! $! OUTPUTS: $! Text may be written out to the screen, and two global symbols $! will be set up and used: $! $! DAY_OF_WEEK <> "" then it will contain the text string indicating $! the day of the week (Saturday, Sunday, Monday, etc). $! DAY_OF_WEEK == "" indicates an error condition $! FACTOR <> 0 gives a unique number of days factor for this date $! FACTOR = 0 indicates an error condition $! $ if p1 .eqs. "" then p1 = f$element(0," ",f$time()) $ say := write sys$output $ week_day = "Saturday/Sunday/Monday/Tuesday/Wednesday/Thursday/Friday/" $ mon_text = "JAN/FEB/MAR/APR/MAY/JUN/JUL/AUG/SEP/OCT/NOV/DEC/" $ day_temp = f$integer(f$element(0,"",p1)) $ mon_temp = f$element(1,"",p1) $ year_temp = f$integer(f$extract(0,4,f$element(2,"",p1))) $ month_temp = 0 $ if year_temp .le. 1583 then goto ERROROUT $ if year_temp .gt. 4905 then goto ERROROUT $ if day_temp .le. 0 then goto ERROROUT $ if day_temp .gt. 31 then goto ERROROUT $ if f$locate(mon_temp,mon_text) .eq. f$length(mon_text) then goto ERROROUT $COUNT_MONTHS: $ if mon_temp .eqs. f$element(month_temp,"/",mon_text) then goto CONT1 $ month_temp = month_temp + 1 $ goto COUNT_MONTHS $CONT1: $ month_temp = month_temp + 1 $! $! For January and February the equation is: $! FACTOR = 365(YYYY) + DD + 31(MM1) + INT((YYYY1)/4)  $! INT( 3/4 * (INT(((YYYY1)/100)+1)) $! $ if month_temp .ge. 3 then goto FIGURE2 $ FACTOR == 365 * year_temp + day_temp + 31 * (month_temp  1)  + (year_temp 1)/4  (((((year_temp1)/100)+1)*3)/4) $ GOTO CONT2 $! $! For March through December the equation is: $! FACTOR = 365(YYYY) + DD + 31(MM1)  INT(.4MM + 2.3) + $! INT(YYYY/4)  INT( 3/4 * (INT(YYYY/100) + 1)) $! $FIGURE2: $ FACTOR == 365 * year_temp + day_temp + 31 * (month_temp  1)   (4 * month_temp + 23)/10  + year_temp/4  ((((year_temp/100)+1)*3)/4) $! $! The day of the week can be found from the FACTOR for the date $! Day_of_week = FACTOR + (INT (FACTOR/7) * 7) $! Where 0 is Saturday and 6 is Friday. $! $CONT2: $ INDEX = FACTOR + (FACTOR/7)*7 $ DAY_OF_WEEK == F$ELEMENT(INDEX,"/",week_day) $ if p2 .eqs. "SUPPRESS" then exit $ say p1," is a ",DAY_OF_WEEK $ exit $! The solar year is 365.242216 days; 365 days, 5 hours, 48 min, 46 seconds $! The lunation is 29.530585 days; 29 days, 12 hours, 44 min, 2.8 seconds $! Twelve Lunations 364.3671 days; 364 days, 8 hours, 48 min, 34 seconds $ERROROUT: $ say "The date ",p1," is invalid or out of range." $ DAY_OF_WEEK == "" $ FACTOR == 0 $ EXIT $! Known dates to compare against: $! 25DEC2000 is on a Monday $! 25DEC1900 was on a Tuesday $! 25DEC2063 is on a Tuesday (same calendar as 1900) $! 25DEC1991 is on a Wednesday $! 25DEC1800 was on a Thursday $! 25DEC1998 is on a Friday $! 25DEC2060 is on a Saturday $! 25DEC1994 is on a Sunday  DAYS_BETWEEN_DATES.COM  $! DAYS_BETWEEN_DATES.COM $!  $! To calculate the day between two dates we calculate a FACTOR $! for each date. The difference of the FACTORs is the number $! of days. The Factor is given in another DCL command procedure $! DAY_OF_WEEK.COM. $! $! INPUTS: $! P1  input date, if not specified you will be prompted for it. $! P2  second input date, if not specified you will be prompted $! for it. $! P3  if it contains the string "SUPPRESS" then the normal $! output of this command procedure will be suppressed. $! Any errors will be printed. $! OUTPUTS: $! Text may be written out to the screen, and a global symbol $! will be set up: $! DAYS_BETWEEN_DATES == 1 indicates and error condition $! DAYS_BETWEEN_DATES <> 1 contains the number of days between $! the input dates. $! $! Some dates to check on: $! Between June 1, 1960 and October 31, 1976 are 5996 days $! Between Oct 1, 1976 and Oct 31, 1976 are 30 days $! $ say := write sys$output $ if p1 .eqs. "" then inquire p1 "Enter First Date " $ if p2 .eqs. "" then inquire p2 "Enter Second Date " $ days_between_dates == 1 $ day1 = "''p1'" $ @DAY_OF_WEEK 'p1 SUPPRESS $ factor1 = factor $ day2 = "''p2'" $ @DAY_OF_WEEK 'p2 SUPPRESS $ factor2 = factor $ if factor1 .eq. 0 then exit $ if factor2 .eq. 0 then exit $ if factor1 .gt. factor2 $ then $ days_between_dates == factor1  factor2 $ else $ days_between_dates == factor2  factor1 $ endif $ if p3 .eqs. "SUPPRESS" then exit $ say "The days between ",day1," and ", day2," are ", days_between_dates," days" $ exit
