Hi guys I was wondering if anyone could help me with the following:
I have two dates entered in two different fields > startDate and endDate.
As they are entered I would like to show a warning if:
the second one is a date before the first one. So it is wrong.
and that between the first one and the second one there a minimum gap of at least 3 days during certain period of the year and 7 days during other periods of the year.
I was thinking to write a PHP function but how do I call it as soon as the second date is entered?
Many many thank for you help
Francesco
Convert your dates to Julian day with gregoriantojd.
/**
* Get the Julian day of a date. The Julian day is the number of days since
* January 1, 4713 BC.
*/
function datetojd($date)
{
return gregoriantojd(idate('m', $date),
idate('d', $date),
idate('Y', $date));
}
// you can use strtotime to parse a lot of date formats, assuming they are text
$startDate = strtotime('22nd Nov 2009');
$finishDate = strtotime('26nd Nov 2009');
$diff = datetojd($finishDate) - datetojd($startDate);
if ($diff < 0) {
// oops, $finishDate is before $startDate
}
else {
// check $diff is at least 3 or 7 depending on the dates
}
Do the check on the client side with Javascript.
Then perform the same checks server side which can present a message after the form has been submitted (for those few users running with Javascript disabled?).
I'm not sure if you can call it as soon as the second date is entered, unless you reload the page or have the function on another page which could get a tad complicated
The way i would check the dates is to use php's mktime function, which will give you the unix time. Then if the second one is less that the first, the second date is before and if the second one is less that the first + 3 * 24 *60 * 60 (seconds in 3 days) then it isn't 3 days apart
1° case:
SELECT [whatever you need from the table] WHERE endDate < startDate
2°case:
SELECT [whatever you need from the table] WHERE (endDate - startDate) >= IF([select that define in wich period of the year the data are],3, 7)
This ill do the trick, but probably your problem cant be solved sql-side.
Please, describe better what you need to do.
EDIT:
Ok, then as someone else suggested, first check htem by js (for convenience, not for safely: never rely only on js validation!)
Use strtotime for the comparison/operation.
EDIT2 (last;) :
Go with Alex's Answer
Related
Currently, I'm trying to parse out dates when messages were received into timestamps. I have the month and day but the year is not specified. The event always occurs at the most recent (human) reading of the time. It works great in most cases to do this:
$time = strtotime("Jan 2 8:38pm");
That returns a date for this year, which is correct. Unfortunately, I get problems when I try to do for example:
$time = strtotime("Dec 31 8:38pm");
That returns a date which hasn't happened yet, and wont happen for the whole rest of the year. Obviously, my message was not sent in the future. I need it to return December 31st of last year.
For weekdays, I had a solution by prepending 'last' before the weekday like so:
$time = strtotime("Last Saturday 8:38pm");
That always returned the time of the last Saturday. However, trying to do the same thing here doesn't work:
$time = strtotime("Last Dec 31 8:38pm");
This returns false. I know to decrement a date by 1 year, I can do this:
$time = strtotime("Dec 31 8:38pm -1 year");
And that works great for Dec 31. However, Jan 2 will now fail:
$time = strtotime("Jan 2 8:38pm -1 year");
One solution I thought of was to subtract off a year (86400 * 365) from the resulting value if it is past today's date. However, this result will fail if we passed over February of a leap year. In that case, we would end up with a time that was ahead by a day.
The best solution I came up with so far is this:
$time = strtotime($raw_time);
if ($time > time()) {
$time = strtotime($raw_time." -1 year");
}
It seems kind of wasteful to make two calls to strtotime which I know is probably not a very efficient function. Is this the most elegant solution?
Is anyone aware of an option in strtotime which forces the dates to be in the past instead of in the future?
Is there another way to parse these dates that I should consider?
Efficiency is important for this because I am going to be parsing a lot of dates with it, but I would also like simple and readable code so I can understand it later.
Your approach is fine, as there is no date format to get what you want. Another approach could be using the DateTime class:
$datetime = new DateTime($raw_time);
if ($datetime > new DateTime()) {
$datetime->modify('-1 year');
}
You could test which one of the two approaches is faster. My guess is that this is a micro-optimization that won't make a lot of difference.
I have a list of timestamps that represent a list of backed up files. But to reduce the amount of space needed I only want to keep the files that are from around mid day- I have started writing a function check but got stuck on how could i check if the timestamp is between 12 and 1 for that day? I have a list of timestamps for many days.
function check_date($timestamp='')
{
if (($timestamp < strtotime("-1 week")) && (time is between 12 and 1 )){
}
else
remove
}
I wrote an answer to this previously, I will try find a link in a minute when im free but essentially get the timestamp for 12 and the timestamp for 1 then
if(timestamp12 < curTimestamp && curTimestamp < timeStamp1)
Then you know that the curTimeStamp is between 12 and 1.
Previous answer https://stackoverflow.com/a/11578345/1475461
The other question was for a javascript implentation but timestamp comparison works the same whether you are using PHP, javascript etc. since they are miliseconds/seconds since a set point in time (1st January 1970), so it is just a comparison of integers.
Okay, let me think...ah, here it is. Good old 'localtime' function.
http://www.php.net/manual/de/function.localtime.php
Run your timestamp through this function, then you can check the result.
$TimeInfo = localtime(timestamp, true);
if (($timestamp < strtotime("-1 week")) && $TimeInfo["tm_hour"] == 12) {
}
else remove
With this code, all files, which have arrived at 12:00, up to 12:59 (1 is excluded in this example) are preserved, the others get removed.
I'm trying to get the number of the month of the year by the number of a week of the year and the year.
So for example week 1 is in january and returns 1, week 6 is in february so I want 2.
I tried to go with date_parse_from_format('W/Y') but had no success (it's giving me errors).
Is there any way to go with date_parse_from_format() or is there another way?
print date("m",strtotime("2011-W6-1"));
(noting that in 2011, January has six weeks so week 6 (by some definitions) is in month 1).
Just wanted to add a note for the first answer, the week number should be 01-09 for Weeks 1 through 9 (it will always give month 1 if you don't add the leading zero)
date("m",strtotime("2011-W06-1"));
Using PHP DateTime objects (which is the preferred way of dealing with dates see links below for more info) you can accomplish it this way:
$dateTime = new \DateTime();
$dateTime->setISODate($year,$week);
$month = $dateTime->format('n');
Note that the following will not work as week "W" is not a supported format:
$month = \DateTime::createFromFormat("W/Y ", "1/2015")->format('n');
The format used by this method is the same supported by the function you where trying to use date_parse_from_format, hence the errors.
Why PHP DateTime Rocks
DateTime class vs. native PHP date-functions
strtotime notes
PHP/Architect's Guide to Date and Time Programming (Chapter 2)
Something like this will do, this is also tested and works:
function getMonthByNumber($number,$year)
{
return date("F",strtotime('+ '.$number.' weeks', mktime(0,0,0,1,1,$year,-1)));
}
echo getMonthByNumber(27,2011);
Hope this helps
I need to compare two dates to show an edit link if it is within 5 mins after the post was made, in PHP. If more than 5 minutes have passed, don't show anything.
$answer_post_date = get_the_time("Y-m-d");
$current_date = date("Y-m-d");
$formated_current_date = strtotime($answer_post_date);
$formated_answer_post_date = strtotime($current_date);
At this point I have two values:
1274414400 ($formated_current_date)
1276056000 ($formated_answer_post_date)
I am not sure what to do next to check if the current date/time is > 5 mins from the answer post date.
Any suggestions would be great.
All I really need the answer to be is a Boolean (yes/no) and if yes, display the minuets left to show the link to edit.
You're only handling dates, how are you supposed to know if the difference is 5 minutes?
Anyway, I'd say the majority of the PHP code that uses the default PHP functions is at least somewhat broken. The problem is you, despite a unix timestamp storing the correct point in time something happens, it does not store timezone information. See here.
So, forget using only date and strtotime. Use the datetime extension.
Store in the database the Unix timestamp and the timezone (by timezone I mean e.g. Europe/Lisbon). Then:
$tz = new DateTimeZone($timezone);
$answer_post_date = new DateTime("$timestamp");
$answer_post_date->setTimeZone($tz);
$current_date = new DateTime("now", $tz);
$diff = $current_date->diff($answer_post_date);
if ($diff->format("a") > 0 ||
$diff->format("h") > 0 ||
$diff->format("m") >= 5) {
//more than 5 minutes have passed
}
Of course, for comparing dates, you can always compare the timestamps.
My understanding of what you need to do:
$delta = ($formated_current_date - $formated_answer_post_date) / 60; // in minutes
if ($delta < 5) {
// show $delta
}
EDIT: Like others pointed out, this alone will not fix all of the issues at hand. As I see it, the smallest change to your current code would be to use a date format with higher granularity - such as "Y-m-d H:i:s". This being enough, like others pointed out, is contingent on the post's date being in the same timezone as your system.
I don't see the need to do a round-trip to a string format and back, regardless of how efficient or reliable it is.
date() will default to calling time() which you can call directly and get the current time in seconds as a Unix epoch timestamp (which is what you're trying to end up with in $formated_answer_post_date). You need to look in the WordPress docs to find the equivalent based on the post's value.
Then you can do a simple comparison of seconds. 5 minutes is 300 seconds.
You will still need to check that the code can assume the timezones of both values will be the same.
I'm trying to make a PHP script to find the next occurence of a date (say 5-1). However, if I put that into strtotime() on 5-2 it comes up with the date from this year. I simply want to make it always return the next date possible. How can I make this work? I'm using codeigniter if that helps.
EDIT: Here's some code I came up with, if some humble soul runs across the same problem:
if (strtotime($date) < strtotime("now")) {
$realseconds = strtotime($date) + 31556926; //add one year in seconds
} else {
$realseconds = strtotime($date);
}
You could check whether the date returned is earlier than the current time, and, if it is, add one year to it.
You could also pass some date in the next year as the second parameter to strtotime.
What is 5-1 or 5-2?!
Try doing this instead:
strtotime('next October');
Assuming 5-2 means february fifth, you could do
strtotime("february 5 +1 year")
Code:
$x=strtotime($inputString);
$YEAR=60*60*24*30*12;
while($x<$time()) $x+=$YEAR;
Basically, it adds one year if the date returned by strtotime is in the past... because i used while() it will never return a date in tha past even if it was explicitly stated like that