Qbasicnews.com

QbasicNews.Com => Challenges => Topic started by: Moneo on July 16, 2003, 04:08:18 PM



Title: Challenge: Compute number of days between two dates.
Post by: Moneo on July 16, 2003, 04:08:18 PM
Given:
1) Two date strings, D1$ and D2$.
2) They should be in the format: YYYYMMDD.
3) You must check them for validity, e.g., 20030229 and 20030931 and 1999019 are all invalid.
4) Once they're valid, figure out how to compute the number of days (positive or negative) of D2$ minus D1$.
*****


Title: Challenge: Compute number of days between two dates.
Post by: Ninkazu on July 16, 2003, 04:09:47 PM
Come on, let's do something more fun than parsing. Blehh.


Title: Challenge: Compute number of days between two dates.
Post by: Moneo on July 16, 2003, 04:13:33 PM
NINKAZU,
Why do you consider this as a parsing problem? Only a small part the date validation could be considered parsing. The rest is computational.
*****


Title: Challenge: Compute number of days between two dates.
Post by: Ninkazu on July 16, 2003, 04:14:13 PM
Quote from: "Moneo"
NINKASU

 :evil:


Title: Challenge: Compute number of days between two dates.
Post by: Moneo on July 16, 2003, 04:16:13 PM
Sorry 'bout that --- I fixed it.
*****


Title: My Code
Post by: Meg on July 16, 2003, 08:40:42 PM
I am becoming way too addicted to these programming challenges.  I have so much other stuff I should be doing.....  :-?

Anyways, here's my entry for the Days-Between-Two-Dates challenge.  I hope it works alright!

*peace*

Meg.

Code:
DECLARE FUNCTION TotDays& (Start$, End$)
DECLARE FUNCTION EnterDate$ (Prompt$)
DECLARE FUNCTION DInM% (Month%, Year%)

     '**********************************************************************
     ' Days between two dates calculator.  Written by Meg Berry, July 2003.
     '**********************************************************************

CLS
D1$ = EnterDate$("First Date")
D2$ = EnterDate$("Second Date")

PRINT : PRINT "There are ";
IF D1$ > D2$ THEN
     PRINT -TotDays&(D2$, D1$);
ELSEIF D2$ > D1$ THEN
     PRINT TotDays&(D1$, D2$);
ELSE
     PRINT 0;
END IF
PRINT "days between those dates."

SYSTEM

FUNCTION DInM% (m%, y%)

     '*************************** OBJECTIVE ********************************
     'This function determines the number of days in a given month and year.
     '**********************************************************************

     '************************* ARGUMENT LIST ******************************
     'm%            month to check
     'y%            year to check
     '**********************************************************************

     '*** DETERMINE USUAL DAYS IN THE MONTH ***
     DInM% = 31 + (m% MOD 2) * (m% > 7) + (m% MOD 2 XOR 1) * (m% < 8)
   
     '*** IF FEB. THEN ADJUST DAYS DEPENDING ON LEAP YEAR ***
     IF m% = 2 THEN DInM% = 28 - ((y% MOD 4 = 0) + (y% MOD 100 = 0) * NOT (y% MOD 400 = 0))
   
END FUNCTION

