I want to make a system which displays time dependant on the timezone in a particular country. E.g. a table in my database contains country names in one field, and in the column next to it, it will contain GMT-compared timezones like -0100 or -0200.
What I need to do on the webpage then is set current GMT time ($time), and then pull the information from the database and alter $time to be GMT -1 or GMT -2.
Could someone tell me what the easiest way to do this would be please?
Thanks for any help
Edit:
So far I have this code:
<?php
$time = date("H:i:s", time());
echo $time;
echo "<br/><br/>";
$myDateTime = new DateTime($time, new DateTimeZone('GMT'));
$myDateTime->setTimezone(new DateTimeZone('Antarctica/South_Pole'));
echo $myDateTime->format('Y-m-d H:i');
?>
which seems to do the job, and I could enter into the database 'Antarctica/South_Pole' rather than the GMT-/+ time. Would this do the job OK in the long run?
Also, using this method, would Daylight saving times be worked out OK?
Using the DateTimeZone is the correct way to go about it.
If you provide it with zoneinfo keys (such as America/New_York, or Antarctica/South_Pole as in your example) Daylight Saving time WILL be factored into the result, which is not the case if you have a naive database with only the UTC offset stored.
Related
I know that questions about this topic have been asked over and over again, but all the reading just increased my confusion, so I decided to ask here.
I am working on a website where user can store Events, which are connected to a date. This date is stored in a mysql Database as type DATETIME.
So what I "just" would like to do is: Get the date from the Database and format it, but somehow, since the start of the Daylight Saving Time, ech date is shown minus one hour.
code:
$date = $item['date'] //<-- the result from the database (2015-11-27 08:15:00)
$dt = new DateTime($date, new DateTimeZone(date_default_timezone_get()));
echo $dt->format('G:i') // 8:15
The Value which was actually written in the "Date Field" of the administration form is 9:15 and that is what should be displayed.
Please correct me if I am wrong, but I think that "Summertime" seams to the common Basis. And the shift to "Wintertime" might be +1.
echo $dt->getOffset() // 3600s = 1 hour
If my assumtion is right, that offset should be zero in "Summertime", right? But that leads to the point I cannot sort out, since I am in the Timezone Europe/Berlin what itself is defined to be UTC +1
So which Offset does this getOffset() represent and how can I display the "right time"?
Thanks in Ahead!
In our application, we're currently storing date, time, and timezone separately. The date field is optional, which is why we have everything separated. For the user interface, they will specifically select a date, a time, and then a timezone. Everything is currently stored in UTC and the timezone would be an ID, which references another lookup table.
The way I understand and see it, we can display the date and time the user specified, simply by showing all three of those values without having to adjust anything. If they entered 11-30-15 6:00PM PST, that's what they'll see, formatted however we see fit.
Are there any immediate issues anyone can think of doing it this way so far?
How should I handle the time conversion? At some point in the system, it needs to understand the actual time. The system time is UTC, but if some work needs to be performed at 11:00AM PST, then it needs to know that. I'm wondering if there is an issue storing the time as UTC, but having them specify a timezone that is different. For example, the time is supposed to be PST, but is stored as UTC.
I am using Laravel with Carbon, just to provide more information. Any feedback would be great!
Store whole date,time and timezone as a single column. Convert user entered time to GMT and store in db. When you need to display time to user convert GMT to USERTIMEZONE.
function getGeneralTimeFormat()
{
return 'Y-m-d H:i:s';
}
function convertDateTimeToGMT($dtime)
{
date_default_timezone_set('GMT');
$dtzone = new DateTimeZone(getTimeZoneDateTime($_SESSION['USER_TIMEZONE']));
$dtime->setTimeZone($dtzone);
return $dtime->format(getGeneralTimeFormat());
}
function convertGMTToLocalTime($timestamp)
{
date_default_timezone_set('GMT');
$dtime = new DateTime($timestamp);
$dtzone = new DateTimeZone(getTimeZoneDateTime($_SESSION['USER_TIMEZONE']));
$dtime->setTimeZone($dtzone);
return $dtime->format(getGeneralTimeFormat());
}
I have an application that posts to an PHP script, I want the PHP script to basically grab the current time and date, and insert it into my SQL database.
I'm currently doing this by using '$time()' within PHP, and then passing that into my SQL DB. In order to retrieve the time and date back, I use 'gmdate("M d Y H:i:s", $time);'.
I have a few questions though:
When I test this, the time it saves is an hour behind, so how do I apply different time zones? (I'm currently London/England) - but that might not be the case for the user who use this application.
Where is PHP retrieving the time from? Is it local? From the server?
Within my SQL, what should I set the data type to be? Timestamp? Currently, I've set it to varchar - but with all these different date and time types, I'm not so sure? (Date, Datetime, Time, Timestamp).
This PHP is called every time the user opens the application, so I want to be able to see: 'ah, so I see this user opened the application up at 21:20 on Wednesday the 14th'.
I'm sorry if its a noob question, but theres so many time and date classes and functions for both PHP and SQL that my brain has over loaded!
For a start, PHP time gets it's time from the server it's running on.
But if you really want the time a record was inserted, you should do one of the following:
Create a field in the table of type datetime, and set the default to:
GETDATE()
This will set the time automatically without you having to do anything special.
If you need that at time of input, still use SQL:
update [tablename] set LastUpdate=GETDATE()
Doing it this way ensures that the time is exactly when the record was set.
The PHP Time() function returns the EPOCH time (Seconds since January 1 1970 00:00:00 GMT).
You can use date_default_timezone_set() along with strftime() or mktime() to convert this to the servers local time.
You could set this via your application for the user if they're in a different timezone.
I linked the PHP manual pages for each function listed above.
What about to create a DateTime Field on MySQL table Structure and use MySQL to grab and set the date with NOW()?. Let MySQL do most calculations, it will help you to optimize the response time of your PHP script.
Look into this example: http://www.w3schools.com/sql/func_now.asp
Following the example of that page, but for an UPDATE:
UPDATE orders set OrderDate=NOW() WHERE OrderId=9999
Setting Timezone will fix the issue. I guess.
$date = date_create('2000-01-01', timezone_open('Pacific/Nauru'));
echo date_format($date, 'Y-m-d H:i:sP') . "\n";
date_timezone_set($date, timezone_open('Pacific/Chatham'));
echo date_format($date, 'Y-m-d H:i:sP') . "\n";
I store times in MySQL sent from a PHP script as CURRENT_TIMESTAMP. This makes times from the wrong timezone, minus 1 hour from where I am. I'm not superuser, so SET GLOBAL time_zone = 'Europe/London'; won't work. Is there anyway I can modify the input or output query to compensate 1 hour?
This is my current sql query, sent from a form:
REPLACE INTO `order_admin_message` (`order_id`, `message`, `date_updated`)
VALUES ('$number', '$msg', CURRENT_TIMESTAMP)
And then I retreive it using:
SELECT order_admin_message.message, order_admin_message.date_updated
FROM order_admin_message
WHERE order_admin_message.order_id = $number
EDIT: To be clear, I don't want to show the user's time, just local London time (taking daylight saving into account in summer).
EDIT 2: Changed the subject to be closer to the question/answer.
In PHP, just change it for your display. Don't store locale dependent dates or times in a database. Makes conversion later on, a PITA. Just display the time/timezone you need even if you don't care about the user.
$tz = new DateTimeZone('Europe/London');
$datetime_updated = new DateTime($results['order_admin_message.date_updated']);
$datetime_updated->setTimezone($tz);
$display_date = $datetime_updated->format("M j, Y g:i A");
echo $display_date;
Use utc_timestamp instead, and convert to the timezone of the user yourself.
UTC_TIMESTAMP is the current UTC date and time, as recognised all over the world.
As long as you know where your user is and what his timezone is, you can convert it by adding the correct offset.
If you don't know what the user's desired timezone is, then you have a different problem - basically you need to find out somehow.
Use the CONVERT_TZ() function:
http://dev.mysql.com/doc/refman/5.0/en/date-and-time-functions.html#function_convert-tz
I wanted to ask if this was going to work, before I went on a full fledged refactor of how i handle dates and times.
To frame my question, here's my problem...
I store "actions" taken by the user in a history table. These actions have a timestamp on them. Users can be from all over the world, and hence have different timezones. I want to display the items in the history and show the timestamps in one's local timezone.
Also, I know I can use datetime fields and simply store UTC time formats, but I'm opting to use timestamp so i can set a default to current time.
Will this work for my problem?
My server time zone will be Los Angeles
Store timestamps as a timestamp in MySQL. My understanding is that timestamp is always stored as UTC. Records will be stored by default as creation_date OR i will explicitly set UTC_TIMESTAMP(). Effictively, all records in the db will be UTC.
When a user logs in I will grab their timezone (I store this in the db as a user setting).
For this example, lets say this person is in New York.
Here's where my question is. Will either of these work?
a) Grab the history data. All timestamps will automatically be converted from UTC to Los Angeles time. Foreach history item, convert the Los Angeles timestamp to New York timestamp and echo.
OR
b) Set the php timezone "date_default_timezone_set" to New York. Grab the history data. All timestamps are STILL in Los Angeles time by server is still Los Angeles time. Foreach history item, just echo the timestamp because the "date_default_timezone_set" will automatically convert the Los Angeles timestamp to New York.
Will option 4b work? Is there a better way to convert from the Los Angeles time to the New York time?
Is there a better way to do this in general?
You are correct, Unix timestamps are always in UTC. If you store the timestamps in your database in UTC, all you need to do to output it in local time is change the timezone in PHP to the timezone local to the user. You don't need to do any conversion on the timestamps.
<?php
$timeStampFromDatabase = 1325448000; // 01 Jan 2012 20:00:00 GMT
date_default_timezone_set('America/Los_Angeles');
echo date('r', $timeStampFromDatabase); // Sun, 01 Jan 2012 12:00:00 -0800
date_default_timezone_set('Asia/Hong_Kong');
echo date('r', $timeStampFromDatabase); // Mon, 02 Jan 2012 04:00:00 +0800
You can change your timezone on the fly and continue to output timestamps in a date format and they will be "converted" based on the set timezone in PHP. It is very easy, you don't need to do any special handling, and it doesn't matter where you set the timezone, as long as you do it before you output dates, but you can read them prior to setting the timezone.
Unfortunately, "date_default_timezone_set" was not working the way I thought it would. As per the previous example, it would work if the dates I was working with were already in unix timestamp format. However, they were formatted in "Y-m-d H:i:s" and the only thing that would change was the GMT offset, which obviously doesnt work.
After a few hours of fidgeting, here's how I was able to handle time conversions.
$datetime = new DateTime($date_to_convert);
$usertimezone = new DateTimeZone($_SESSION['timezone']); //each user has their own timezone i store in a session (i.e. - "Americas/Los_Angeles")
$datetime->setTimezone($usertimezone);
echo $datetime->format("Y-m-d H:i:s");
I suppose that I could have done the following as well:
Pseudo code
strtotime($datetime)
date_default_timezone_set($user_timezone)
echo date(format, $datetime)
the above, i think, would force the date function to handle it's logic in the given $user_timezone. in hindsight, i would have to translate every $datetime -> unix_timestamp -> $datetime_converted, which doesnt sound to be much better than what i chose to do.
Always store your timestamps in the database as UTC. This is a timezone and daylight savings independent point in time time. To display this back to the user in their timezone, simply do:
$users_timezone = 'Europe/London'; // See PHP documentation for names that can be used.
$date = new DateTime();
$date->setTimestamp($timestamp_from_database);
$date->setTimezone(new DateTimeZone($users_timezone));
echo $date->format("H:ia jS F Y");
By default, Unix timestamps are always in UTC. If we store the timestamps in our database in UTC, we just need to use the following PHP script:
<?php
$TZ_UTC = new DateTimeZone('UTC'); //-->Database Timezone;
$TZ_LOCAL = new DateTimeZone('America/New_York'); //-->Expected Local Timezone from user settings;
//--Example Database Query--
while($row = mysqli_fetch_array($result, MYSQLI_ASSOC)) {
//---If we want to show UTC timezone directy----
echo $row['action_timestamp'];
//---If we want to show LOCAL timezone from user settings----
$dateObj = new DateTime($row['action_timestamp'], $TZ_UTC);
$dateObj->setTimezone($TZ_LOCAL); //--> Here is the conversion!
echo $dateObj->format("Y-m-d H:i:s T");
}
?>