How To Get Next Wednesday With PHP? - php

I have this situation :
17 January 2017 is Tuesday.
I'm expecting my code will generate 25 January 2017 as NEXT Wednesday. Not 18 January 2017.
19 January 2017 is Thursday.
I'm expecting my code will generate 25 January 2017 as NEXT Wednesday too.
but this code :
$payment_date = '17 January 2017';
echo $payment_date . '<br>';
$payment_date = date('d M Y', strtotime('next Wednesday', strtotime($payment_date)));
echo $payment_date;
gives me 18 January 2017 as next Wednesday. how to get 25 January 2017 as next Wednesday when my code runs between 15 - 21 January 2017?
thank you

$payment_date = date('d M Y', strtotime('next wednesday next week', strtotime($payment_date)));

Try using +1 week Wednesday instead of Next Wednesday:
$payment_date = date('d M Y', strtotime('+1 week Wednesday', strtotime($payment_date)));

Related

Change UTC0 to UTC +1/+2

I got a timestamp from my SQL-database: $DBdata = '2019-10-10 12:25:59', this date is UTC+0. Well i live in Denmark where we have the following UTC.
Central EU time winter (UTC+1)
Central EU summertime (UTC+2)
These UTC's changes from summer to winter different dates each year.
Summer time
• 2019 - The night between Saturday 30 March and Sunday 31 March
• 2020 - The night between Saturday 28 March and Sunday 29 March
• 2021 - The night between Saturday, March 27 and Sunday, March 28
• 2022 - The night between Saturday 26 March and Sunday 27 March
• 2023 - The night between Saturday, March 25 and Sunday, March 26
Winter time
• 2019 - The night between Saturday, October 26 and Sunday, October 27
• 2020 - The night between Saturday, October 24 and Sunday, October 25
• 2021 - The night between Saturday, October 30 and Sunday, October 31
• 2022 - The night between Saturday 29 October and Sunday 30 October
• 2023 - The night between Saturday 28 October and Sunday 29 October
Would it be possible to make an if-statement that changes these UTC's, with the right +1/+2?
Maybe something like this:
$Winter= gmdate('Y-m-d H:i:s', strtotime("WinterUTC"));
$Summer= gmdate('Y-m-d H:i:s', strtotime("SummerUTC"));
if (($$DBdata>= $Winter) && ($$DBdata<= $Summer)){
$gmt_dateWinter = gmdate('Y-m-d H:i:s', strtotime($date + '+ 2 hours') );
}else{
$gmt_dateSummer = gmdate('Y-m-d H:i:s', strtotime($date + '+ 1 hours') );
}
I don't know if this even is a smart way to do this. If there is another more smart way to do it please lead me in another direction.
Thanks!
With the DateTime class you can easy convert a date/time to any other time zone.
function convertTimeZone($strDateTime, $sourceTimeZone, $targetTimeZone){
return date_create($strDateTime, new DateTimeZone($sourceTimeZone))
->setTimeZone(new DateTimeZone($targetTimeZone))
->format('Y-m-d H:i:s');
}
example with a daylight saving time
$localTime = convertTimeZone('2019-10-10 12:25:59', 'UTC', 'Europe/Copenhagen');
echo $localTime."<br>";
returns:
2019-10-10 14:25:59
example wintertime
$localTime = convertTimeZone('2019-02-10 12:25:59', 'UTC', 'Europe/Copenhagen');
echo $localTime."<br>";
returns:
2019-02-10 13:25:59
Note: Solutions based on stringtotime are not recommended because of known issues and limitations on some systems.
You can use gmdate and date("I") to generate the date considering the timezone:
gmdate: Format a GMT/UTC date/time
$DBdata = '2019-10-10 12:25:59';
$timezone = +2; // (GMT +2:00) CEST (European Summer Time)
$GMdate = gmdate("Y-m-d H:i:s", strtotime($DBdata) + 3600*($timezone + date("I")));
echo $GMdate;
returns:
2019-10-10 22:25:59
From the date documentation:
I (capital i) Whether or not the date is in daylight saving time: 1
if Daylight Saving Time, 0 otherwise.
Thats simple change in php script default timezone and then display time:
https://www.php.net/manual/en/function.date-default-timezone-set.php
$time = date('H:i:s', time());
$ok = date_default_timezone_set('America/Los_Angeles');
echo $tz = date_default_timezone_get();
$h = new DateTime();
echo $h->format('H:i:s'); // curr time
$o = new DateTime($time);
echo $o->format('H:i:s'); // time

PHP Date function skipping February. Does anybody know of a work around for this date bug?