FUNCTION EnterDate$ (Prompt$)

     '*************************** OBJECTIVE ********************************
     'This function returns a valid date string
     '**********************************************************************
   
     '************************* ARGUMENT LIST ******************************
     'Prompt$       Message passed to be displayed before the INPUT command
     '**********************************************************************

     '************************* VARIABLE LIST ******************************
     'EM$           Standard error message
     'd$            Temporary storage of date
     'check$        String used to check for non-numeric characters
     'y%            year, extracted from d$
     'm%            month, extracted from d$
     'd%            day, extracted from d$
     '**********************************************************************

     Em$ = "  Please enter a date between 00010101 and 99991231."
   
     DO
          PRINT
          PRINT Prompt$
          LINE INPUT "Enter Date (yyyymmdd): ", d$
          FOR Temp% = 1 TO 1
               IF LEN(d$) <> 8 THEN PRINT "Invalid Length." + Em$: EXIT FOR
               check$ = RIGHT$(STR$(INT(VAL(d$))), LEN(STR$(INT(VAL(d$)))) - 1)
               check$ = LEFT$("00000000", LEN(d$) - LEN(check$)) + check$
               IF check$ <> d$ THEN PRINT "Invalid Character." + Em$: EXIT FOR
               y% = VAL(LEFT$(d$, 4))
               m% = VAL(MID$(d$, 5, 2))
               d% = VAL(RIGHT$(d$, 2))
               IF y% < 1 THEN PRINT "Invalid Year." + Em$: EXIT FOR
               IF m% < 1 OR m% > 12 THEN PRINT "Invalid Month." + Em$: EXIT FOR
               IF d% < 1 OR d% > DInM%(m%, y%) THEN PRINT "Invalid Day." + Em$: EXIT FOR
               EXIT DO
          NEXT Temp%
     LOOP
   
     EnterDate$ = d$

END FUNCTION

FUNCTION TotDays& (S$, E$)
     '*************************** OBJECTIVE ********************************
     'This function returns the number of days between a start and end date.
     '**********************************************************************

     '************************* ARGUMENT LIST ******************************
     'S$            starting date
     'E$            ending date
     '**********************************************************************

     '************************* VARIABLE LIST ******************************
     'Sy% Sm% Sd%   starting year, month, and day
     'Ey% Em% Ed%   ending year, month, and day
     'Count&        day counter
     '**********************************************************************
   
     Sy% = VAL(LEFT$(S$, 4))
     Ey% = VAL(LEFT$(E$, 4))
     Sm% = VAL(MID$(S$, 5, 2))
     Em% = VAL(MID$(E$, 5, 2))
     Sd% = VAL(RIGHT$(S$, 2))
     Ed% = VAL(RIGHT$(E$, 2))

     IF Sy% = Ey% AND Sm% = Em% THEN
          Count& = Ed% - Sd%
     ELSE
          Count& = DInM%(Sm%, Sy%) - Sd% + Ed%
          DO UNTIL ((Sy% = Ey%) AND (Sm% = Em% - 1)) OR ((Sy% = Ey% - 1) AND (Sm% = 12) AND (Em% = 1))
               Sm% = Sm% + 1
               IF Sm% = 13 THEN Sm% = 1: Sy% = Sy% + 1
               Count& = Count& + DInM%(Sm%, Sy%)
          LOOP
     END IF

     TotDays& = Count&
END FUNCTION


Title: quick question
Post by: Meg on July 16, 2003, 08:53:19 PM
is there a way to make posts so that they don't wrap in the post box?  I thought I've seen posts that had horizontal scroll bars?

I hate when the forum word-wraps my code :p

*peace*

Meg.


Title: Challenge: Compute number of days between two dates.
Post by: oracle on July 16, 2003, 09:00:03 PM
Whenever I post a long line of code in [code] tags, it doesn't bother line-wrapping it. That's why you see scroll bars. But it doesn't really matter does it? All people to is copy and paste the code into notepad and it's correctly formatted.


Title: Re: My Code
Post by: Moneo on July 16, 2003, 09:09:47 PM
Quote from: "Meg"
...Anyways, here's my entry for the Days-Between-Two-Dates challenge.  I hope it works alright!

Does that mean that you haven't checked it out yourself? :wink:

MEG: You are incredible! I checked your program out and it works exactly to specifications. Did you do this unbelievable program from scratch in less than 4-5 hours, or did you "lift" some logic from some of your other programs?

In any event, great job! :P
*****


Title: from scratch
Post by: Meg on July 17, 2003, 01:01:37 AM
I coded the thing from scratch.  It took about an hour and a half.  I had to look up how to determine a leap year, but the logic line for it (the two lines in the DInM% function) are original.

