Detect BST in php - php

I am building a booking system in php that offers session times for people to book outdoor activities.
In the summer months, there is an extra session available at the end of the day, because of Daylight Savings, there is an extra hour in the evenings.
Year Clocks go forward Clocks go back
2014 30 March 26 October
2015 29 March 25 October
2016 27 March 30 October
2017 27 March 30 October
2018 25 March 28 October
I am using this...
$todaysDate = strtotime(date("Y-m-d"));
$bstBegin = strtotime("2015-03-29");
$bstEnd = strtotime("2015-10-25");
if($todaysDate > $bstBegin && $todaysDate > $bstEnd)
{
echo "<option value="evening">Evening Session</option>";
}
I only need to show this extra option in the select list between these dates. Is this something I will need to set manually from year to year, or is there a PHP date variable that knows the days the clocks change?

$today = strtotime(date("Y-m-d"));
if (date('I', $today)) {
echo "We're in BST!";
} else {
echo "We're not in BST!";
}
or use the DateTime object equivalent, which maintains details of all the transition dates globally

I work normally with the DateTime functions and like it very much. You have a lot of possibilities to modify a date.
But in your case you can concat the actual year to your string.
$todaysDate = strtotime(date("Y-m-d"));
$bstBegin = strtotime(date('Y')."-03-29");
$bstEnd = strtotime(date('Y')."-10-25");
I hope i have understood your problem correctly.

I have found this online very good ref : https://gist.github.com/aromig/56376f76d4fb653ba83e
public function is_BST() {
$theTime = time();
$tz = new DateTimeZone('Europe/London');
$transition = $tz->getTransitions($theTime, $theTime);
$abbr = $transition[0]['abbr'];
return $abbr == 'BST' ? true : false; }

Related

php not parsing date correctly

I need to convert 'Nov22' into a date object that is in the month of November. I am trying the following - but it only works with months with 31 days:
$novDateString = 'Nov22';
$decDateString = 'Dec22';
$novDate = DateTime::createFromFormat('My', $novDateString);
$decDate = DateTime::createFromFormat('My', $decDateString);
echo $novDate->format('m');
echo $decDate->format('m');
// output
12
12
As you can see, both Nov22 and Dec22 go to December. In fact, all months with less than 31 days go map to the month ahead of it. Is this a known issue or is there an easy way to solve?
Since you're not specifying a day, it's defaulting to today, which is the 31st:
$novDateString = 'Nov22';
$decDateString = 'Dec22';
$novDate = DateTime::createFromFormat('My', $novDateString);
// DateTime #1669926271 {#4573
// date: 2022-12-01 15:24:31.0 America/New_York (-05:00),
// }
$decDate = DateTime::createFromFormat('My', $decDateString);
//DateTime #1672518273 {#4578
// date: 2022-12-31 15:24:33.0 America/New_York (-05:00),
// }
November 31st doesn't exist, so the day becomes December 1st. You need to prepend a day before the string, and then pass in the correct format:
$novDate = DateTime::createFromFormat('jMy', '1'.$novDateString);
//DateTime #1667331673 {#4576
// date: 2022-11-01 15:41:13.0 America/New_York (-04:00),
// }

How does daylight saving work in php (difference between php and hhvm)?

I need to detect when a timestamp is in daylight saving or not.
I'm using this code to test the functionality:
<?php
date_default_timezone_set('Europe/Berlin');
$timestamp = $baseTimestamp = 1509234900; // Sunday, 29 October of 2017 1:55:00 GMT+02:00 DST
$date = (new DateTime)->setTimestamp($baseTimestamp);
echo "DateTime\t\t| Is in summer \t| Minutes passed\n";
for($i = 0; $i < 70; $i++) {
$date = (new DateTime)->setTimestamp($timestamp);
echo $date->format("Y-m-d H:i:s \t|I") . "\t\t| " . ($timestamp - $baseTimestamp)/60 . "\n";
$timestamp = $timestamp + 60;
}
https://3v4l.org/dqNlK
Working with Europe/Berlin, I've seen that in March, when at 2.00 we pass from winter to summer, php solves it right, but then in October, when it is supposed to come back from summer to winter at 3.00, it doesn't work as expected.
In this case, we have two timestamps corresponding to the same hour (at 3 is 2 again), but the timestamp is unique, so for 2.00 there must be one timestamp in the summer time and another one in the winter time.
Using hhvm, it shows the right value, but normal php interpreters show that is not in summer for both 2.00 (the first one, which is 2am and the second one which is when at 3am is 2am again. This is the one that should say is not in summer anymore)
Yes, there are several long-lived, unresolved, DST-related bugs in PHP.
You appear to have hit on this one:
https://bugs.php.net/bug.php?id=68549
function isSummer($timestamp) {
$date = (new DateTime)->setTimestamp($timestamp);
if ($date->format('I') == 1) {
return true;
}
return ($date->getTimestamp() > $timestamp);
}
I think this is going to do the trick