I am displaying month titles 3 month into the future as well as getting the 1st and last day of each of those months.
for($i = 1; $i < 4; $i++) { // For each month for 3 months
$monthTitle = date('F Y', strtotime('+'.$i.' month'));
$begin_date = date('Y-m-01', strtotime('+'.$i.' month')); // First day of calendar month in future.
$end_date = date('Y-m-t', strtotime('+'.$i.' month')); // Last day of calendar months in future.
};
Nov. 29, 2015 output is:
December 2015
2015-12-01
2015-12-31
January 2016
2016-01-01
2016-01-31
February 2016
2016-02-01
2016-02-29
This was working great right up until yesterday, Nov. 29, 2015 but today Nov. 30, 2015 it skips February.
Nov. 30, 2015 output is:
December 2015
2015-12-01
2015-12-31
January 2016
2016-01-01
2016-01-31
March 2016
2016-03-01
2016-03-31
I'm guessing a bug but does anybody know of a work around?
Thanks to #devlin carnate for pointing me in the right direction.
for($i = 1; $i < 4; $i++) { # for each month
$tmp = date('Y-m-15'); // Get the middle of the month to avoid PHP date bug.
$begin_date = date('Y-m-01', strtotime($tmp . '+'.$i.' month')); // First day of calendar month in future.
$end_date = date('Y-m-t', strtotime($begin_date)); // Last day of calendar months in future.
$monthTitle = date('F Y', strtotime($begin_date));
};
This seems to work very well.
You can use DateInterval to add one month to the current date, so you can get the first and the last day of month.
<?php
$date = new DateTime('2015-12-01');
$i = 0;
while($i < 3){
printf("%s | first day: %s, | last day: %s <br>", $date->format('F Y'), $date->format('d'), $date->format('t'));
$date->add(new DateInterval('P1M'));
$i++;
}
Output:
December 2015 - first day: 01, | last day: 31
January 2016 - first day: 01, | last day: 31
February 2016 - first day: 01, | last day: 29
if last day of next month is needed then you can use this
$d = new DateTime( '2010-01-31' );
$d->modify( 'last day of next month' );
echo $d->format( 'Y-m-d' ), "\n";

How to loop through months that have been already passed

I have the following to loop through each month of the year. However, it seems to skip February.
$start = new DateTime('2015-01-01');
$start->modify('last day of this month');
$current = new DateTime('now');
$end = new DateTime('2018-01-01');
$interval = DateInterval::createFromDateString('1 month');
$period = new DatePeriod($start, $interval, $end);
$timestamps = array();
foreach ($period as $dt) {
$dt->modify('last day of this month');
echo 'C:' . $current->format('d F Y') . '<br>';
echo 'S:' . $start->format('d F Y') . '<br>';
echo 'D:' . $dt->format('d F Y') . '<br>';
echo '<br><br>';
}
However, the above outputs:
C:17 March 2015
S:31 January 2015
D:31 January 2015
C: 17 March 2015
S:31 January 2015
D:31 March 2015
C: 17 March 2015
S:31 January 2015
D:30 April 2015
Can anyone spot my mistake? I expected the second D to have a value of the 28 February 2015.
I just want a list of months that have already been passed.
Update
The problem highlighted by MLeFevre in the comments is that working with date intervals can be tricky. See Example #3 Beware when adding months http://php.net/manual/en/datetime.add.php.
Rather than use a DatePeriod, why not just use the modify method slightly differently like this:
$current = new DateTime('now');
$end = new DateTime('2018-01-01');
while($current < $end) {
$current->modify('last day of next month');
echo 'C:' . $current->format('d F Y') . '<br>';
}
In your question, you're firstly adding a month, then going to the end of that month. This doesn't work, as the length of each month varies.
Sample output:
C:30 April 2015
C:31 May 2015
C:30 June 2015
C:31 July 2015
C:31 August 2015
C:30 September 2015
C:31 October 2015
C:30 November 2015
C:31 December 2015
C:31 January 2016
C:29 February 2016
C:31 March 2016
// etc.
To loop from $start to $current, you could change the logic slightly like this:
$start = new DateTime('2015-01-31'); // start from end of month
$current = new DateTime('now');
do {
echo 'C:' . $start->format('d F Y') . '<br>';
} while($start->modify('last day of next month') < $current);
Output:
C:31 January 2015
C:28 February 2015
It happen because February has 28 days and your interval is 1 month (30 days). So it skips 30 days from 30 January to 2 March. Then it move to last day of March.
Change
$start->modify('last day of this month');
to
$start->modify('first day of this month');
Your first date is 31-Jan-2015. Since February has no 31st, it's going to March 3rd. Then you are telling it to go to the end of that month which is why you are getting the end of March after January and not February.

Parsing dates with inconsistent formats in PHP