There actually were a couple logic errors in the original post (notice it's been edited two times hehehe).  I think they're worked out, now.

*peace*

Meg.


Title: p.s.
Post by: Meg on July 17, 2003, 01:07:54 AM
I considered adding a check for the 10-day drop (Oct. 4 to 15, in the year 1582) but this might have been going overboard ;)

*peace*

Meg.


Title: Re: p.s.
Post by: oracle on July 17, 2003, 09:48:20 PM
Quote from: "Meg"
I considered adding a check for the 10-day drop (Oct. 4 to 15, in the year 1582) but this might have been going overboard ;)

*peace*

Meg.


Ahem.... maybe. But if you could that proggie would be no. 1 in QBasic for that (do you want to be the authority on something? ;))


Title: Re: p.s.
Post by: na_th_an on July 17, 2003, 10:35:00 PM
Quote from: "Meg"
I considered adding a check for the 10-day drop (Oct. 4 to 15, in the year 1582) but this might have been going overboard ;)

*peace*

Meg.


Are you saying that days from Oct.5 to Oct 14, in 1582, didn't happen? :P


Title: yep
Post by: Meg on July 17, 2003, 10:58:37 PM
According to the Gregorian calendar, the day after October 4th, 1582 was October 15th, 1582 to compensate for the Year actually being slightly less than 365.25 days long (which is why now leap years DO occur on 1600, 2000, etc. but NOT on 1700, 1800, etc. They did before this, and it was throwing off the calendar little by little.)  So they skipped 10 days in this year to line everything back up.  Well, different countries adopting the Gregorian calendars shifted in different years, but the original Gregorian calendar had it in 1582.

 :lol:  

*peace*

Meg.

p.s. no, I don't know all this.  I looked it up.  8)


Title: Challenge: Compute number of days between two dates.
Post by: toonski84 on July 17, 2003, 11:05:23 PM
The way I always thought it was that the leap year is either skipped or extended every 128 years to adjust for the earth's funky rotation cycle.  but it's pretty cool that people were smart enough to adjust dates based on the earth's rotation as early as 1582.  for heretic-burning mummy drinkers they seem to have their head on straight :)

oh, and meg:  that code might be a little smaller if you converted the gregorian day to julian and just subtracted :)


Title: Challenge: Compute number of days between two dates.
Post by: Moneo on July 18, 2003, 12:11:51 AM
MEG,

All the implementatioms that I've seen do one of the following:

1) Ignore the year 1582 problem altogether, just like your code does.

2) Pick a pivot date like 1800 or newer, and figure cumulative days as starting on January 1st of that pivot date.

You are one heck of a programmer for doing that program in 1.5 hours. It would take me more than that just to analyse the problem.

However, I must comment on the one-liner for calculating the number of days in a month. Although it works, I think this piece of code it is excessively complex, almost Machiavellian.

By the way, a published six-line algorithm exists for converting a date to the number of days from year zero. It also is a bit complex.
*****


Title: single line of code
Post by: Meg on July 18, 2003, 12:27:18 AM
yeah it prolly could be calculated a lot easier.  what that line basically says is:

m = 31
if month is > 7 and odd, subtract one
if month is < 8 and even, subtract one

so it just uses weights and multiplies them by the boolean (m%>7) and (M%< 8 )

so it looks pretty complex, but it's pretty straightforward.

there prolly is a more efficient way to calculate it tho.  I was just coding really fast :)

*peace*

Meg.


Title: Challenge: Compute number of days between two dates.
Post by: Moneo on July 18, 2003, 12:33:50 AM
Again, Meg, you're something special. When I have to code something in  a hurry, I code it as straightforward as possible.  It really annoying to look at piece of code later and wondering what I was trying to do. Unless of course, I heavily commented it.
*****


Title: comments
Post by: Meg on July 18, 2003, 12:36:04 AM
I try to comment my code, but i get really lazy about it.... :)

p.s. thanks so much for the kind words :)  i've always respected the way you handle people on this forum.  you've a knack for challenging and criticizing people in a way that's not insulting ;)  And also, I like that you don't get all up in a huff if somebody criticizes you  Very professional :)

