Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Reading input in the format of DDMMYYYY? Help!

Status
Not open for further replies.

cooljosh2k2

Technical User
Oct 4, 2011
5
CA
In an assignment i have, i am to enter a date in the format DDMMYYYY, and its suppose to compute and display the day of the week that date falls on (based on a given algorithm). I was able to code a program that would give me the right day of the week, however, i was only able to get it to work in the format: date, month, year (with commas separating each of them). How can i get my program to read the date DDMMYYYY, without the commas.

Here's what i have coded (keep in mind i am new to this):

---------------------------------------------
PROGRAM assignment2
IMPLICIT NONE

INTEGER:: Day, Month, Year, Century, H

READ(*,*) Day,Month,Year !to read in format DD,MM,YYYY

Month = Month -2
!this accounts for unusual format for months (eg. March=01......February=12)
If (Month <= 0) Month = Month + 12
IF (Month >= 11) Year = Year - 1
Century = INT(Year / 100)
!eg. 2011 = 20
Year = MOD(Year, 100)
!eg. 2011= 11
H = INT(13 * Month - 1)/5 + Day + Year + &
(Year / 4) + (Century / 4) - 2*Century
H = MOD(H,7)
IF (MOD(H,7) < 0) H = MOD(H,7) + 7
!this will make sure our day of the week is a positive integer
write(*,*) 'Day Of the Week :',H


END PROGRAM assignment2


--------------------------------
Please help me.

Thanks
 
Things can be made a lot simpler.

All you need to do is specify a read format, for example:

read(*,'(i2,i2,i4)') Day, Month, Year

The statement above will read such thing as DDMMYYYY, like that, without commas.

 
You are basically coding up Zeller's congruence. See The formula you are using is for the Gregorian calendar.

Just note that mod will give you the wrong answer when h is negative. Check your coding.

-6 mod 7 = -6 should be 1
-5 mod 7 = -5 should be 2
-1 mod 7 = -1 should be 6
1 mod 7 = 1 correct
5 mod 7 = 5 correct
 
Thanks salgerman!

And to xwb, i thought by adding IF (MOD(H,7) < 0) H = MOD(H,7) + 7 at the end of the code, H will always give a positive number. Havent had a problem with the formula giving a wrong answer yet.
 
There is a part 2 to my assignment that i have no idea how to do. I am to compute the day of the week my birthday fell on (Sunday or 0), and then write a code that will give me the next five years (after 2011) that my birthday falls on the same day of the week (sunday).

I understand that im supposed to do some kind of a DO LOOP, but am way too lost to even know where to start. Any ideas?
 
Well, that does not have anything to do with Fortran, does it?

You just need to do a do loop for the next few years, put your birthday in (mmddyyyy) and call your function...if the day of the week is zero, then you print that one out...clear?
 
Not really lol. I understand what you are saying, i just dont know how to code it. It took me a while to write the code for part 1.

I also dont understand why it has nothing to do with FORTRAN. It has to be coded in FORTRAN.

Thanks for helping, btw.
 
YOUR problem has nothing to do with Fortran, because you do not seem to have an idea on how to write pseudo code or a little flow diagram of what you are supposed to do, etc...you really need to practice this and figure which way is best for you to visualize in a programming-language-independent manner.

Having said that...I would write a short function that returns the day of the week (number from 1 to 7) the date provided falls in.

Let's say your birthday was October 3rd, 1971...03,10,1971

do year=2012, 2020
n = day_number(3,10,year)
if (n==0) then
write(*,*) 'In ', year, ' my birthday will be a sunday'
end if
end do

where the function day_number() implements your algorithm and returns the day of the week.



I has nothing to do with fortran because you
 
