के अलावा @ fyrye बहुत मददगार जवाब यह उल्लेख बग (के लिए एक okayish समाधान नहीं है यह एक ), कि DatePeriod एक घंटे substracts जब गर्मियों में प्रवेश, लेकिन जब गर्मियों छोड़ने (और इस प्रकार यूरोप / बर्लिन के मार्च अपनी है एक घंटे नहीं जोड़ता है सही 743 घंटे लेकिन अक्टूबर में 745 घंटे के बजाय 744 है):
एक महीने (या किसी भी समय) के घंटे की गिनती, दोनों दिशाओं में डीएसटी-बदलाव पर विचार करना
function getMonthHours(string $year, string $month, \DateTimeZone $timezone): int
{
// or whatever start and end \DateTimeInterface objects you like
$start = new \DateTimeImmutable($year . '-' . $month . '-01 00:00:00', $timezone);
$end = new \DateTimeImmutable((new \DateTimeImmutable($year . '-' . $month . '-01 23:59:59', $timezone))->format('Y-m-t H:i:s'), $timezone);
// count the hours just utilizing \DatePeriod, \DateInterval and iterator_count, hell yeah!
$hours = iterator_count(new \DatePeriod($start, new \DateInterval('PT1H'), $end));
// find transitions and check, if there is one that leads to a positive offset
// that isn't added by \DatePeriod
// this is the workaround for https://bugs.php.net/bug.php?id=75685
$transitions = $timezone->getTransitions((int)$start->format('U'), (int)$end->format('U'));
if (2 === count($transitions) && $transitions[0]['offset'] - $transitions[1]['offset'] > 0) {
$hours += (round(($transitions[0]['offset'] - $transitions[1]['offset'])/3600));
}
return $hours;
}
$myTimezoneWithDST = new \DateTimeZone('Europe/Berlin');
var_dump(getMonthHours('2020', '01', $myTimezoneWithDST)); // 744
var_dump(getMonthHours('2020', '03', $myTimezoneWithDST)); // 743
var_dump(getMonthHours('2020', '10', $myTimezoneWithDST)); // 745, finally!
$myTimezoneWithoutDST = new \DateTimeZone('UTC');
var_dump(getMonthHours('2020', '01', $myTimezoneWithoutDST)); // 744
var_dump(getMonthHours('2020', '03', $myTimezoneWithoutDST)); // 744
var_dump(getMonthHours('2020', '10', $myTimezoneWithoutDST)); // 744
पुनश्च यदि आप एक (अधिक) समय-समय पर जांच करते हैं, जो उन दो संक्रमणों से अधिक की ओर जाता है, तो मेरा वर्कअराउंड फनी साइड इफेक्ट्स की संभावना को कम करने के लिए गिने हुए घंटों को नहीं छूएगा। ऐसे मामलों में, अधिक जटिल समाधान को लागू किया जाना चाहिए। सभी पाए गए संक्रमणों पर एक पुनरावृत्ति कर सकता है और अंतिम के साथ वर्तमान की तुलना कर सकता है और यह जांच सकता है कि क्या यह डीएसटी के साथ सही है-> गलत।
strftime()
3600 तक के अंतर का उपयोग करते हुए टिकटों में बदल दें , लेकिन क्या यह हमेशा काम करेगा? धिक्कार है, डेलाइट सेविंग टाइम!