p.p.s. my brain doesn't seem to grasp the concept of "straightforward" from time to time...

*peace*

Meg.


Title: Challenge: Compute number of days between two dates.
Post by: Moneo on July 18, 2003, 01:32:02 PM
MEG, I certainly thank *you* for your kind words. Youˇre a gal after me own heart. Some day I'll say that I met you on this forum, and not only were you most charming, but one of the best programmers that I ever met.
*****


Title: ...
Post by: Meg on July 18, 2003, 06:44:29 PM
p.p.p.s.  I use altogether too many emoticons.


Title: Challenge: Compute number of days between two dates.
Post by: Blitz on July 18, 2003, 08:01:03 PM
Meg, a girl name ?


Title: Challenge: Compute number of days between two dates.
Post by: oracle on July 18, 2003, 08:19:01 PM
Yes (short for Megan), but is she a girl? We don't know. That would make 1 girl in these forums :P

Are you working on a project, Meg?


Title: Challenge: Compute number of days between two dates.
Post by: na_th_an on July 18, 2003, 09:57:31 PM
Two, in fact. We have Meg and Bannana.


Title: uh oh
Post by: Meg on July 18, 2003, 11:04:17 PM
Look out.  We're slowly taking over.

A project?  I'm always working on something.  My long-term project is a BBS game that's been in the works for many months.  It's called "Dungeon" and you can check it out at my BBS (telnet to 68.48.142.201 port 23 with an ansi-supporting telnet client.  I like mTEL32.)

*peace*

Meg(an).

p.s. I thought na_th_an was a girl for the longest time because of the picture on his posts....


Title: Challenge: Compute number of days between two dates.
Post by: oracle on July 19, 2003, 01:21:23 AM
Na_th? Nah, he told me (all of us) he had a girlfriend ages ago (probably before you came). However, his rank (the old na_th_an rank) put me off, I didn't realise you could actually get the rank he had...


Title: Challenge: Compute number of days between two dates.
Post by: Nexinarus on July 19, 2003, 07:39:25 AM
lol looks like meg cleaned up this competition :). Im too stupid with dates im completely lost with them, we should count in BINARY! BINARY! j/k.

"In the time of 00101110001001001011010100101010010110001001010101 there once lived a young boy..." hehe.

sorry for this random post, im up late with no caffeen in me for at least 9 hours..  im starting to go crAzy..


Title: hm.
Post by: Meg on July 19, 2003, 05:47:27 PM
That's the stupidest idea since 0000000000000000000000000000000000000000000000000000000.

*peace*

Meg.


Title: Challenge: Compute number of days between two dates.
Post by: Moneo on July 19, 2003, 06:05:44 PM
Ok guys, we have 27 posts to this challenge but only 1 solution, that is, from Meg. Her elegant solution complies with all the specifications and works 100%.  

Doesn't anyone want to submit a solution of their own?
I'm going to establish a deadline of 21-Jul-2003 ar 23:59. GMT. If there are no better solutions by that time, Meg will be declared the winner.
Since Meg's solution works, a better solution would be considered as being simpler and having less code.
*****


Title: Challenge: Compute number of days between two dates.
Post by: Moneo on July 21, 2003, 09:08:44 PM
MEG IS THE WINNER OF THIS CHALLENGE.

CONGRATULATIONS, MEG, FOR AN EXCELLENT SOLUTION AND AN EXCEPTIONAL DATE HANDLING PROGRAM.
*****


Title: yeah
Post by: Meg on July 21, 2003, 09:32:25 PM
Whohoo!  ::does a little dance::

Anybody want a Kudo?

*peace*

Meg.


Title: Re: uh oh
Post by: Blitz on July 21, 2003, 11:13:24 PM
Quote from: "Meg"
p.s. I thought na_th_an was a girl for the longest time because of the picture on his posts....


Nathan is a girl trapped inside a skinny pale boys body.