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'));
Related
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.
Given an arbitrary timestamp (e.g. 2019-02-26 10:30:00) I would like to find the next occurrence of an arbitrary time.
For example, the next occurrence of 12:00:00 will be 2019-02-26 12:00:00 but the next occurrence of 09:00:00 will be the next day at 2019-02-27 09:00:00. The results could be Carbon or Datetime objects. The test time will just be a string as shown.
Is there a way to calculate this in native PHP or PHP Carbon without conditionally boxing in time periods. An obvious way would be to see if the time being tested is past the check time for today, and if it is, taking the result as the check time plus 24 hours (the next day). That feels to me like too much chopping and joining of dates and times, so is there a way to calculate it by considering time to be a simple linear line?
All times will be in a single timezone, with DST. Note: the arbitrary datetimes and check times will stay clear of DST changeovers i.e. 01:00 to 02:00 so hopefully they will not be an issue to take into account.
Short answer is no for PHP (partial answer, I'm no specialist of Carbon but from quick look it's also no, but you can create a macro from following code).
However, with a ternary condition the one-liner is simple enough IMHO (replace the second DateTime($str) with DateTime() if you want to compare with current date and time, and change the >= by > if you want next day when time compared is exactly the same):
$str = '2019-02-26 10:30:00';
$date1 = ( ($a = (new DateTime($str))->setTime(12,00)) >= (new DateTime($str)) ) ? $a : $a->modify('+1 day');
$date2 = ( ($a = (new DateTime($str))->setTime(9,00)) >= (new DateTime($str)) ) ? $a : $a->modify('+1 day');
echo $date1->format('Y-m-d H:i:s'); //2019-02-26 12:00:00
echo $date2->format('Y-m-d H:i:s'); //2019-02-27 09:00:00
quick note: what you gave us is not a timestamp, but a formatted date.
Here is what I am using now through Carbon, which appears to give me the correct results:
$dateTime = Carbon::parse('2019-03-30 17:34:50', 'Europe/London');
$testTime = '16:00:00';
list ($hour, $minute, $second) = explode(':', $testTime);
$nextTimeOccurrence = $dateTime
->copy() // Carbon 1 only
->hour($hour)->minute($minute)->second($second);
if ($dateTime->gt($nextTimeOccurrence)) {
$nextTimeOccurrence = $nextTimeOccurrence->addDay();
}
// $nextTimeOccurrence is the next occurrence of $testTime after $dateTime
The splitting of the time seems clumsy, but might be the best way? The approach is:
Create a timestamp with the test time on the same day as the timestamp I'm checking. This will be the timestamp I am looking for.
If the timestamp I'm checking is after the timestamp created in the previous step, then add a day to it.
I've tested this around DST, and happily Carbon/Datetime keeps the same time when adding a day over a DST period, where a day there would be 25 hours or 23 hours, depending on which way it goes.
I still think there is a more "linear time" way to do this, but this seems simple and robust. Thanks go to #michael-stokoe here at the office for my lead on this.
In My SQL Database I have a Timestamp Column with values like this one representing the Date of the last edit:
2015-01-17 08:55:34.000000
I want to compare the Date with the current date and when is the same day I want to echo Today and otherwise I want to Display the Date of the last edit:
$timefromdb = '2015-01-17 08:55:34.000000'
$edit = strtotime($timefromdb);
if($edit > $_SERVER['REQUEST_TIME']){echo "Today";}
else{
echo strftime("on %A, the %d %B %Y", $edit);
}
echo " at ".date('h:i',$edit)
It always Displays 01/01/1970. There must be a Problem with strtotime. I did a bit of research and it seems like my Timestamp Format isn't a valid one: http://php.net/manual/en/datetime.formats.php
Around the web are a lot of Questions about converting Timestamps but I just can't find the right one: I also got a bit confused by all the functions to convert date stuff.
So can someone Tell me how to get a valid Timestamp for using it in strftime and to compare it to the REQUEST_TIME.
Thanks in Advance!
UPDATE: As Always: The Problem sits in Front of the PC. I declared the Variable but never assgined the Timestamp to it :)
Chop off the .000000 from the date as it makes the date a format strtotime() cannot work with. There's several ways to do this. A simple substr is one of them.
$timefromdb = substr('2015-01-17 08:55:34.000000', 0, -7);
I'm not exactly understood you, but
try
1. compare gettype( $edit ) and gettype($_SERVER['REQUEST_TIME'])
2. not sure what $timefromdb will be more then $_SERVER['REQUEST_TIME'], because IMHO when user edited data, time of it action will me less then current time.
What I'm attempting to do is create a simple "Quote of the Day" script. What this needs to do is be able to read from a simple .txt file, grab each entry per line and output the contents of that line, once per day. For example, if a .txt file had the following text:
This is the quote of the day
This is another quote of the day
This is the last quote of the day
Then, the script would grab the first block of text, This is the quote of the day and output it on the site. It would then cycle through, line by line, based on each incremental day until the end (and then cycle back to the beginning). Hopefully this would just allow people to cut/paste new info in as it would rely on line numbers, not the content itself.
If anyone even knows of a .XML implementation of this - it would be a big help - trying to figure out the simplest way of going about this. Thanks!
Assuming you had a file with 365 lines (one line per the current day)...
$lines = file("quotes.txt");
$day = date("z");
echo $lines[$day];
You can save the current index line and day on the first line of the file, like this:
01;09-11-2011
This is the quote of the day
This is another quote of the day
This is the last quote of the day
To retrieve the quote you would check if the date is today, if it is you get the nth line otherwise you add 1 to the number, update the date and then get the quote.
This should work with any number of lines in your textfile (untested):
// get lines
$lines = file('lines.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES );
// snap to midnight
$day = mktime(0,0,0, date("n"), date("j"), date("Y")) / (3600*24);
// modulo fun
echo $lines[ $day % count($lines) ];
It's very simple.
1.) You create a text file with 7 lines, each line represents a quote.
2.) PHP: You have to load the file into an array and get the numeric representation of the current day of the week:
$quotes = file('your_file.txt');
$the_quote = $quotes[ date('w') ];
echo $the_quote;
From php.net:
w
Numeric representation of the day of the week
0 (for Sunday) through 6 (for Saturday)
If you want to have a quote for each day in a year, just create a file with 366 lines and use date('z').
The most flexible way is definitely:
$day = date("z");
$file = file('quotes.txt');
$file_length = count($file);
$quote = $file[$day % file_length];
By using the modulus of the day and file length you have a recurring cycle every day from the first line to the last line of the file (and then start again).
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