I have a requirement where the user wants to be able to save "Date Modifier" strings to a database, and then use that with other dates in their application.
e.g. -
id name date_modifier
1 Add 1 Year +1 year
2 Last Day Of Month last day of this month
// simplified; using DateTime
echo $date->modify($date_modifier);
// today = 02/03/2022
// Add 1 Year = 02/03/2023
// Last day of month = 31/03/2023
Essentially I'm passing a date modifier string to a DateTime object to modify it.
This seems to be working OK but I am running into issues -
For example; some of the requirements are 5th of {whatever date is supplied}
this isn't working / I don't know what a date modifier looks like to achieve this.
$date = '02/03/2022';
$date->modify($fifth_of_month);
// outputs 05/03/2022
My next thought was to also store date_format so I wouldn't modify this date; but I would format it as $date->format('Y-m-05')
Is there a better approach to this as this looks like it could get very messy very quickly?
User can have endless weird requests for an option like this. For instance: "Next leap year last day of February". OK, I might be overdoing it, but these dates can be relative, absolute or a mixture. Predicting what user want is always difficult. You need to be flexible.
In cases like this I usually don't even try to find a cute solution, because there will come a time you have to ditch it and start again. My solution? The simple switch:
switch ($wantedModification) {
case 'Add 1 year' : $newDate = $date->modify('+1 year');
break;
case 'Last Day Of Month' : ....
break;
case '5th of next Month' : ....
break;
default : alert('Sorry, I forgot to implement this choice...');
break;
}
(code is just an example, and not meant to be correct)
This way you can easily incorporate any weird request that might come your way, and you get to keep your existing work. This is not the shortest solution, or the cleverest, but it is the most practical.
Related
I am trying to program a script that submits a form only on specific days of the week.
I have this code already.
date('w'); // gets day of week as number(0=sunday,1=monday...,6=sat)
// *note*: returns 0 through 6 but as string so to check if monday do this:
if(date('w') == 1){
echo "its monday baby";
}
But I do not know if this is efficient enough.
Please is there a better way around this
I think you have the best approach for this task.
In case you want the name of the day, you can use the same fuction but a different param:
$day_name = date('l');
//$day_name = Monday. If lowercase is required, use strtolower().
I have this date / time value (with timezone):
2019-10-22T17:00:00+02:00
Now I would like to check, which weekday this date is (for example: Monday)
and if this date has a difference of 1h between 16:00 o'clock and the date time.
How can I check the two factors as best practice ?
You may use DateTimeImmutable's constructor to parse the date string, DateTime#format to format it / retrieve the week day, and DateTime#diff to fetch the difference:
$date_string = '2019-10-22T17:00:00+02:00';
$date = new \DateTimeImmutable($date_string);
$date_at_16 = $date->setTime(16, 0);
echo $date->format('l'), PHP_EOL;
echo $date->diff($date_at_16)->h;
Demo: https://3v4l.org/R7e9n
Note that:
I've used DateTimeImmutable which is just like DateTime except it cannot be modified, so setTime doesn't also modify the initial date,
you should catch its constructor's potential thrown exception (if the format is invalid),
it should be better to use 'N' to retrieve the day of the week, as it's numerical and therefore more appropriate to store/compare (I've used 'l' for the purpose of this little demo, to get the full name),
if you need to know if it's 1 hour prior to or following 16 o'clock, you may check the DateInterval#invert flag (the date interval is what DateTime#diff returns).
Of a given datetime I need the very end of the previous month.
For example:
$date_given = '2019-07-14 16:33:05';
should become:
2019-06-30 23:23:59
I have some possible solutions to make it in several lines. But the requirement for my program/script is to have it in one line. So something like this:
$date_result = ...somefunction..(($date_given) -1 month) ...;
It really would be helpfull to have everything in that one line and not have prior lines with functions.
Thanks.
Here is many solution to this, but if has to be one line i would go with this
echo date_create($date_given.' last day of last month')->format('Y-m-d 23:59:59');
I actually don't know if there is a a way to dynamically get the last hour/minute/second of a day but I guess we can safely assume it always is "23:59:59" so you could do:
$lastDateOfMonth = date("Y-m-t 23:23:59", strtotime($date_given . '- 1 month'));
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
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