A Need To Check For Daylight Saving Time - php

What i am trying to archive is what time exactly a post was posted based on the users default timezone via there IP.
What i am worried about is daylight saving time so say if it's 1:46PM now then if daylight saving time in effect it might still post a update as 1:46PM instead of the exact time 3:46PM
The question is does PHP automatically check against that? or is there anything I need to do to see if daylight saving is in effect or not
$timezone = '+0:00';
$timezone = preg_replace('/[^0-9]/', '', $timezone) * 36;
$timezone_name = timezone_name_from_abbr(null, $timezone, true);
date_default_timezone_set($timezone_name);
echo date('D d M Y H:i:s');
Thanks :)
Just checking as everything needs to be 100% accurate

The answer is yes, PHP can give you the precise time based on timezone, regardless of DST. For example, if a user's IP tells you that they're in New York, you could do
$date = date_create('now America/New_York');
to create a DateTime object with the current time in New York.
echo $date->format('h:i:s');
Incidentally, DST is currently in effect, and this code prints the correct current time of 12:21:32.
EDIT
In response to your follow-up question, yes, the time that you save is the time that you will retrieve. For example,
$timestamp = (int) $date->format('U');
would save the absolute unix time of 12:21:32 (or whenever you run this code), regardless of timezone or DST. Another DateTime object will yield the same time:
$retrieved = new DateTime;
$retrieved->setTimestamp($timestamp);
echo $retrieved->format('h:i:s'); // outputs '12:21:32'
Hope that helps.
EDIT 2
To answer your next question, it is indeed possible to adjust a DateTime you've saved to a different timezone. First, set your script's default timezone to UTC.
date_default_timezone_set('UTC');
Then, you can save your timestamps as shown above (except, don't specify a timezone), and when you retrieve them, you can adjust them to where your users are:
echo $retrieved->format('h:i:s'); // Outputs UTC time of 5:21:32
$retrieved->setTimezone(new DateTimeZone('America/New_York'));
echo $retrieved->format('h:i:s'); // Outputs correct New York time of 12:21:32
Even after DST ends, this code would still display 12:21:32 (or, again, whatever time at which you run it)
Hope that helps, again!
EDIT 3
To address your most recent question, you can always just adjust the DateTime object based on the user's settings. For example, if they decide to override DST to off, then you should
// Change your default timezone to that of your user
date_default_timezone_set('America/New_York');
// Check for daylight savings time with date('I')
if (date('I', $timestamp) == 1) $retrieved->modify('-1 hour');
And that should do it!

Related

Setting PHP DateTime doesn't appear to be observing TimeZones

I'm fairly new to PHP so forgive me if this is a stupid mistake that I haven't spotted
I've run into a problem where in our current system where we currently used strtotime and it was returning our date an hour ahead than it actually was set. E.g 1:15pm became 2:15pm when I set the timezone to be European rather than GMT.
I read that strotime had this problem but I can't get it to observe a different timezone if I try and set it.
So I tried working with PHPs DateTime instead.
The user enters the time and they select it as 1:15PM however we want to store it as 13:15. So I did this:
$t = DateTime::createFromFormat('h:i A', $venue['startTime']);
$t_24 = $t->format('H:i:s');
Then I try and create my Date object
$d = DateTime::createFromFormat('d-m-Y H:i:s', $venue['startDay'] . ' ' . $t_24);
$d->setTimezone(new DateTimeZone('America/New_York'));
echo ' ' . $d->getTimestamp();
Trying to set the timezone after the object is set because apparently it doesn't work if you add the timezone as the third argument in createFromFormat
My computers time is currently observing European time currently GMT+1 because we're observing daylight savings time in the UK, I select the time set on the through our system as 1:15pm and because I've set the timezone I expect the timestamp outputted equivalent to 7:15am as it's six hours behind European time, however when I convert the timestamp 1500639300 it's still equal to 2:15 PM. Probably done something stupid but can't quite figure out what? Any help would be appreciated :)
Timestamps have no time zone - they are always in UTC time. If you want to save timezone related data use another format! For example save in H:i:s, as you need it.
you can use gmdate() Function for this
<?php $current_time = gmdate('Y-m-d H:i:s'); ?>
http://php.net/manual/en/function.gmdate.php

timestamp from both date & time inputs and compare php

I've been struggling to get an exact answer for this question. There are many that are close to what I'm wanting but seem to still be just off. The application of this is to ensure that a booking can't be made for a past date.
I have a form which has an input for time & another for date. Firstly, I wan't to take both of these inputs & convert them to a timestamp.
This code returns nothing
$time_date = sprintf("%s %s", $pDate, $pTime);
$objDate = DateTime::createFromFormat('H:ia d/m/Y', $time_date);
$stamp = $objDate->getTimestamp();
echo $stamp;
So I've have tried using something like this
$pDate = $_POST['pDate'];
$pTime = $_POST['pTime'];
$full_date = $pDate . ' ' . $pTime;
$timestamp = strtotime($full_date);
echo $timestamp;
But for some reason it is returning an incorrect timestamp. (i've been using an online converter) 02/06/2014 as date & 12:23am as time, is not 1401625380. This according to the converter is Sun, 01 Jun 2014 12:23:00 GMT.
Does someone have working code for returning a timestamp of both time & date inputs?
Secondly I want to compare this timestamp with a specified one & check to see if it is greater than. I've created a timestamp for my timezone with this
$date = new DateTime(null, new DateTimeZone('Pacific/Auckland'));
$cDate = $date->getTimestamp();
echo $cDate;
and will simply have an if statement which compares the two and echos the appropriate message.
I feel as though there are multiple question on here that are ALMOST what I'm wanting to achieve but I can't manage to get them working. Apologies for the near duplicate.
Note: I'm using ajax to post form data (if this could possibly interfere).
Your second code snipped is correct. Assuming it's in datetime format (Y-m-d H:i:s).
From php manual about strtotime():
Each parameter of this function uses the default time zone unless a time zone is specified in that parameter.
Check your PHP default time zone with date_default_timezone_get() function.
To compare two dates, be sure they both are in same time zones.
For datetime inputs I personally use jQuery UI timepicker addon.
you receiving the time and date in string format - so i don't believe the ajax can interfere.
as for your question:
first of all - find out what is the locale timezone of your server. you can do it by this function: date_default_timezone_get.
if the answer doesn't suit you - you can use its "sister": date_default_timezone_set, and change it to whatever value you need (like 'Pacific/Auckland' - see the documentation there). it is also recommended to return it to the original value after you finish your stuff.
i believe fixing your locale timezone will solve your issue.

Convert GMT time to Day light saving countries Timezone

I am working on project in which i am converting the time according to user location. i.e if user belongs to ALASKA then then all the information will be shown according to his countries timezone.I did some conversion but i am getting wrong time in case of user has a Daylight timezone (DST) which changes frequently.
Here is my code snippet.
date_default_timezone_set('UTC');
$offset=$_SESSION['gmtoffset'];
echo date('Y-m-d H:i:s',strtotime(date('Y-m-d H:i:s'))-(-$offset));
So in this case how do i maintain this timezone? what is the exact way for this time related conversions?
Any guidance and idea will be appreciated.
Thanks
Here's a simple solution
Javascript:
var timeZone = new Date().getTimezoneOffset();
document.cookie="tz=" + (timeZone/(-60));
Then PHP:
if(!empty($_COOKIE['tz']) && $_COOKIE['tz']>=-12 && $_COOKIE['tz']<=13){
$offset = $_COOKIE['tz'];
$tz = timezone_name_from_abbr(null, $offset * 3600, true);
if($tz === false) $tz = timezone_name_from_abbr(null, $offset * 3600, false);
date_default_timezone_set($tz);
}else{
date_default_timezone_set('UTC');
}
I am a bit uncertain to what in particular you are asking, but hopefully this will help.
If your question is regarding detecting that the user is in the Alaska time zone, then read:
How to detect user's timezone?
If your question is about picking a time zone by country, then read:
In PHP, how can I get Timezone from offset and country?
If you are wanting to understand Alaskan time zones, recognize that there are three different legal zones, and seven different IANA/Olson/TZ time zones (that PHP can use):
http://en.wikipedia.org/wiki/Time_in_Alaska
Don't try to treat a time zone as a numeric value. See "TimeZone != Offset" in the timezone tag wiki.
If you are wanting to manipulate dates with time zones in PHP, see the example in the PHP documentation for date_default_timezone_set.
If you just want to work with UTC, then there's no reason to do anything with time zones at all. The browser can always convert UTC to and from the user's local time zone, whatever that might be. Just create your JavaScript Date objects with a UTC timestamp integer, or parse from a UTC format, such as YYYY-MM-DDTHH:MM:SSZ.
To eliminate browser inconsistencies, you might want to use a library instead, such as moment.js:
// here's one way
var m = moment('2013-05-31T12:34:56Z');
// here's another
var m = moment.utc('2013-05-31 12:34:56','YYYY-MM-DD HH:mm:ss');
// pretty much anything else you might want to do...

advice with php date and timestamps

We have a battle system where people can pick a match time to challenge another player. To create a match the user needs to pick a date. Currently a user picks the day, hour, minute, and pm/am from a dropdown list. If the user selects 5/20/2012 # 1PM, the system adds the hours and minutes from the start of the day. Here's a quick sample to get a better understanding of what I'm talking about:
$time = strtotime('today', $inputdate);
$time = $time + $hours + $minutes;
the value of $hours changes if the users selects AM or PM. It's pretty basic:
Everything was working fine until people started have timezone issues. For example, if player A creates a match at 1:PM, then player B will see the match starts at 1:PM, but he/she will have different timezones!
The problem is that I don't know the problem :/
I don't know how to fix the timezone issue. I have been creating functions in the hopes that everything will fall together, but no luck.
What I have:
User profiles have a timezone options.
A function that gets the raw timestamp and returns the formatted time based on the user's timezone.
A function that gets a timestamp and converts it to another timestamp
based on the user's timezone.
I'm lost and I can't seem to fix the issue, I can code, but right now I'm not thinking logical. I took me one hour to write this and try to explain it how I could, since I myself don't know how to make it work. Some advice is appreciated.
I need a function to convert a timestamp to UTC-5:
function input_date($timestamp)
{
global $vbulletin;
$timestamp = (int)$timestamp;
if (strlen((string)$timestamp) == 10)
{
$hour = 3600.00;
$offset = $vbulletin->userinfo['timezoneoffset'];//sample -8
$ds = (int)$vbulletin->userinfo['dstonoff'];//DST
$fluff = $hour*($offset+5.00);
$timestamp = $timestamp+$fluff+($ds*$hour);
return $timestamp;//return timestamp in UTC-5 format..
}
else
{
return 0;
}
}
Essentially everything in the database should be stored using a single timezone, preferably one which is not affected by DST. The standard option here is UTC.
If you know the user's timezone by its name, you can use that to generate your time:
// Player A creates match at 1PM Europe/London
$timezone = 'Europe/London';
$localTime = '2012-03-01 13:00:00';
// work out UNIX timestamp using that timezone (making it timezone independent)
date_default_timezone_set($timezone);
$timestamp = strtotime($localTime);
// store $timestamp in the database
// Player B views the timestamp with timezone America/Los_Angeles
$timezone = 'America/Los_Angeles';
date_default_timezone_set($timezone);
var_dump(date('c', $timestamp)); // see manual for more output formats
If you have the timezones stored as their abbreviations (e.g. "CET", "GMT"), then use timezone_name_from_abbr to get the correct timezone name.

Converting from UTC in PHP using a variable timezome

I store timestamps on my server using a simple timestamp in SQL. When I pull down that timestamp, I run it through the following function in order to format the time.
How do I add to the following function in order to convert $timestamp into whatever timezone the user is querying from?
// Returns the formatted time
function displayDate($timestamp)
{
$secAgo = time() - $timestamp;
// 1 day
if ($secAgo < 86400)
return date('h:i:A', $timestamp);
// 1 week
if ($secAgo < (86400 * 7))
return date('l', $timestamp);
// older than 1 week
return date('m/t/y', $timestamp);
}
If you have timezone name to change, you can use something like:
$date = new DateTime(date('Y-m-d H:i:s', $timestamp), new DateTimeZone('UTC'));
$date->setTimezone(new DateTimeZone('Asia/Vladivostok'));
return $date->format('m/t/y');
Where Asia/Vladivostok is the user's custom timezone.
#zerkms's method is the best way to convert timestamps to any timezone.
But if you do that every time you need to display a time, it may have a significant performance hit because you're setting up and tearing down a timezone object every time. There's a convenient shortcut, if all the timestamps on the page are going to be in the same timezone. (Which is usually the case, because users don't change timezones in the middle of an HTTP request.)
Somewhere outside of the function, do:
date_default_timezone_set('America/New_York'); // or any other timezone
It's probably a good idea to tie this into one of your session management functions, so that the same user always gets the same timezone.
Once you do this, date() will automatically start using the correct timezone, assuming that $timestamp represents a Unix timestamp. It will also automatically correct for daylight saving time. So there's no need to change anything in that function.
Use timezone_identifiers_list() to retrieve a list of valid timezones.

Categories