0

Hello i have a special timezone like Europe/Berlin and i would like to add 90 days to the current date. After that i detect the last day of month.

My Dates in the database are saved in UTC. That is why i must change the timezone at the end.

My Problem is, that the Timezone change subtract 2 hours from the time between Europe/Berlin and UTC. When i don't modify the datetime object before i change it to UTC then it will subtract just 1 hour. Can anybody tell me what the problem is or the correct solution?

//$timezone = 'Europe/Berlin';
private function getMaxTillDate($timezone)
{        
    $threemonth = new \DateTime('now', new \DateTimeZone($timezone) );
    $threemonth->setTime(23, 59, 59);
    $threemonth->add(new \DateInterval('P0Y90DT0H0M'));
    $maxday = $threemonth->format('t');        
    $threemonth->setDate($threemonth->format('Y'), $threemonth->format('m'), $maxday);
    $threemonth->setTimezone(new \DateTimeZone('UTC'));

    return $threemonth;
}

Thank you very much

hakre
  • 193,403
  • 52
  • 435
  • 836
Wolf-Tech
  • 1,259
  • 3
  • 18
  • 38
  • 2
    There is daylight saving time in Germany for at least half of the year, which is UTC+2 hours. – Sven Jan 15 '13 at 21:04
  • yes, i know but it doesnt describe why php substract just 1 hour if i doesn't manipulate the dateobject before i change the timezone. – Wolf-Tech Jan 15 '13 at 21:23

1 Answers1

0

I tested your code - it works for me:

function getMaxTillDate($timezone){
    $threemonth = new \DateTime('now', new \DateTimeZone($timezone) );
    var_dump(1, $threemonth);
    $threemonth->setTime(23, 59, 59);
    var_dump(2, $threemonth);
    $threemonth->add(new \DateInterval('P0Y90DT0H0M'));
    var_dump(3, $threemonth);
    $maxday = $threemonth->format('t');
    var_dump(4, $threemonth, $maxday);
    $threemonth->setDate($threemonth->format('Y'), $threemonth->format('m'), $maxday);
    var_dump(5, $threemonth);
    $threemonth->setTimezone(new \DateTimeZone('UTC'));
    var_dump(6, $threemonth);
    return $threemonth;
}

$tz = "Europe/Berlin";

var_dump(getMaxTillDate($tz));

Results:

int(1)
class DateTime#1 (3) {
public $date =>
string(19) "2013-01-15 22:29:59"
public $timezone_type =>
int(3)
public $timezone =>
string(13) "Europe/Berlin"
}
int(2)
class DateTime#1 (3) {
public $date =>
string(19) "2013-01-15 23:59:59"
public $timezone_type =>
int(3)
public $timezone =>
string(13) "Europe/Berlin"
}
int(3)
class DateTime#1 (3) {
public $date =>
string(19) "2013-04-15 23:59:59"
public $timezone_type =>
int(3)
public $timezone =>
string(13) "Europe/Berlin"
}
int(4)
class DateTime#1 (3) {
public $date =>
string(19) "2013-04-15 23:59:59"
public $timezone_type =>
int(3)
public $timezone =>
string(13) "Europe/Berlin"
}
string(2) "30"
int(5)
class DateTime#1 (3) {
public $date =>
string(19) "2013-04-30 23:59:59"
public $timezone_type =>
int(3)
public $timezone =>
string(13) "Europe/Berlin"
}
int(6)
class DateTime#1 (3) {
public $date =>
string(19) "2013-04-30 21:59:59"
public $timezone_type =>
int(3)
public $timezone =>
string(3) "UTC"
}
class DateTime#1 (3) {
public $date =>
string(19) "2013-04-30 21:59:59"
public $timezone_type =>
int(3)
public $timezone =>
string(3) "UTC"
}
Sven
  • 69,403
  • 10
  • 107
  • 109
  • please uncomment these rows then you will see the difference: $threemonth->setTime(23, 59, 59); $threemonth->add(new \DateInterval('P0Y90DT0H0M')); $maxday = $threemonth->format('t'); $threemonth->setDate($threemonth->format('Y'), $threemonth->format('m'), $maxday); – Wolf-Tech Jan 15 '13 at 21:45
  • They are not commented, as you see. If I comment them out, I perfectly see the current timezone setting being active: It is now 22:50 in the "Europe/Berlin" timezone today, we are on winter time, e.g. "UTC+1". Starting from 2013-03-31 we will be on "UTC+2". – Sven Jan 15 '13 at 21:48
  • it doesn't explain why the timezone substract 2 hours when i manipulate the date and just 1 hour when i don't do anything with the date. – Wolf-Tech Jan 16 '13 at 08:54
  • 2
    It does. You create a "point in time" with the info "rules of Europe/Berlin timezone apply". Today that implies that the time you give is UTC+1 - changing the timezone to UTC means that the hour for the same point in time is one less. If you move the date to "3 months from now", you do not change the timezone first, and you do not change the time. Now you have a date where the timezone rules states that it is "UTC+2". This is subject to the way the date add id performed: You only add days, you do not change the local hour if the UTC offset is changed. – Sven Jan 16 '13 at 16:40
  • thank you very much. now i understand. i totally forgot that. – Wolf-Tech Jan 17 '13 at 07:34