php DatePeriod Object access start and current date - php

My understanding is that you cant access start and current date from date period object. My current php is 5.5, is there a workaround, since I cant upgrade to php 5.6 or php 7, and I need to get those dates.
DatePeriod Object
(
[start] => DateTime Object
(
[date] => 2016-04-03 00:00:00
[timezone_type] => 3
[timezone] => UTC
)
[current] => DateTime Object
(
[date] => 2016-04-10 00:00:00
[timezone_type] => 3
[timezone] => UTC
)
)

DatePeriod is a Traversable interface implementation. It supports only foreach loop.
You can obtain start and current elements only converting it to an array:
$start = new DateTime( '2016-03-01' );
$end = new DateTime( '2016-03-31' );
$interval = new DateInterval( 'P1D' );
$period = new DatePeriod( $start, $interval ,$end );
$arPeriod = iterator_to_array( $period );
$startDate = $arPeriod[0];
next( $arPeriod );
$currentDate = current( $arPeriod );

Related

PHP Timezone bug: adding extra hour

I have problem...
I'm currently working with "America/Santiago" timezone, and whenever I create a datetime object with a hour < 01:00AM, it adds 1 hour.
Example:
date_default_timezone_set('America/Santiago');
$dateTest = date_create_from_format('d/m/Y H:i:s', '04/09/2022 00:32:27');
print_r($dateTest);
This prints:
DateTime Object
(
[date] => 2022-09-04 01:32:27.000000
[timezone_type] => 3
[timezone] => America/Santiago
)
But if I create the following object:
date_default_timezone_set('America/Santiago');
$dateTest = date_create_from_format('d/m/Y H:i:s', '04/09/2022 01:22:11');
print_r($dateTest);
prints:
DateTime Object
(
[date] => 2022-09-04 01:22:11.000000
[timezone_type] => 3
[timezone] => America/Santiago
)
I'm really lost here, can someone guide ?
Thanks

php date_diff / timestamp off by 31 minutes

I've generated a timestamp using code:
date_default_timezone_set("UTC");
$timestamp = date_create("now")->getTimestamp();
echo "value=$timestamp";
I get a value:
1484800385
I [later] want to grab the difference between that value and the current time.
$timestamp = "1484800385";
echo " timestamp=$timestamp<hr>";
print_r (new DateTime("#$timestamp"));
echo "<hr>";
print_r (date_create("now",timezone_open("UTC")));
and this outputs dates - but the difference in the time is greater than what I am expecting - by half an hour. The timezones are also shown differently.
timestamp=1484800385
DateTime Object ( [date] => 2017-01-19 04:33:05.000000 [timezone_type] => 1 [timezone] => +00:00 )
DateTime Object ( [date] => 2017-01-19 05:08:32.000000 [timezone_type] => 3 [timezone] => UTC )
I tried another script. First I generated a timestamp:
date_default_timezone_set("Australia/Sydney");
echo date_create("now")->getTimestamp(); // prints 1484800977
I then copied and pasted the value shown looked at it a few seconds later, compared to the date now
date_default_timezone_set("Australia/Sydney");
$date1 = new DateTime();
$date1->setTimestamp($timestamp);
print_r($date1);
$date2 = date_create("now");
print_r($date2);
and it's still wrong - by 31 minutes.
DateTime Object ( [date] => 2017-01-19 15:42:57.000000 [timezone_type] => 3 [timezone] => Australia/Sydney )
DateTime Object ( [date] => 2017-01-19 16:22:25.000000 [timezone_type] => 3 [timezone] => Australia/Sydney )
and UTC timezone
$timestamp = 1484801882;
date_default_timezone_set('UTC');
$date1 = new DateTime();
$date1->setTimestamp($timestamp);
$date2 = new DateTime();
print_r($date1);
print_r($date2);
results in the same timezone, but the current date is 31 minutes ahead of where I expect it to be.
DateTime Object ( [date] => 2017-01-19 04:58:02.000000 [timezone_type] => 3 [timezone] => UTC )
DateTime Object ( [date] => 2017-01-19 05:33:23.000000 [timezone_type] => 3 [timezone] => UTC )
What's going on?
Try to setTimeZone to UTC before print
$UTC = new DateTimeZone("UTC");
$date = new DateTime("now");
$date->setTimezone( $UTC );
print_r ($date);
echo "<hr>";
print_r (date_create("now",timezone_open("UTC")));
The output is
DateTime Object
(
[date] => 2017-01-19 05:17:52.000000
[timezone_type] => 3
[timezone] => UTC
)
>DateTime Object
(
[date] => 2017-01-19 05:17:52.000000
[timezone_type] => 3
[timezone] => UTC
)

Strange bug of date_modify function in DateTime class

I use the native PHP DateTime class for adding days to dates. But when dealing with negative dates, I encountered a strange bug. Depending on the millennium added or a day or two. Example:
$date_one = date_create("-1000-12-27");
date_modify($date_one, '+1 day');
//Return DateTime Object ( [date] => -1000-12-29 00:00:00 )
$date_two = date_create("-2000-12-27");
date_modify($date_two, '+1 day');
//Return DateTime Object ( [date] => -2000-12-28 00:00:00 )
$date_three = date_create("-3000-12-27");
date_modify($date_three, '+1 day');
//Return DateTime Object ( [date] => -3000-12-29 00:00:00 )
That is, depending on the parity of the millennium issue, or December 28 or December 29. Why is this happening? What is the problem?

Repeat event on assigned day every week until specific date