I have two queries, both related to dates.
1) I have dates in these formats, which I'm looking to normalise into the same format before saving into a database:
Saturday 26 July
Monday 28 - Wednesday 30 July
July 24th, 2014
Thu 4 Sep
Thu 28 Aug — Fri 19 Sep
24-07-2014
Single days are quite easy to work out using strtotime(), but ranges of dates are a bit more tricky.
This, for example, doesn't work:
$dateString = "Monday 28 - Wednesday 30 July";
if (strpos($dateString, "-")) {
$datePieces = explode("-", $dateString);
$startDate = strtotime($datePieces[0]);
$endDate = strtotime($datePieces[1]);
} else {
$startDate = strtotime($dateString);
$endDate = strtotime($dateString);
}
echo '<pre>';
echo date('d F Y', $startDate);
echo '<br/>';
echo date('d F Y', $endDate);
Because the month is only on one side of the explode(), doing it this way returns:
01 January 1970
30 July 2014
2) I need a way of working out what year the date is (it will always be in the future). Something along the lines of:
if (the month in the date string has elapsed) {
the year of the date is this year + 1
}
As long as each source provides you with a consistent format you can use DateTime() and DateTime::createFromFormat() to process the dates for you.
//Saturday 26 July
$date = DateTime::createFromFormat('l j F', 'Saturday 26 July');
//July 24th, 2014
$date = new DateTime('July 24th, 2014');
//Thu 4 Sep
$date = DateTime::createFromFormat('D j M', 'Thu 4 Sep');
//Thu 28 Aug — Fri 19 Sep
list($start, $end) = explode(' - ', 'Thu 28 Aug — Fri 19 Sep');
$start = DateTime::createFromFormat('D j M', $start);
$end = DateTime::createFromFormat('D j M', $end);
//24-07-2014
$date = new DateTime('24-07-2014');
I'm going to leave handling Monday 28 - Wednesday 30 July to you since you'll need to do a little more work to get the month from the second date and apply it to the first. But this should show you how to go about this.

What happening to php date function [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
PHP date() and strtotime() return wrong months on 31st
I have this code and it outputs something strange i think. So, what i am doing wrong here.
<?php
$sP1 = date('m Y');
$sP2 = date('m Y', strtotime('+01 month'));
$sP3 = date('m Y', strtotime('+02 month'));
$sP4 = date('m Y', strtotime('+03 month'));
echo $sP1.'<br>';
echo $sP2.'<br>';
echo $sP3.'<br>';
echo $sP4.'<br>';
?>
and this outputs
05 2012
07 2012
07 2012
08 2012
i think the second one should be
06 2012
Anybody know any solution?
Today is the 31st next month only has 30 days so it would be 7/12 in 1 month from today
assuming that today is May 31 2012
date('m Y') == 05 2012
date('m Y', strtotime('+1 month')) == 07 2012 because june has 30 days
date('m Y', strtotime('+2 month')) == 07 2012
date('m Y', strtotime('+3 month')) == 08 2012
date('m Y', strtotime('+4 month')) == 10 2012
I would take today's date and find the first day of the month then add a month to that if you are doing something that needs to get each month
As others have said, it is because today is the 31st and +1 month equals June-31 which changes to Jul-1. If you include the day in the date string, you can see exactly this.
<?php
$sP1 = date('m-d-Y');
$sP2 = date('m-d-Y', strtotime('+01 month'));
$sP3 = date('m-d-Y', strtotime('+02 month'));
$sP4 = date('m-d-Y', strtotime('+03 month'));
echo $sP1."\n";
echo $sP2."\n";
echo $sP3."\n";
echo $sP4."\n";
/* Outputs:
05-31-2012
07-01-2012
07-31-2012
08-31-2012
*/
?>
strtotime though can take the start date as part of the string so as King suggested, calculate the +N months from the first. So a string like May-1-2012 +01 month such as:
<?php
$sP1 = date('m Y');
$sP2 = date('m Y', strtotime(date('M-1-Y').' +01 month'));
$sP3 = date('m Y', strtotime(date('M-1-Y').' +02 month'));
$sP4 = date('m Y', strtotime(date('M-1-Y').' +03 month'));
echo $sP1."\n";
echo $sP2."\n";
echo $sP3."\n";
echo $sP4."\n";
/* Outputs:
05 2012
06 2012
07 2012
08 2012
*/
?>
http://codepad.org/auYLHvDI
It is working as intended. In a nutshell, it is because what is "one month" from May 31? June 30? August 1?
My suggestion is that if you need sequential months, calculate the offset from the start of the current month, not the current day. Or compose the date that you're looking for manually using the month, day, and year parts broken up.

Categories