Hi all,

I am total new to php and even coding, i am a netadmin.
Now my webmaster has quited, and we are in search of new webmaster, till the time been i am in charge of the site.

I need to add a time difference been the market open and market close (related to stock exchange)

so pls can u help me in coding this.
My market opens at 9:15 am and closes at 12:30.
I need to show the time difference between the current time to market open,
and also time left to market close after the market is open. i have done something is u can check if its correct or wrong.

<?php
function mktcls_diff($time1, $time2) {
        $time_diff      = strtotime($time2) - strtotime($time1);
        $hours          = floor($time_diff / 3600);
        $minutes        = floor(($time_diff % 3600) / 60);

    // Just returning the string...
    // can change this if you like so that
    // it returns an array of the hours/minutes, etc...
    return("$hours:$minutes");
}
function mktopn_diff($time1, $time3) {
        $time_diff      = strtotime($time3) - strtotime($time1);
        $hours          = floor($time_diff / 3600);
        $minutes        = floor(($time_diff % 3600) / 60);

    // Just returning the string...
    // can change this if you like so that
    // it returns an array of the hours/minutes, etc...
    return("$hours:$minutes");
}

// Test Call
$time1          = date ("h:i:s");
$time2          = "12:30:00";
$time3		= "09:15:00";
$diff           = mktcls_diff($time1, $time2);
$diff2          = mktopn_diff($time1, $time3);

//print date ("H:i");
//print $diff;
//print $diff2;

echo "<B>OPEN<BR></B>";

//Market Open Check
if ($time_diff <= $time1) { 
echo "Market Closed<br>";
	}
else {
echo "Market Open";
echo $diff2 ("hours left for Market to Open.");
	}
print $diff2+$hours;

//CLOSE
echo "<br><BR><B>CLOSE</B>";

//Market Close Check
if ($time_diff <= $time1) { 
echo "<br>Market Closed<br>";
	}
else {
echo "Market Open";
echo  $diff("hours left for Market to Close.");
	}
print $diff;
?>

this is my testing code that i am working on.