cooljosh2k2 said:
How can i get my program to read the date DDMMYYYY, without the commas.
I would simply try something like this:
Code:
[COLOR=#a020f0]program[/color] ddmmyyyyy;
  [COLOR=#2e8b57][b]implicit[/b][/color] [COLOR=#2e8b57][b]none[/b][/color]

  [COLOR=#2e8b57][b]integer[/b][/color] :: date_num, day_num, month_num, year_num
  [COLOR=#2e8b57][b]character[/b][/color]([COLOR=#ff00ff]8[/color]) :: date_str
  [COLOR=#2e8b57][b]character[/b][/color]([COLOR=#ff00ff]2[/color]) :: day_str, month_str
  [COLOR=#2e8b57][b]character[/b][/color]([COLOR=#ff00ff]4[/color]) :: year_str
  
  [COLOR=#804040][b]write[/b][/color] ([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#ff00ff]"Enter date (ddmmyyyy) = "[/color]
  [COLOR=#804040][b]read[/b][/color] ([COLOR=#804040][b]*[/b][/color], [COLOR=#ff00ff]'(I8.8)'[/color]) date_num
  [COLOR=#0000ff]! convert number to string[/color]
  [COLOR=#804040][b]write[/b][/color] (date_str, [COLOR=#ff00ff]'(I8.8)'[/color]) date_num
  [COLOR=#0000ff]! substrings: day, month, year[/color]
  day_str   [COLOR=#804040][b]=[/b][/color] date_str([COLOR=#ff00ff]1[/color]:[COLOR=#ff00ff]2[/color])
  month_str [COLOR=#804040][b]=[/b][/color] date_str([COLOR=#ff00ff]3[/color]:[COLOR=#ff00ff]4[/color])
  year_str  [COLOR=#804040][b]=[/b][/color] date_str([COLOR=#ff00ff]5[/color]:[COLOR=#ff00ff]8[/color])
  [COLOR=#0000ff]! convert strings to numerical values[/color]
  [COLOR=#804040][b]read[/b][/color] (day_str,[COLOR=#ff00ff]'(I2)'[/color]) day_num    
  [COLOR=#804040][b]read[/b][/color] (month_str,[COLOR=#ff00ff]'(I2)'[/color]) month_num    
  [COLOR=#804040][b]read[/b][/color] (year_str,[COLOR=#ff00ff]'(I4)'[/color]) year_num    

  [COLOR=#804040][b]write[/b][/color] ([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#ff00ff]"date_str  = '"[/color], date_str, [COLOR=#ff00ff]"'"[/color]
  [COLOR=#804040][b]write[/b][/color] ([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#ff00ff]"day_str   = '"[/color], day_str, [COLOR=#ff00ff]"'"[/color]
  [COLOR=#804040][b]write[/b][/color] ([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#ff00ff]"month_str = '"[/color], month_str, [COLOR=#ff00ff]"'"[/color]
  [COLOR=#804040][b]write[/b][/color] ([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#ff00ff]"year_str  = '"[/color], year_str, [COLOR=#ff00ff]"'"[/color]

  [COLOR=#804040][b]write[/b][/color] ([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#ff00ff]"date_num  = "[/color], date_num
  [COLOR=#804040][b]write[/b][/color] ([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#ff00ff]"day_num   = "[/color], day_num
  [COLOR=#804040][b]write[/b][/color] ([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#ff00ff]"month_num = "[/color], month_num
  [COLOR=#804040][b]write[/b][/color] ([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#ff00ff]"year_num  = "[/color], year_num
[COLOR=#a020f0]end program[/color] ddmmyyyyy;
Code:
$ g95 ddmmyyyy.f95 -o ddmmyyyy

$ ddmmyyyy
 Enter date (ddmmyyyy) = 
22041966
 date_str  = '22041966'
 day_str   = '22'
 month_str = '04'
 year_str  = '1966'
 date_num  =  22041966
 day_num   =  22
 month_num =  4
 year_num  =  1966

$ ddmmyyyy
 Enter date (ddmmyyyy) = 
5102011
 date_str  = '05102011'
 day_str   = '05'
 month_str = '10'
 year_str  = '2011'
 date_num  =  5102011
 day_num   =  5
 month_num =  10
 year_num  =  2011
 
mikrom:

You call that simply?

You first read an 8 digit number into an integer, THEN
you write that number into a string, THEN
you split that string into 3 different strings, THEN
you read those individual strings to retrieve integers back again.

That's quite a round trip!

What happened to SIMPLY reading the numbers straight into their final destinations? Like this:

program ddmmyyy
integer dd,mm,yyyy
write(*,*) "Enter date (ddmmyyy) = "
read(*,'(i2,i2,i4)') dd,mm,yyyy
write(*,*) "day = ", dd
write(*,*) "month = ", mm
write(*,*) "year = ", yyyy
end



 
I took what you said salgerman, and added it to my code (after modifying it a tad). But when i try to compile it, i get an error message:

--------------
tttt.f90:4:
INTEGER:: Day, Month, Year, Century, H, N
1
tttt.f90:23: (continued):
N = H(10,07,year)
2
Invalid declaration of or reference to symbol `h' at (2) [initially seen at (1)]

-------------
-----------------
Heres what my code looks like:

PROGRAM assignment2
IMPLICIT NONE

INTEGER:: Day, Month, Year, Century, H, N

read(5,100)Day,Month,Year
100 format(2i2,1i4) !to read in format DDMMYYYY

Month = Month -2
!this accounts for unusual format for months (eg. March=01......February=12)
If (Month <= 0) Month = Month + 12
IF (Month >= 11) Year = Year - 1
Century = INT(Year / 100)
!eg. 2011 = 20
Year = MOD(Year, 100)
!eg. 2011= 11
do year=2012, 2100
H = INT(13 * Month - 1)/5 + Day + Year + &
(Year / 4) + (Century / 4) - 2*Century
H = MOD(H,7)
IF (MOD(H,7) < 0) H = MOD(H,7) + 7
N = H(10,07,year)
if (N==0) then
write(*,*) 'My birthday will fall on a sunday in the year: ', year
end if
end do

END PROGRAM assignment2

--------------------------

What am i doing wrong?
 
What you need to do is declare a function, outside of your main program that you can then call within your main program...as it is, your code attempts to call function H, but such function was never declared. At this time H is simply an integer; and not even an array, it is simply a scalar...so, an attempt to refer to H(.) is an error.

Your function could look like this:

Code:
integer function day_of_week(Day,Month,Year)
  implicit none
  integer Day, Month, Year
  integer d,m,y,c,h

  d = Day
  m = Month
  y = Year
  
  m = m - 2
  if (m <=  0) m = m + 12
  if (m >= 11) y = y -  1
  c = y/100        !eg. 2011 ==> 20
  y = mod(y,100)   !eg. 2011 ==> 11
  h = (13*m-1)/5 + d + y + y/4 + c/4 - 2*c
  h = mod(h,7)
  if (h < 0) h = h + 7
  day_of_week = h
end

Then, you turn around and write the main program to call this function, like so:

Code:
program assignment2

  integer day_of_week   ! function prototype
  integer birth_day
  integer dd,mm,yyyy,yr 
  
  character*9 week(0:6)  
  week=(/'Sunday   ','Monday   ','Tuesday  ','Wednesday','Thursday ','Friday   ','Saturday '/)

  write(*,*) "Enter date (ddmmyyy) = "
  read(*,'(i2,i2,i4)') dd,mm,yyyy

  birth_day = day_of_week(dd,mm,yyyy)

  do yr = 2012,2100
    if (day_of_week(dd,mm,yr) == birth_day) then
      write(*,*) 'My birthday will fall on a ',trim(week(birth_day)),' in the year: ', yr
    end if
  end do
end program assignment2

And that's it.

Notice that in the main program above, I went ahead and generalized it so that it works for anybody, not just people born on Sunday. So, now, the program takes the read in birthday and records what day of the week that is; then, it compares the result of the function call to that number to see which other year that birthday will be on the same day of the week.


 
Salgerman,
in your solution you didn't store the original input date format ddmmyyyy, who knows - maybe the user needs it in further computation.
The example I posted delivers ddmmyyyy, day, month, year in numeric and in strings - the user can choose what datatype to use.

Further in your example, if you type for 6.10.2011 instead of 06102011 the number without leading zero, i.e. 6102011 you will get bad data:
Code:
 Enter date (ddmmyyy) = 
6102011
 day =  61
 month =  2
 year =  11
My example works with this input too:
Code:
$ ddmmyyyy 
 Enter date (ddmmyyyy) = 
6102011
 date_str  = '06102011'
 day_str   = '06'
 month_str = '10'
 year_str  = '2011'
 date_num  =  6102011
 day_num   =  6
 month_num =  10
 year_num  =  2011
 
mikrom:

well, for the sake of some friendly back-and-forth arguing...

Sure, it is always possible to give a program what is not expecting and make it misinterpret the input...nothing new there. The spec said to provide input in DDMMYYY format, period.

Having said that, if you are going to depart from the requested format, I think you are not being consistent...you are allowing to specify day with a single digit when it is less than 10; but, you are not allowing the same for the month.

But that is besides the point...my main point in the previous post was that you, somehow, assumed that the input is a string in the first place...which it is not the case. If you see cooljosh's original code, he meant to read the input into numbers from the very beginning...he never though of ddmmyyy as a single string...

...I don't know for how long you've been around and how old fortran code you have been exposed to, but this 'ddmmyyy' kind of input it's been around from the beginning...it is called 'formatted' input, as opposed to 'list-directed'. 'Formatted' input in fortran has been around forever and it was very popular for the longest time...manuals for programs would help the user put together input files by showing column numbers along the top of an input template, like this:

1111111111222222222233333333334
1234567890123456789012345678901234567890

And then provide a sample input properly aligned.

Anyway...

Cheers.





 
salgerman said:
you are allowing to specify day with a single digit when it is less than 10; but, you are not allowing the same for the month.
because for example for 6.9.2011, the inputs 06092011 and 6092011 are numerically the same, but 692011 isn't
salgerman said:
my main point in the previous post was that you, somehow, assumed that the input is a string in the first place...which it is not the case
Yes it's character input from the keyboard containing only digits. If you assumed that it's number, then why your recipe cannot accept the same numbers 06092011 and 6092011 ?
 
Because the format is supposed to be respected in formatted input...that's why formatted input finally fell out of fashion, because people would get tricky with the input or even a small offset would produce different numbers.

Along with formatted input, there is (or was) a flag the used to be setup to indicate whether empty spaces in the formatted input were to be interpreted as zeroes or just blanks...more often than not, it was set to take in zeroes where there was nothing....this allowed to input 3000 with a single 3 if, for example, the field was specified as I5:
# 1 <-column number
#234567890
3000
3

The last two lines above would result into the same number with formatted input and setting the flag to take zero where blanks.

Needless to say, this column-oriented input was dangerous.
 
Btw, I don't understand the purpose of using numerical dates in format of ddmmyyyy.
However, representing the dates as numbers of format yyyymmdd is very often used, because we can compare the dates, using the usual relational operators "<" and ">" for numbers, without the need to use date arithmetics.
 
I am with you on that one...apparently, a few years ago, the yyyymmdd date format was declared the international format so that there is no confusion since in the US traditionally date is specified as mmddyyy but in other countries is done like ddmmyyyy...whether they were thinking straight and chose something that makes sense or they were fighting and not letting the other get away with already established format spec...the result is that yyyymmdd is becoming the format of choice...although I still feel I am the only one using...Nobody else seems to be picking it up!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top