Parsing dates with inconsistent formats in PHP - 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.

Related

How To Get Next Wednesday With 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)));

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.

Adding time to Nov. 2nd gives error

I'm having some problems adding a date.
$test = strtotime('nov 02 2014');
$test_date = date('D, M. jS, Y' ,(1.0*86400) + $test);
echo $test_date;
returns Sun, Nov. 2nd, 2014
changing input to nov 01 and nov 03 return the expected strings.
This should work for you:
$test = "nov 02 2014";
echo $test_date = date('D, M. jS, Y' ,strtotime($test . ' + 1 day'));
Daylight Saving Time ended on November 2, 2014. This means that November 2, 2014 lasted longer than the 86,400 seconds you're adding to the date!

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.

Date formatting in PHP

I've a date formatted like "Tue Jan 05 11:08:27 +0000 2010" and I want to convert it's format to "yyyy-mm-dd 00:00" in PHP.
How can I do that?
convert it to a PHP date object with strtotime() then output it with date()
EDIT
Some more detail; try:
$time = strtotime('Tue Jan 05 11:08:27 +0000 2010');
echo date("Y-m-d h:i", $time);
Y = 4 digit year
m = 2 digit month (with leading 0)
d = 2 digit month (with leading 0)
h = 12 hour time (leading 0)
i = minutes (with leading 0)
http://php.net/manual/en/function.date.php
for all the formatting options
$time_string = 'Tue Jan 05 11:08:27 +0000 2010';
$formated_time = date('Y-m-d h:i', strtotime($time_string));
echo $formated_time;
strtotime + date
Agree with Erik, if you want to do it in one line.
Solution
$date = date('Y-m-d H:i:s', strtotime('Tue Jan 05 11:08:27 +0000 2010'));

Categories