When creating event I need to set event start and event end in datetime format (0000-00-00 00:00:00)
Then I have option to set weekly repeating of that event until specific date (0000-00-00)
But I can't insert repeating events properly in database. Here is what I have:
$startDateTime = '2015-04-30 10:30:00';
$endDateTime = '2015-04-30 11:30:00';
$repeatEndDate = '2015-06-01';
$timestamp = strtotime($startDateTime);
$day_of_week = date('l', $timestamp);
$step = 1;
$unit = 'W';
$repeatStart = new DateTime($startDateTime);
$repeatEnd = new DateTime($repeatEndDate);
$repeatStart->modify($day_of_week);
$interval = new DateInterval("P{$step}{$unit}");
$period = new DatePeriod($repeatStart, $interval, $repeatEnd);
foreach ($period as $key => $date ) {
$repeatQuery = 'INSERT INTO event(start,end,status,repeats) VALUES ("'.$startDateTime.'","'.$endDateTime.'","'.$status.'","'.$repeatEndDate.'")';
$repeatResult = mysqli_query($db, $repeatQuery) or die (mysqli_error($db));
}
When I do print_r($date); it looks like this, no actual time just 00:00:00
DateTime Object
(
[date] => 2015-04-30 00:00:00
[timezone_type] => 3
[timezone] => Europe/Berlin
)
I know that I can't insert values like that but I don't know how to get correct values from objects.
So in this example I need to insert events that begin in 10:30:00 and end in 11:30:00(events always end same day) every Thursday starting at 2015-04-30 and ending at 2015-06-01. How can this be achieved?
Thank you
The problem is you're calling DateTime::modify with a day name (currently 'Thursday'). This value is calculated from the $startDateTime variable, and then used to modify that variable, so the only effect it has, is resetting the Time portion of that DateTime instance back to 0:00:00.
The following gives me the results I would expect:
(I've commented out the parts you need to remove from yours, to make it easier to see the difference)
date_default_timezone_set('Etc/UTC');
$startDateTime = '2015-04-30 10:30:00';
$endDateTime = '2015-04-30 11:30:00';
$repeatEndDate = '2015-06-01';
#$timestamp = strtotime($startDateTime);
#$day_of_week = date('l', $timestamp);
$step = 1;
$unit = 'W';
$repeatStart = new DateTime($startDateTime);
$repeatEnd = new DateTime($repeatEndDate);
#$repeatStart->modify($day_of_week);
$interval = new DateInterval("P{$step}{$unit}");
$period = new DatePeriod($repeatStart, $interval, $repeatEnd);
foreach ($period as $key => $date ) {
echo($date->format('Y-m-d H:i:s')) . PHP_EOL;
}
The result from running the above is:
2015-04-30 10:30:00
2015-05-07 10:30:00
2015-05-14 10:30:00
2015-05-21 10:30:00
2015-05-28 10:30:00
When you modify your $repeatStart using the modify() method you are using the l format character which, according to the docs, returns
A full textual representation of the day of the week
by changing the $day_of_week format string to
$day_of_week = date('Y-m-d H:i:s', $timestamp);
I get the following output
DateTime Object
(
[date] => 2015-04-30 10:30:00
[timezone_type] => 3
[timezone] => Europe/London
)
DateTime Object
(
[date] => 2015-05-07 10:30:00
[timezone_type] => 3
[timezone] => Europe/London
)
DateTime Object
(
[date] => 2015-05-14 10:30:00
[timezone_type] => 3
[timezone] => Europe/London
)
DateTime Object
(
[date] => 2015-05-21 10:30:00
[timezone_type] => 3
[timezone] => Europe/London
)
DateTime Object
(
[date] => 2015-05-28 10:30:00
[timezone_type] => 3
[timezone] => Europe/London
)
Although, the modification is not actually necessary and the following code should achieve what you are looking for.
<?php
$startDateTime = '2015-04-30 10:30:00';
$endDateTime = '2015-04-30 11:30:00';
$repeatEndDate = '2015-06-01';
$step = 1;
$unit = 'W';
$repeatStart = new DateTime($startDateTime);
$repeatEnd = new DateTime($repeatEndDate);
$interval = new DateInterval("P{$step}{$unit}");
$period = new DatePeriod($repeatStart, $interval, $repeatEnd);
foreach ($period as $key => $date ) {
$repeatQuery = 'INSERT INTO event(start,end,status,repeats) VALUES ("'.$startDateTime.'","'.$endDateTime.'","'.$status.'","'.$repeatEndDate.'")';
$repeatResult = mysqli_query($db, $repeatQuery) or die (mysqli_error($db));
print_r($date);
}

get date from DateTime Object

After more than an hour struggling and trying I'd like to ask it here.
Trying to make something with weeks etc. in php I got from you site this:
Get all Work Days in a Week for a given date
Nice and will work for me fine.
But ... I can't get, trying and trying, the data out of this part: [date] => 2013-08-12 00:00:00
Array
(
[0] => DateTime Object
(
[date] => 2013-08-12 00:00:00
[timezone_type] => 3
[timezone] => Europe/Amsterdam
)
How to get that date out of the array ?
Please help me out, thanks in advance for the help !
Use DateTime::format()
$dateTime = new DateTime('2013-08-12 00:00:00');
echo $datetime->format('Y-m-d'); // produces 2013-08-12
$firstMondayThisWeek= new DateTime('2013-08-12');
$firstMondayThisWeek->modify('tomorrow');
$firstMondayThisWeek->modify('last Monday');
$nextFiveWeekDays = new DatePeriod(
$firstMondayThisWeek,
DateInterval::createFromDateString('+1 weekdays'),
4
);
$dateTimes = iterator_to_array($nextFiveWeekDays);
foreach ($dateTimes as $dateTime) {
echo $dateTime->format('Y-m-d H:i:s');
}

Categories