need to store date as per user timezone in php

i have simple php script where i have this variable
$date = date('Y-m-d', time());
The Problem: The variable is storing date as per my server timezone.
What is want: I want to store date as per user time zone, take a look into
example below:
1- tom checkin from USA
2- jenne checkin from Asia
since there is 12 hrs. difference so the date will be different too sometime
here is found some example but it's not dynamic
Converting GMT time to local time using timezone offset in php
offset = '-0500';
$isDST = 1; // Daylight Saving 1 - on, 0 - off
$timezoneName = timezone_name_from_abbr('', intval($offset, 10) * 36, $isDST);
$timezone = new DateTimeZone($timezoneName);
Then you can use it in a DateTime constructor, e.g.
$datetime = new DateTime('2012-04-21 01:13:30', $timezone);
Now what exactly i am looking,
1- in case of TOM $date should be 18
11:38 PM
Tuesday, 18 April 2017 (GMT-5)
Time in Chicago, IL, USA
2- in case of jenne $date should be 19
9:40 AM
Wednesday, 19 April 2017 (GMT+5)
Time in Lahore
difficult writing code in the comments section so i posted a working answer for you here
<?php
// here $usertimezone should be set = to what you have in your database
$usertimezone="Asia/Shanghai";
date_default_timezone_set('"'.$usertimezone.'"');
//new date and time
$ndate= new datetime();
//split into date and time seperate
$nndate =$ndate->format("Y-m-d");
$nntime= $ndate->format("H:i:S");
//here you can test it
echo $nndate;
echo $nntime;
?>
Use this function date_default_timezone_set for setting timezone, From this function you can set the timezone according to user and then get the required format.
Examples
<?php
date_default_timezone_set("new/timezone");//set the name of timezone here example Asia/Kokata
echo $date= date("Y-m-d H:i:s");

Can't get previous month from DateTime in PHP- Is this a (pretty big) bug?