Thanks

    That is why I hate unix timestamps, hit one wrong key on my calculator and it all goes wrong. See my repost below.

      Maybe I'm not understanding this properly but I don't think your logic is correct.

      I see the problem as this:

      If it is between 9:30 and 12:30 then the market is open, so calc how long it will be before it closes. I think your function for that will work.
      BUT
      If it is closed then
      if it is after 12:30 then you have to wait until tomorrow before it opens, that would be how long till midnight plus 9.5 hours
      if it is before 9:30 then it is just how long till 9:30

      Now I don't see that your functions can cope with the 24 hour clock. Your mktopn function is going to return the wrong figures.
      If it is 15:30 then your function will return
      9:30 (34200) - 15:50 (55800) = 6 (21600) hours by your calculation till next it opens. Obviously wrong.

      The calculation should be
      24:00 (864000) - 15:30 (55800) + 9:30 (34200) = 18 (64800) hours
      Now that is correct, if it is 15:30 then it is 18 hours till 9:30 tomorrow.

        thanks for pointing out the error,

        as i mentioned i have no knowledge of coding, can u point it where can i add 24:00 (864000).

        thanks

          For someone who has no knowledge of coding you've done pretty well so far, floor and modulo and everything in there. It was only the logic that was foggy.

          OK, I would handle the whole thing like this

          
          $now = strtotime(date("h:i:s"));
          $open = strtotime(9:30);
          $close = strtotime(12:30);
          
          switch (TRUE) {
          case ($now<$open):
             $diff = $open-$now;
             $hours = floor($diff / 3600);
             $minutes = floor(($diff % 3600) / 60);
             $state = 'Market Closed<br />' . $hours . 'hours ' . $minutes . 'minutes till the market opens again';
             break;
          case ($now<$close):
             $diff = $close-$now;
             $hours = floor($diff / 3600);
             $minutes = floor(($diff % 3600) / 60);
             $state = 'Market Open<br />' . $hours . 'hours ' . $minutes . 'minutes till the market closes';
             break;
          default:
             $diff = 86400 - $now + $open;
             $hours = floor($diff / 3600);
             $minutes = floor(($diff % 3600) / 60);
             $state = 'Market Closed<br />' . $hours . 'hours ' . $minutes . 'minutes till the market opens again';
          }
          
          echo $state;
          

          Now you can wrap that up as a function, and you could refactor some things like the string generation of the message, but I've written it out longhand so you can see the logic more clearly. The main thing not to change is the logic in the case select (Switch in php). It tumbles down through the test and that must not be changes
          is it before 9:30 , no then
          is it before 12:30, it must also be after 9:30 or you would not have got this far
          no then it is after 12:30 so we need the long time till open.

            I think the switch statement almost has it except that if it's before closing time and before opening time two statements are valid. I think it is better to compare if like so
            if (($now < $close) && ($now > $open)) {
            $status="Market is open";
            $diff=$close - $now;
            $hours=floor($diff / 3600);
            if ($hours > 1){
            $minutes=($diff / 60) - ($hours * 60);
            $minutes=$minutes." minutes"; }
            else $minutes="";
            $timeleft="There is ".$hours."hours ".$minutes." left till market closes";
            }
            else {
            $status="Market is closed";
            $timeleft="";
            }

            echo $status;
            echo $timeleft;

              No, that is not neccessary. The switch just tumbles down through the tests, that is what the break; is for.

              If it is before 9:30 then you get true in the first case and then exit on the break, so if you get to the second case if must be after 9:30. Likewise with the default: you have proved that it is after 12:30 so no further test is required.

              In php, switch works somewhat differently than case selects in other languages, but only in the fact that you have to force an exit from the code with break;
              In eg VB, or Pascal, or even SQL, a case select limits processing only to the code in the case segment for which the condition is true.
              But in all languages you can rely on the fact that if a preceeding case was false then it is still false for every following case.

                Not to be too nosey but using

                $now = strtotime(date("h:i:s"));

                Will not give the proper results because that is a twelve hour clock and if you echoed now on a twelve hour time you would get some really strange results. This is some code that takes a little different approach and will I think kind of do what they want and could be tweaked. Right now if the time is during opening hours it shows how many left til close or if after hours how many hours til reopen.

                <?php 
                $now = strtotime(date('H:i'));
                //$now = strtotime('10:45');// Uncomment to test various open times
                $open = strtotime('9:15:00');
                $close = strtotime('12:30:00');
                /*echo $then."<br>";  Just to check your time variables with 
                echo $now."<br>";     uncomment to test them  
                echo $open."<br>"; echo $close."<br>";*/ if($now > $open && $now < $close){ echo "It is ".date('h:i',$now)." the Market is now open!<br>"; $still_open =($close - $now)/3600; $still_open = number_format($still_open,2); echo "It will close in $still_open hours."; } elseif($now < $open ||$now > $close){ echo "The Market is now closed!<br>"; $until_open =($close - $now)+75600; $until_open = number_format($until_open/3600,2) ; echo "It will reopen in $until_open hours"; } ?>

                  Well, you are right about the 12-hour clock for the hours - my only excuse is that I copy/pasted from Wrathy's code.

                  But I wish you would all stop trying to upsatge me on the control structure, especially with if/else's. If you would read the manual you would understand how switch works and why it is better than a load of ifs.

                  "It is important to understand how the switch statement is executed in order to avoid mistakes. The switch statement executes line by line (actually, statement by statement). In the beginning, no code is executed. Only when a case statement is found with a value that matches the value of the switch expression does PHP begin to execute the statements. PHP continues to execute the statements until the end of the switch block, or the first time it sees a break statement. If you don't write a break statement at the end of a case's statement list, PHP will go on executing the statements of the following case."

                  AND

                  "In a switch statement, the condition is evaluated only once and the result is compared to each case statement. In an elseif statement, the condition is evaluated again. If your condition is more complicated than a simple compare and/or is in a tight loop, a switch may be faster."

                  Now, obviously, in my use I am evaluating an expression for each case, so the speed advantage is diminished. Even so, yours will require the evaluation of at least 2 expressions for the IF and 3 or 4 for the ELSE - while mine is 1 for the first case and just 2 for the second and third cases.

                  The switch also is better because it is more logical, and more legible and far less likely to introduce a bug if it needs to be amended with new conditions/cases.

                  Houdini your time calculation is cool, but again it's logic is not obvious and any amendment is likely to introduce a bug unless it is thoroughly well documented.

                  [edit]No it's not, it does not work for times between midnight and opening hour. See what I mean about obtuse code. So your solution needs another elseif to account for that case (midnight to 9:30 AM). Even less satisfactory than the switch.[/edit]

                  Now I know everyone is going to say "What do you mean introduce a bug? Should be obvious to an experienced coder.". This thread is all about an inexperienced coder having to maintain and update someone elses code because the guy left. Clear, concise, self documenting code that can be easily maintained by anyone else is the mark of a good proffessional software engineer - everything else is just hacking, no matter how slick the algorithm may be.

                    Thanks Roger,

                    It worked! but it displays the Market Open a minute later; e.i. when is 9:16 it state market is open.

                    Never mind, i can reduce the open time to 9:14.
                    Just have to wait for market close.

                    Its just great.

                    Thanks everyone.

                      Glad it works.

                      The odd minute is probably because I pasted your date("h:i:s") with hours mins and seconds but did the open and close with just hours and mins. When you do the time diff calculation the odd seconds get rounded up by 1 minute. Just change it to date('H:i') (note the capital H for 24 hour clock). Without the seconds the calculations should be accurate.

                        jsut checked the market closing, is not calculating the reopening time difference, as i checked it after the market close, its giving the following status:
                        current time 01:20 PM
                        Market Closed
                        7hours 54minutes till the market opens again.

                        its not calculating the next day, its only giving difference between current time

                        $now  = strtotime(date("h:i:s"));

                        and the market open time

                        ($open = strtotime("9:15");

                        so its just giving difference between 09:15 pm

                          Order of precedence with the plus and minus signs, just needs bracketting. Sorry, I never actually do any arithmetic in php so I'm not up on how it works. Must be adding $open to $now and then subtracting that from midnight. Simple fix

                           $now = strtotime(date("h:i:s"));
                          $open = strtotime(9:30);
                          $close = strtotime(12:30);
                          
                          switch (TRUE) {
                          case ($now<$open):
                             $diff = $open-$now;
                             $hours = floor($diff / 3600);
                             $minutes = floor(($diff % 3600) / 60);
                             $state = 'Market Closed<br />' . $hours . 'hours ' . $minutes . 'minutes till the market opens again';
                             break;
                          case ($now<$close):
                             $diff = $close-$now;
                             $hours = floor($diff / 3600);
                             $minutes = floor(($diff % 3600) / 60);
                             $state = 'Market Open<br />' . $hours . 'hours ' . $minutes . 'minutes till the market closes';
                             break;
                          default:
                             $diff = (86400 - $now) + $open;
                             $hours = floor($diff / 3600);
                             $minutes = floor(($diff % 3600) / 60);
                             $state = 'Market Closed<br />' . $hours . 'hours ' . $minutes . 'minutes till the market opens again';
                          }
                          

                          Now we are forcing it to evaluate the midnight minus now before adding the opening time.

                            thanks for the fix;
                            but now i just remembered; that the market will also be closed on weekends.

                            Sorry roger, but i just skipped it since i was tring to concentrate on the market open and close timing. This will be real though for me, seem its very complex piece of code.

                            Thank you.

                              Well, it is pretty straight forward really, and easy enough to solve in a messy way. Doing it elegently and efficiently will need a lot of thought though. No time right now so bear with me.

                                Just a side note:
                                PHP follows the basic laws of mathematics in that with addition & subtraction( + - ), it follows in the order it is viewed from left to right. Same with multiplication and division( * / ). Now, if there is both multiplication and/or division with addition & subtraction in the equation, then it will multiply & divide first, and then add or subtract.

                                Just something to help you as you think your logic through. Usually it's always a good idea to define just what items will be evaluated first though....

                                  Well that is what I expected for the expression: left to right, first subtract the current time from midnight, then add the opening time.
                                  Not what was happening though, or so the man sez.
                                  Now, I believe in being very explicit in my coding and would usually have written it with the brackets to force the issue, but it was late at night when I wrote that and I just got sloppy - no excuse, just sloppy.
                                  Still it reinforces my normal coding style - which I arrived at years ago because of just this sort of thing.

                                    I thk that this just about does it, though there may be some error in my arithmetic.
                                    To check this script you can substitue test times for the $now var and day of week rather than waiting for the earth to spin around.

                                    $now = strtotime(date("H:i"));
                                    $open = strtotime(9:30);
                                    
                                    // set up midnight and closing time according to the day of the week
                                    switch (date(w)) {
                                       case 1:
                                       case 2:
                                       case 3:
                                       case 4:
                                       // if it is mon, tues, wed, or thurs, closing time and midnight are normal
                                          $close = strtotime(12:30);
                                          $midnight = 86400;
                                          break;
                                       // friday, add 48 hours to midnight and closing time is normal
                                       case 5:
                                          $close = strtotime(12:30);
                                          $midnight = 345600;
                                          break;
                                       // sat add 24 hours to midnight and closing time is zero
                                       case 6:
                                          $close = 0;
                                          $midnight = 172600;
                                          break;
                                       // sunday midnight is normal and closing time is zero
                                       case 0:
                                          $close = 0;
                                          $midnight = 86400;
                                    }
                                    
                                    switch (TRUE) {
                                       // if it is after the market closed calculate time till next open
                                       // setting close to zero for sat and sun covers the weekend
                                       // adding extra days to midnight covers friday and saturday
                                       case ($now > $close):
                                          $diff = ($midnight - $now) + $open;
                                          $hours = floor($diff / 3600);
                                          $minutes = floor(($diff % 3600) / 60);
                                          $state = 'Market Closed<br />' . $hours . 'hours ' . $minutes . 'minutes till the market opens again';
                                          break;
                                       // if it is before opening time then calculate time till open
                                       case ($now < $open):
                                          $diff = $open-$now;
                                          $hours = floor($diff / 3600);
                                          $minutes = floor(($diff % 3600) / 60);
                                          $state = 'Market Closed<br />' . $hours . 'hours ' . $minutes . 'minutes till the market opens again';
                                          break;
                                       // otherwise the market is open
                                       default:
                                          $diff = $close-$now;
                                          $hours = floor($diff / 3600);
                                          $minutes = floor(($diff % 3600) / 60);
                                          $state = 'Market Open<br />' . $hours . 'hours ' . $minutes . 'minutes till the market closes';
                                    } 
                                    

                                      Thanx again Roger, seems its working.

                                      thanx alot..

                                      let me wait till this week end to check if its woking.

                                        Found a boo boo:

                                        case 1:
                                        case 2:
                                        case 3:
                                        case 4:
                                        // Whatever code

                                        case 5:
                                        // friday

                                        case 5:
                                        // saturday

                                        How can friday and saturday have the same day number? Saturday should be day 6 (and thus case 6) not case 5....

                                        I'm not sure about your math, but PHP math works fine for me:
                                        http://phpbuilder.bpatterson.net/userhelp/RogerRamjet/math.php