OK,
I have a problem. I'm setting up a site that will end up holding large amounts of client data records. Because the clients can export and import their data, I have to be able to maintain session based timezones with in the site and server.
Right now my server is set to GMT. When I run the date command on the shell I see, which is correct at time of posting.
Fri Mar 18 20:04:32 GMT 2011
Then when i do hwclock --show is gives me, again this is was correct.
Fri 18 Mar 2011 08:06:22 PM GMT
Now when i tell php to change it's timezone to GMT-4 (since that is my timezone factoring in DST)
date_default_timezone_set('Etc/GMT-4');
echo date("m/d/Y g:i:s A T");
I get 03/19/2011 00:11:35 AM GMT-5 Is is totally wrong in stead of taking 5 hours away it added 5 hours.
So then I did this:
date_default_timezone_set('Etc/GMT+4');
echo date("m/d/Y g:i:s A T");
I got 03/18/2011 4:14:56 PM GMT+4. Which is the correct time. MySQL does the same thing. It seems like both are wanting to invert the time adjustments. Am i missing something on the settings?
No I think you misunderstand the notation/syntax.
The idea is that you set + if the timezone you want to get to is west of prime meridian, and you set - it it is east of it. So it doesn't actually have anything to do with the number of hours you add or take away, rather, to go back to the example, GMT+4:
4 hours in countries that are west of Greenwich
Which is basically the eastern edge of the USA, who are a few hours behind us in England... thinking about it this way should make sense.
Related
I am working with PHP and Outlook REST API, I am able to create the events just fine except that the date I give API to create events is getting incremented by 11 hours and something is wrong with end_date also, for example if i am telling the API to create the event from 2014-03-31T15:00:00-0000 to 2014-03-31T16:00:00-0000 it ends up creating the end from 2014-04-01T02:00:00+1100 to 2014-04-01T02:30:00+1100
This is what my API URL looks like
https://apis.live.net/v5.0/9898ef90931244e8/events?name=testing_event&description=event_description&start_time=2014-03-31T15:00:00-0000&end_time=2014-03-31T16:00:00-0000&access_token=token-goes-here&method=POST
if I remove the -0000 at the end, i get the following error
{
"error": {
"code": "request_parameter_invalid",
"message": "The value of input parameter 'start_time' isn't valid. The expected formats for this parameter are the following: '1970-01-01T00:00:00Z', '1970-01-01T00:00:00.000Z', '1970-01-01 00:00:00Z'. In all cases, 'Z' is interchangeable with a time zone offset of the form: '+00:00', '-00:00', '+0000' or '-0000'."
}
}
I will really appreciate any help as I have spent hourssss trying to fix this and I am pretty much out of all ideas..
Try using Z for local time like this:
2014-03-31T15:00:00.000Z
So it would be something like
https://apis.live.net/v5.0/9898ef90931244e8/events? name=testing_event&description=event_description&start_time=2014-03-31T15:00:00Z&event_start_time=2014-03-31T16:00:00Z&access_token=token-goes-here&method=POST
It's the same time with a different time zone (the -0000 and +1100).
A while ago I posted this question at MSDN Forum and forgot about it, today i visited the question and this is the reply I got from Outlook team explaining how to understand UTC timezone, I hope this helps someone out there stuck at the same problem and I wish they included this in their documentation. This fixed the problem I was having
*The ISO 8601 format for dates can be a bit confusing. What you're seeing in your response is actually correct. The calendar service
takes your date and maps it to the time zone of the user.
"2014-03-31T15:00:00-0000" means 3 PM on March 31, 2014, with an
adjustment of 0 hours and 0 minutes to translate to UTC time. In other
words, this basically IS UTC time. The calendar service then
translates this into the local time zone of the user for whom you are
creating the event. "2014-04-01T02:00:00+1100" means 2 AM on April 1,
2014, for whatever time zone your user is in. To translate back to
UTC, you need to SUBTRACT the offset from the local time. So 2 AM,
April 1, 2014 in your time maps to 11 hours earlier UTC, which is 3 PM
March 31, 2014 (what you entered).
If you're using Z, that means that you are essentially specifying a
UTC time. So to get the desired time for your event you need to take
your desired time and figure out what the corresponding UTC time is.
So if the UTC offset of your user is +1100 you would need to subtract
that offset from the local time of your event to calculate the UTC
time. In your case I believe this would be 2014-03-31T04:00:00Z. This
is actually something that's best left to code instead of trying to
figure out how to do yourself. If you take a look at the "Creating
Calendar Events" sample at http://isdk.dev.live.com it shows you how
to do this in JavaScript - maybe there's a PHP equivalent.*
In my application I'm trying to calculate the time left until midnight GMT (UK time). At the moment I'm doing this:
$now = new DateTime();
$timeToMidnight = $now->setTimezone(new DateTimeZone('Europe/London'))->diff(new DateTime('tomorrow'))->format('%h hours, %i minutes and %s seconds');
The code is working, however it seems to be one hour behind (using GMT -1). At the moment the time is 11:49PM and the output is this:
1 hours, 10 minutes and 36 seconds
I've double checked my php.ini and I also have that timezone set as GMT:
date.timezone = Europe/London
This is also confirmed by checking phpinfo().
What gives? Why isn't my application using the correct timezone?
I tested this on Linux PHP 5.5.5, with Europe/London set as the timezone in php.ini. I actually set the clock back four hours to do this, too. The minimal code I used to reproduce was:
$d = new DateTime('tomorrow');
echo $d->format('c e');
The (correct) output was:
2013-10-27T00:00:00+01:00 Europe/London
I am going to look for a bug in PHP or a bug in the timezone data. To find out which, we'll see what some other program makes of midnight in London tonight. Epoch Converter tells me this should have a Unix timestamp of 1382828400. To double check that timestamp, I ran in PHP:
$d = new DateTime('27-10-2013');
echo $d->format('U');
It also returned 1382828400. So, let's see what it's supposed to show...
TZ=Europe/London date --date="#1382828400" +%c
The output was:
Sun 27 Oct 2013 12:00:00 AM BST
Correct! So tzdata is fine. So let's look at PHP.
I ran your sample code, along with the date command, and got the following output:
1 hours, 29 minutes and 53 seconds
Sat Oct 26 21:30:07 UTC 2013
Sat Oct 26 22:30:07 BST 2013
This is, of course, correct.
I think at this point we have ruled out bugs in both tzdata and PHP, and need to look at configuration issues and programmer expectations.
First, as I noted previously, Europe/London is not UTC, which has no concept of summer time and thus does not change twice per year. Since it doesn't cause such problems, it's a best practice for servers to run on UTC, regardless of what time zone their users are in, and a best practice for programs to use UTC internally and then convert to/from local time zones for display and user input only.
My best guess is that your server's running PHP is actually set to use UTC and not Europe/London as its default time zone. This is the only configuration in which I could reproduce your issue. The results of that test were:
date.timezone = UTC
2 hours, 24 minutes and 36 seconds
Sat Oct 26 21:35:24 UTC 2013
Sat Oct 26 22:35:24 BST 2013
Going forward, you should work in UTC (and with Unix timestamps) wherever practical, and convert to local time as early in processing user input, and as late in displaying it, as you can. An edge case like this one, where summer time is about to end, may be an exception, but you have to be extra careful to ensure that each new DateTime object you construct has the correct time zone set when you construct it, and also be aware that they will have issues like this.
See also the huge and informative Daylight saving time and time zone best practices
Finally, to "fix" your code, let's do this:
$tz = new DateTimeZone('Europe/London');
$now = new DateTime('now', $tz);
$midnight = new DateTime('tomorrow', $tz);
$timeToMidnight = $now->diff($midnight);
echo $timeToMidnight->format('%h hours, %i minutes and %s seconds');
I'm developing a website where I have to deal with different possible timezones from the users. This becomes a great problem since the website hosts time-delicate events like auctions.
All dates/times on the server are in UTC. Database stores everything in UTC timestamps. PHP default timezone is set to UTC too (date_default_timezone_set('UTC');).
Now, my problem is how I should interact with the users, whether I'm only showing a date or, more important, I'm reading a date/time from user input.
A concrete example:
An auction has a deadline, which I store in database as UTC.
When I view the auction on the website, a javascript timer uses a Date object to calculate the remaining time. It automatically converts the timezone to GMT+0100 (my local timezone). So if the deadline is '2013-08-08 10:46:08' (UTC), the javascript date object will return Aug 08 2013 11:26:15 GMT+0100 (GMT Standard Time).
If the current time is greater than 11:46:08 then the timer says that the remaining time is 00:00 (which is correct).
But if I try to insert a bid, the server accepts since the condition on the MySQL INSERT evaluates to true:
INSERT INTO Bids ... WHERE ... AND auction_deadline > NOW() ...
( because auction_deadline = '2013-08-08 10:46:08' and NOW() = '2013-08-08 10:26:50')
All this mumbo jumbo of timezone melts my brains. What am I missing here? I'm almost certain that storing all dates/times in UTC inside the database is the best. I just can't think crystal clear how do deal with it between the user and the database.
Your problem doesn't involve timezones at all, just the fact that clients can turn their clocks or have their clock skewed considerably. For that the fix is to poll the server every once in a while for an offset fix to use in calculations.
In fact, you don't even need date objects. There is a certain universal instant in time when the auction ends. Let's say it is 1375960662823. Right now, the universal instant in time is 1375960669199, so from that we see that the auction ends in 6 seconds (1375960662823 - 1375960669199 ~ 6000 ). It will end in 6 seconds regardless if I am in Morocco or Japan. Do you understand it yet?
To generate these numbers, on the client side you can call var now = Date.now() + skewFix where skewFix is the correction that needs to applied in case client has time skew or manually set their computer to wrong time.
In PHP, you can generate it with $now = time() * 1000;
This is rather a typical subject yet very complex for most to understand. First thing, you never mention the DAYLIGHT SAVING. yeah I am increasing your tension :).
Now let us see how we can do this. You did a good job by saving the Time in UTC. Now, I hope you have registered members and that each member has ability to set their preferred timezone, otherwise you will show Server' timezone based time to them.
When you through "start time" to user you must send them after converting UTC time to their time, similarly when you accept TIME from browser be it user action or javascript you need to convert that time to UTC considering the fact that user is that time zone that he select for his profile.
Hope that clear the idea on where you are going wrong? Please read through day light saving as that will play an important role too when you move ahead with other logic on same.
EDIT:
You can use javascript's Timezone offset, for auto submission and user input based on his settings.
Date in JavaScript uses local timezone. You should get UTC time for the user and send it to the server
new Date
Thu Aug 08 2013 17:00:14 GMT+0530 (India Standard Time)
(new Date("Thu Aug 08 2013 17:00:14")).toUTCString();
"Thu, 08 Aug 2013 11:30:14 GMT"
This will resolve the timezone issue between the server and client.
You said
( because auction_deadline = '2013-08-08 10:46:08' and NOW() = '2013-08-08 10:26:50')
In MySQL - NOW returns the current time in the server's local time zone (docs).
You probably want something like UTC_TIMESTAMP which returns the current time in UTC (docs).
Also - you probably shouldn't accept any input time from the client JavaScript at all. Only trust your own clock. When a bid is placed, use the time on your server in MySQL or in PHP. Don't accept it as input.
You can do the following
once page is loaded, send an ajax request to server with timezone offset of user. You can get timezone offset using the following code.
var curdate = new Date()
var offset = curdate.getTimezoneOffset()
offset is timezone offset in minute.
I think it will help.
everytime when you get the date from the clientside, you can use the getUTC to convert to UTC date ie:
var todayDate = new Date();
var todayDateInUTC = new Date(todayDate.getUTCFullYear(), todayDate.getUTCMonth(), todayDate.getUTCDate(), todayDate.getUTCHours(), todayDate.getUTCMinutes(), todayDate.getUTCSeconds());
so right before you insert the bid date to database, use the getUTC functions to convert it into UTC format.
OK. So I have been trying to implement a timer. Now a very weird thing is happening and I can't understand why ?.
Basically I am trying to find the difference between the last access and the current time. I am storing the time of last access in the database. This value is according to the server time. But when I try the time() function of php it shows me values which are 5-6 hours behind the time that I have in the database.
For example: here is my code :
$t1= strtotime($played_row->timer); // Time from the database with CURRENT_TIMESTAMP
$t2= strtotime("now"); // Get the current time
It shows Year: 2012 Month: 01 Day: 21 - 05:28 pm for t2
and Year: 2012 Month: 01 Day: 21 - 10:28 pm for my timestamp values.
Can anyone tell my why is that ?
P.S: I am running the code on my computer itself.
At a guess I would say that your database and PHP are using two different timezone offsets.
Most likely this is a timezone issue: if you are in the Eastern timezone, you are 5 hours away from UTC right now. If one sytem is returning local time and another is returning UTC this is what you will see.
Try using date_default_timezone_set() to set the timezone in PHP that is used in your database.
date_default_timezone_set — Sets the default timezone used by all
date/time functions in a script
Alse see date_default_timezone_get() how to get ini-set timezone.
I have a site that has list of stores in different countries ( different time zones ), and it should display when store is OPEN or CLOSED by working hours.
I have javascript that gets DEFAULT timezone GMT offset when daylight saving isn't set, put it inside mysql, and that part works correctly.
My timezone is GMT+1 ( and now it's daylight saving active, so it's +1 hour now )
I use php to change zone using this:
date_default_timezone_set('Etc/GMT+1');
echo date('h');
Time here: 10 PM
GMT time: 8 PM
And this code return: 7 PM
So it's like it instead increasing by 1, it decrease, and plus there is no daylight saving...
Can someone tell me what happen here?
Is it php bug or something wrong on server?
Thank you...
I'm currently chuckling because I recently had a similar problem. Unfortunately Etc/GMT timezones are deprecated. They break. My personal recommendation? Just use HH:MM or set it by the city (cities don't require daylight savings time adjustments!)
Perhaps date('I') might help in this situation.
Unless there is an option to define a look-up list [GMT offset] - [time zone name]. Then it will be possible to adjust time zone using DateTime\DateTimeZone classes.