I need to create functions in PHP that let me step up/down given datetime units. Specifically, I need to be able to move to the next/previous month from the current one.
I thought I could do this using DateTime::add/sub(P1M). However, when trying to get the previous month, it messes up if the date value = 31- looks like it's actually trying to count back 30 days instead of decrementing the month value!:
$prevMonth = new DateTime('2010-12-31');
Try to decrement the month:
$prevMonth->sub(new DateInterval('P1M')); // = '2010-12-01'
$prevMonth->add(DateInterval::createFromDateString('-1 month')); // = '2010-12-01'
$prevMonth->sub(DateInterval::createFromDateString('+1 month')); // = '2010-12-01'
$prevMonth->add(DateInterval::createFromDateString('previous month')); // = '2010-12-01'
This certainly seems like the wrong behavior. Anyone have any insight?
Thanks-
NOTE: PHP version 5.3.3
(Credit actually belongs to Alex for pointing this out in the comments)
The problem is not a PHP one but a GNU one, as outlined here:
Relative items in date strings
The key here is differentiating between the concept of 'this date last month', which, because months are 'fuzzy units' with different numbers of dates, is impossible to define for a date like Dec 31 (because Nov 31 doesn't exist), and the concept of 'last month, irrespective of date'.
If all we're interested in is the previous month, the only way to gaurantee a proper DateInterval calculation is to reset the date value to the 1st, or some other number that every month will have.
What really strikes me is how undocumented this issue is, in PHP and elsewhere- considering how much date-dependent software it's probably affecting.
Here's a safe way to handle it:
/*
Handles month/year increment calculations in a safe way,
avoiding the pitfall of 'fuzzy' month units.
Returns a DateTime object with incremented month/year values, and a date value == 1.
*/
function incrementDate($startDate, $monthIncrement = 0, $yearIncrement = 0) {
$startingTimeStamp = $startDate->getTimestamp();
// Get the month value of the given date:
$monthString = date('Y-m', $startingTimeStamp);
// Create a date string corresponding to the 1st of the give month,
// making it safe for monthly/yearly calculations:
$safeDateString = "first day of $monthString";
// Increment date by given month/year increments:
$incrementedDateString = "$safeDateString $monthIncrement month $yearIncrement year";
$newTimeStamp = strtotime($incrementedDateString);
$newDate = DateTime::createFromFormat('U', $newTimeStamp);
return $newDate;
}
Easiest way to achieve this in my opinion is using mktime.
Like this:
$date = mktime(0,0,0,date('m')-1,date('d'),date('Y'));
echo date('d-m-Y', $date);
Greetz Michael
p.s mktime documentation can be found here: http://nl2.php.net/mktime
You could go old school on it and just use the date and strtotime functions.
$date = '2010-12-31';
$monthOnly = date('Y-m', strtotime($date));
$previousMonth = date('Y-m-d', strtotime($monthOnly . ' -1 month'));
(This maybe should be a comment but it's to long for one)
Here is how it works on windows 7 Apache 2.2.15 with PHP 5.3.3:
<?php $dt = new DateTime('2010-12-31');
$dt->sub(new DateInterval('P1M'));
print $dt->format('Y-m-d').'<br>';
$dt->add(DateInterval::createFromDateString('-1 month'));
print $dt->format('Y-m-d').'<br>';
$dt->sub(DateInterval::createFromDateString('+1 month'));
print $dt->format('Y-m-d').'<br>';
$dt->add(DateInterval::createFromDateString('previous month'));
print $dt->format('Y-m-d').'<br>'; ?>
2010-12-01
2010-11-01
2010-10-01
2010-09-01
So this does seem to confirm it's related to the GNU above.
Note: IMO the code below works as expected.
$dt->sub(new DateInterval('P1M'));
Current month: 12
Last month: 11
Number of Days in 12th month: 31
Number of Days in 11th month: 30
Dec 31st - 31 days = Nov 31st
Nov 31st = Nov 1 + 31 Days = 1st of Dec (30+1)

Find out date of nth week's monday in PHP?

I have a simple situation where I have a user supplied week number X, and I need to find out that week's monday's date (e.g. 12 December). How would I achieve this? I know year and week.
Some code based mainly on previous proposals:
$predefinedYear = 2009;
$predefinedWeeks = 47;
// find first mоnday of the year
$firstMon = strtotime("mon jan {$predefinedYear}");
// calculate how much weeks to add
$weeksOffset = $predefinedWeeks - date('W', $firstMon);
// calculate searched monday
$searchedMon = strtotime("+{$weeksOffset} week " . date('Y-m-d', $firstMon));
An idea to get you started:
take first day of year
add 7 * X days
use strtodate, passing in "last Monday" and the date calculated above.
May need to add one day to the above.
Depending on the way you are calculating week numbers and the start of the week this may sometimes be out. (i.e. if the monday in the first week of the year was actually in the previous year!)
TEST THIS THOROUGHLY - but I've used a similar approach for similar calcualtions in the past.
This will solve the problem for you. It mainly derives from Mihail Dimitrov's answer, but simplifies and condenses this somewhat. It can be a one-line solution if you really want it to be.
function getMondaysDate($year, $week) {
if (!is_numeric($year) || !is_numeric($week)) {
return null;
// or throw Exception, etc.
}
$timestamp = strtotime("+$week weeks Monday January $year");
$prettyDate = date('d M Y');
return $prettyDate;
}
A couple of notes:
As above, strtotime("Monday January $year") will give you the timestamp of the first Monday of the year.
As above +X weeks will increment a specified date by that many weeks.
You can validate this by trying:
date('c',strtotime('Sunday Jan 2018'));
// "2018-01-07T00:00:00+11:00" (or whatever your timezone is)
date('c',strtotime('+1 weeks Sunday Jan 2018'));
// "2018-01-14T00:00:00+11:00" (or whatever your timezone is)
date('c',strtotime('+52 weeks Sunday Jan 2018'));
// "2019-01-06T00:00:00+11:00"
Due to reputation restriction i can't post multiple links
for details check
http://php.net/manual/en/function.date.php and http://php.net/manual/en/function.mktime.php
you can use something like this :
use mktime to get a timestamp of the week : $stamp = mktime(0,0,0,0,<7*x>,) {used something similar a few years back, so i'm not sure it works like this}
and then use $wDay = date('N',$stamp). You now have the day of the week, the timestamp of the monday should be
mktime(0,0,0,0,<7*x>-$wDay+1,) {the 'N' parameter returns 1 for monday, 6 for sunday}
hope this helps
//To calculate 12 th Monday from this Monday(2014-04-07)
$n_monday=12;
$cur_mon=strtotime("next Monday");
for($i=1;$i<=$n_monday;$i++){
echo date('Y-m-d', $cur_mon);
$cur_mon=strtotime(date('Y-m-d', strtotime("next Monday",$cur_mon)));
}
Out Put
2014-04-07
2014-04-14
2014-04-21
2014-04-28
2014-05-05
2014-05-12
2014-05-19
2014-05-26
2014-06-02
2014-06-09
2014-06-16
2014-06-23

Categories