time period in time period (PHP) - php

i try to find out if a Timeperiod is inside a timeperiod. I have my reference time period and my comparative time period.
Let me make an example:
Time period A (reference) goes from 1.1.2014 to 1.2.2014 (tt.mm.yyyy).
Time period B (comparative) goes from 1.4.2014 to 1.5.2014.
=> This would be totaly ok.
Time period C (reference) goes from 1.1.2014 to 1.3.2014
Time period D (comparative) goes from 1.2.2014 to 1.5.2014.
=> Not ok because D is in C.
I hope you get what i want. I tried to make serval < = > if actions but this starts to get to huge and slow. Maybe there is a faster ways to do so.
Also, is MySQL able to do such things?

you can try this with php timestamp
$reference_start_date = "1.1.2014";
$reference_end_date = "1.2.2014";
$comparative_start_date = "1.4.2014";
$comparative_end_date = "1.5.2014 ";
$reference_start_time = strtotime(str_replace(".", "-", $reference_start_date);
$reference_end_time = strtotime(str_replace(".", "-", $reference_end_date);
$comparative_start_time = strtotime(str_replace(".", "-", $comparative_start_date);
$comparative_end_time = strtotime(str_replace(".", "-", $comparative_end_date);
if($comparative_start_time>$reference_start_time && $comparative_start_time<$reference_end_time)
{
echo "Not OK";
}
else if($comparative_end_time>$reference_start_time && $comparative_end_time<$reference_end_time)
{
echo "Not OK";
}
else if($comparative_start_time<$reference_start_time && $comparative_end_time>$reference_end_time)
{
echo "Not OK";
}
else
{
echo "OK";
}

you can do like below:
Check Reference_start >= comparative_start && Reference_end < comparative_end, If this condition become true than your time will be overlapped.

If you have a reference period (having startDate and endDate) and you have a comparative period, then you can have this where clause in MySQL:
where ((reference.startDate > comparative.endDate) or reference.endDate < comparative.startDate)
which would be true if the two periods have no intersection.

Assuming you have your dates give in UTC it is really simple to compare two date ranges. There are 5 specific cases that could happen:
11111......
......22222
..11111.....
.....22222..
...11111....
...22222....
.....11111..
..22222.....
......11111
22222......
Only the first and the last one are the ones you are looking for. It's easy to construct an if query of it and negate it:
if (!($dateRange1End <= $dateRangeStart2 && $dateRange2End <= $dateRange1Start))
// NOT OKAY
else
// OKAY

Related

regex match cond1 OR match cond2 in single command

I need to check if entered date is between 2019-09-01 - 2019-12-31
I can do this as follows: $koodi is user input
$pattern1 = "/^2019-(09|11)-([0-2][0-9]|30)$/";
$pattern2 = "/^2019-(10|12)-([0-2][0-9]|3[0-1])$/";
if(preg_match($pattern1, $koodi) || preg_match($pattern2, $koodi)) {
echo "<code>$koodi</code> ok!<br>\n";
}
else {
echo ("<code>$koodi</code> NOT ok!<br>\n");
}
I was trying to make those two conditions into single regex statement, is that possible and if so how?
I tried:
$pattern = "/^2019-(09|11)-([0-2][0-9]|30)$ | ^2019-(10|12)-([0-2][0-9]|3[0-1])$/";
Did not work, neither the following where i tried to put parentheses around conditions:
$pattern = "/(^2019-(09|11)-([0-2][0-9]|30)$) | (^2019-(10|12)-([0-2][0-9]|3[0-1])$)/";
Please don't use a regex to do that, what if the dates change or what if the next developer has to come and work on this and figure out what your doing?
According to this article you can check if a date is between 2 dates by doing something like this.
<?php
$currentDate = date('Y-m-d');
$currentDate = date('Y-m-d', strtotime($currentDate));
$startDate = date('Y-m-d', strtotime("01/09/2019"));
$endDate = date('Y-m-d', strtotime("01/10/2019"));
if (($currentDate >= $startDate) && ($currentDate <= $endDate)){
echo "Current date is between two dates";
}else{
echo "Current date is not between two dates";
}
as for why your patterns didn't work its because you have a space around the pipe in the middle and you may possibly need to wrap the whole thing in brackets. You also have the $ half way through the regex which is matching the whole string, I would usually only have it at the end, like this: -
^(regex1|regex2)$
I haven't written the correct version in case your tempted to use it, (please use the date objects method)

Using time() inside a while loop

For a school assignment we need to write a PHP script that counts for 1 second.
The following code I wrote should do exactly that was my thought:
$startTijd = time();
$teller = 0;
while($startTijd == time()){
echo 'Iteratie: ' . $teller . '<br>';
$teller++;
}
However, every time I run this or any PHP script similar to it that uses the time() function inside a while loop I get a 502 bad request from the server when I try to visit the page.
Your code as it is would not work (would not count one second exactly), because time() has a granularity of one second, and you have no guarantees that you landed on your page exactly at the tick of a second. So you need to synchronize.
To be clear, imagine calling time() several times, and let's suppose time() outputs in HH:MM:SS instead of Unix timestamps for legibility's sake:
Code
print time()
print time()
print time()
...
Output:
01:15:17
01:15:17
01:15:17
...
01:15:18
01:15:18
01:15:18
...
Your program probably currently does not work correctly because even in the little time that the loop runs, it generates a fantastic quantity of output (as can be seen above, time() remains "valid" for up to a whole second, and in that time a loop can execute lots of times). If there's some sort of resource limit on the PHP process, it's possible that this drives the process over its quota, resulting in the 502 error. You can check that by removing the echo from the loop, and just adding echo "Done." at the end.
You want to count between the instant in time in which time() transitions from 01:15:17 to 01:15:18, up to the instant when it again transitions to 01:15:19. Those instants will be separated by exactly one second.
What you would need to do is:
$startTijd = time()+1; // It is now maybe 01:15:17.93. We want to start
// counting at 01:15:18, so we need to wait for it.
while($startTijd !== time()) {
// Do nothing except maybe a very brief sleep to save CPU
usleep(5); // this is optional anyway.
}
// It is now 01:15:18.000003 and $startTijd is 01:15:18
$teller = 0;
// time() will remain equal to 01:15:18 for one second,
// while wall clock time increases from 01:15:18.000003 to 01:15:18.999999
while ($startTijd == time()) {
// Don't output anything here
$teller++;
}
// New transition detected.
// It is now e.g. 01:15:19.000137 and time() says 01:15:19.
echo 'Iteratie: ' . $teller . '<br>';
Alternately you can use microtime(true):
$teller = 0;
$endTijd = microtime(true) + 1.0;
while ($endTijd >= microtime(true)) {
// Don't output anything here
$teller++;
}
echo 'Iteratie: ' . $teller . '<br>';
Your code makes no sense... your while statment is only true if you computer is fast enough.
$startTijd = 100; # you set here the time represented by a number
while(100 == time() #101) { # here time is some milliseconds or seconds in the future
so after a second your while stops so that make not so much sense. Then use
while(true) {
and stop the while with a condition insight the while loop.

Run script every 2 hours, 6 times in X pattern, 6 times in Y pattern per 24 hours

I want to run a script every two hours, so I use this cron jon command:
0 */2 * * *
The script should use key X when running the first time, and on the following run it should use key Y, and then X again and so on.
My initial idea was to use the server time, and according to whether the hour is odd or even number, it will choose different key:
$h = date('G');
if ( $h & 1 ) {
$key = "X"; } // odd
else {
$key = "Y"; } // even
But since I run it every two hours in the first place, it is bound to use only one of these keys always, so it's not good.
What's a good way to achieve this?
You can write a file "flag.txt" to filesystem, and check if he exists. If it exists, use X and delete file, if it not exists, create file and use Y.
I think that this should work, but I have no tested it. But doing this with date is the easiest to do.
1 to 12 with date
$dDate = date("g");
Lets say that it fires on 0/2/4/6/8/10/12
$iResult = $dDate % 2;
If any of the given fire times is given $iResult will be 0 so in this case
if($iResult != 0) {
//Do X
} else {
//Do Y
}

preg_match for mysql date format

im trying to validate a date to see if it matchs the mysql format
this is the code
$match = "/^\d{4}-\d{2}-\d{2} [0-2][0-3]:[0-5][0-9]:[0-5][0-9]$/";
$s = $this->input->post("report_start"). " " . $this->input->post("report_start_time").":00";
$e = $this->input->post("report_end"). " " . $this->input->post("report_end_time").":59";
if($this->input->post("action") != "")
{
echo trim($s). " => " . preg_match($match, trim($s));
echo "<br>";
echo trim($e). " => " . preg_match($match, trim($e));
}
the date format goes into $s and $e are
$s = 2011-03-01 00:00:00
$e = 2011-03-01 23:59:59
and they both return false (0).
i tested the pattern on http://www.spaweditor.com/scripts/regex/index.php and it returns true (1)
http://pastebin.com/pFZSKYpj
however if i manual inter the date strings into preg_match like
preg_match($match, "2011-03-01 00:00:00")
it works.
i have no idea what im doing wrong
======================
now that i think about it, i only need to validate the houre:min part of the datetime string.
im manually adding the seconds and the date is forced by a datepicker and users cant edit it
You're making your work harder that it needs to be. In php there are many date handling functions that mean you don't have to treat dates like strings. So, rather than test that your input dates are in the correct format, just insist on the correct format:
$adate= date_create('January 6, 1983 1:30pm'); //date format that you don't want
$mysqldate= $adate->format("Y-m-d h:i:s");//date format that you do want
There are also functions to check that a date is a real date, like checkdate.
ok heres wat i did.
since im forcing the date format and the ending seconds of the time part
i just validated the hour:mini part using "/^2[0-3]|[01][0-9]:[0-5][0-9]$";
and if that returns true i put everything together end reconstructed the final datetime string
$match = "/^2[0-3]|[01][0-9]:[0-5][0-9]$/";
$s_d = $this->input->post("report_start");
$s_t = $this->input->post("report_start_time");
$e_d = $this->input->post("report_end");
$e_t = $this->input->post("report_end_time");
if($this->input->post("action") != "")
{
if(
( preg_match($match , trim($s_d." ".$s_t.":00")) )
&& ( preg_match($match , trim($e_d." ".$e_t.":59")) )
)
{
$r = $this->model_report->client_hours_logged(array($s,$e));
$data['report'] = $r;
var_dump($r);
//$this->load->view("report/client_hours_per_client",$data);
}
}
Watch out:
[0-2][0-3] is not a good regex for hour values - it will match 01, 12, 23 and others, but it will fail 04 through 09 and 14 through 19.
Better use (2[0-3]|[01][0-9]) instead.
I use this to validate a 'Y-m-d H:i:s' format date string:
match = '/^[12][0-9]{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[01]) ([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]$/';
You could use strtotime and date to parse and format the date properly.
Why not just simply force the date into the format you want:
$e = '2011-03-01 00:00:00';
$mysqlFormat = date('Y-m-d H:i:s', strtotime($e));
Also, there is a bit of an error in your regex [0-2][0-3]:[0-5][0-9]:[0-5][0-9] will only match the hours of 00,01,02,03,10,11,12,13,20,21,22,23 so it will never match 4am, or 3pm among others. That aside I looked over your RegEx and I don't see any problems with it matching the test cases you've offered. I would check to make sure there is not extra whitespace on either side of date string with trim().
I concur with Tim : MySQL behaves in quirks mode and always tries to go easy on DATE and DATE_TIME column types. You can omit certain parts of your input and it still will try to compensate and achieve that goal successfully to some degree... That's why, most numbers your Reg-ex considers as invalid, MySQL will accept as valid.

compare dates not working

Hallo,
I am comparing 2 dates. It is clear that $db_minus7 is greater so the value of $can_invoiced should be 'maybe' but it is 'Yes'. When i execute.
<?php
$db_minus7 = '2010-07-05 09:45:29.420';
$completion_date = '30.07.2009';
if(date("m-d-Y",strtotime($db_minus7)) > date("m-d-Y",strtotime($completion_date))) {
$can_invoiced = 'maybe';
} else {
$can_invoiced = 'Yes';
}
echo $can_invoiced;
?>
please help
why don't you just compare the times instad of formating them again like this:
if(strtotime($db_minus7) > strtotime($completion_date)) {
$can_invoiced = 'maybe';
} else {
$can_invoiced = 'Yes';
}
EDIT:
if you want to use date(), use "Ymd" or "Y-m-d" as pattern because it's string-comparision, and this is the logical order to work with (arrange the patterns from "big"(years) to small (days... or maybe seconds, if you need));
Dont' use "m-d-Y" but "Y-m-d".
01-01-2010 is lower than 02-01-2009 (bad !) but 2010-01-01 is not lower than 2009-01-02 (good !).
Compare the dates as datestamps, not as strings:
if(strtotime($db_minus7) > strtotime($completion_date)) {
If you have to compare the dates as strings, then use Y-m-d rather than m-d-y
Never Compare Dates as strings, even if it works for your Testcases it will fall on your feets sooner or later ... or maybe... richard stallman will hunt you down, i don't know ...
if(strtotime($db_minus7) > strtotime($completion_date)) {
$can_invoiced = 'maybe';
} else {
$can_invoiced = 'Yes';
}

Categories