php timestamp utc - php

I have a PHP MySQL query that inserts some data into a MySQL database and it includes a timestamp.
Currently the INSERT query uses NOW() for the the timestamp column and it is saved in the database in the following format: 2012-07-24 13:13:02
Unfortunately for me the Server is not in my time zone and it is listed as America/Los_Angeles as shown print date_default_timezone_get();
I was hoping to do the following:
date_default_timezone_set('Europe/London');
$timefordbLondonEU = date('Y-m-d H:i:s', time());
and simply save into the database the $timefordbLondonEU in place of the NOW();
Is this a good way to save such data ?
Many Thanks,
Richard
[ADDED TEXT]
I changed the Type in the MySQL db to DateTime and did the following:
date_default_timezone_set('Europe/London');
$timefordbLondonEU = date('Y-m-d H:i:s', time());
It is working but Im still not getting the overall concept yet.
Assumptions based on your comments:
MySQL = Does not have a datatype UTC you simply use type INT.
Unix_TimeStamp() will save the current time or count? in UTC format such as 1343247227.
As UTC is a count from a common 0 point you can get any timezone from it. Assuming that you don't want a date before the reference 0 point in 1970.
My guess and lead on from what you have said is the best way to do it is save the time as UTC in an INT (1343247227) and then generate any time zones you want from there. Again assuming you don't need to store dates before the reference 0 point in 1970.
Equally why not store as datetime YYYY-MM-DD HH:MM:SS at a known timezone and then convert to UTC or other timezones. It all seems pretty messy =(

As #Petah said in the comments, store your times in UTC and covert them in the application as needed.
Unix timestamps are in UTC so I usually store my times in the database as timestamps. This saves the headache and confusion of first converting to UTC to insert, and then from UTC when selecting.
That is, make your time field an INT type, and use the function UNIX_TIMESTAMP() in MySQL when you insert, or get the timestamp from PHP using the time() function.
When you fetch the timestamp from the DB it will be in UTC, but when you display it in your PHP application using date(), it will display in the server timezone, or whatever you set with date_default_timezone_set.
Therefore the following two queries will work:
INSERT INTO `table` (id, time) VALUES(NULL, UNIX_TIMESTAMP());
// or
$time = time();
$query = "INSERT INTO `table` (id, time) VALUES(NULL, $time);
If you want to select it from the DB as a DATETIME, you can do this:
SELECT *, FROM_UNIXTIME(time) as dt FROM `table` WHERE 1
The resulting dt column will be in the format yyyy-MM-dd hh:mm:ss.
You can format the numeric timestamp in PHP using date()
If the PHP version you have is 64-bit, you aren't limited to the 1970 - 2036 range, PHP will support 64-bit timestamps, just make sure to use a BIGINT column in MySQL in that case.
Hope that helps.

Related

PHP & MySQL Timezones whilst supporting user-defined timezones

I'm working on something where the user can select their own timezone and the software will be able to be used by others on their sites as well but I want to make sure that the timezone within the database is always set to UTC.
Now I know how you set the default timezone for PHP, such as:
date_default_timezone_set('Australia/Sydney');
...but I'm not sure how to make sure MySQL is using UTC? ...and even once you have made sure it is using UTC I guess you would have to convert your PHP dates/times into UTC before passing it to the database?
I guess I am wondering about many different date formats such as TIMESTAMP, DATETIME & even UNIX EPOCH integer timestamps which would simply be stored as a int datatype for example.
Then there is the whole retrieving dates/times from the DB and converting it to the respective timezone and lastly how does DST come into all of this?
I know there is a lot of similar questions out there, but I guess none really answered all my questions.
MySQL's data type timestamp stores the dates in UTC. For this to work properly, MySQL uses server's time zone and does the date conversion. It converts the date from servers's current time zone to UTC for storage. This implies that the database server should never change its time zone for this feature to work properly.
When you send the data to such a database, you send the UTC time as well. The easiest way to do this is to format a result of time() according to what MySQL wants (m-d-Y H:i:s).
In PHP, when you format the date for insertion to MySQL, it's the best to use DateTime class. It lets you offset the date with the time zone information, meaning that you don't have to use date_default_timezone_set function - that can lead to mistakes.
An example of DateTime in action:
$date = '1.12.2015 13:37:37'; // Format is day.month.year hour:minute:second
// We create DateTime from custom date format, for the person who resides in Australia/Sydney time zone
$dt = DateTime::createFromFormat('d.m.Y H:i:s', $date, new DateTimeZone('Australia/Sydney');
// Now we change the date's time zone into UTC, and we can insert it into MySQL
$dt->setTimeZone(new DateTimeZone('UTC'));
// This is the formatted date-string that can be safely inserted into MySQL
$date_string_for_mysql = $dt->format('m-d-Y H:i:s');
Alternatively, you can use int type in MySQL for timestamp storage and insert result of time() but this has a huge disadvantage of not being able to use date-related functions.
for current session of mysql you can try something like
SET time_zone = timezonename;
for more details you can also look into this answer https://dba.stackexchange.com/questions/20217/mysql-set-utc-time-as-default-timestamp

Why can't I use php time() for a timestamp column?

I have a timestamp column in a db table. Saving values with:
UPDATE `table` SET `activated_at` = CURRENT_TIMESTAMP WHERE `id` = 123;
works fine.
But when I use the php function time() to get the timestamp, it doesn't work. It only works using date('Y-m-d H:i:s') for the column value. Question is why?
the column definition is:
`activated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'
I'm using the php mysql extension (and yes, I know it's deprecated, but I have to maintain some legacy code)
Since time() in php return a unix timestamp and timestamp is a datetime type and it requeires a valid datetime value.If you didnt give a valid datetime value it will be storing like 0000-00-00 00:00:00. If you want to keep your field as datetime type then you must give date('Y-m-d H:i:s') in php
Also check the documention of various date time types in mysql
time() returns a unix timestamp, but the MySQL timestamp column supports specific formats such as YYYY-MM-DD HH:II:SS. You can easily do the conversion using date for PHP or FROM_UNIXTIME in mysql.
Look here
The TIMESTAMP data type is used for values that contain both date and time parts. TIMESTAMP has a range of '1970-01-01 00:00:01' UTC to '2038-01-19 03:14:07' UTC.
MySQL converts TIMESTAMP values from the current time zone to UTC for storage, and back from UTC to the current time zone for retrieval. (This does not occur for other types such as DATETIME.) By default, the current time zone for each connection is the server's time. The time zone can be set on a per-connection basis. As long as the time zone setting remains constant, you get back the same value you store. If you store a TIMESTAMP value, and then change the time zone and retrieve the value, the retrieved value is different from the value you stored. This occurs because the same time zone was not used for conversion in both directions. The current time zone is available as the value of the time_zone system variable. For more information, see Section 10.6, “MySQL Server Time Zone Support”
*nix timestamp and MySQL TIMESTAMP is not the same... that's why you need convert from *nix timestamp to MySQL timestamp over date('Y-m-d H:i:s', $unix_timestamp)
if you want to use time() change the column type to varchar(15)

PHP, using timestamp for mysql?

I've been trying to search for a straight answer, but for some reason the answer isn't coming to me. I was wondering what is the best way to store date/time into mysql?
I researched that timestamp in mysql is good because it will update depending on timezones too.
So I've set my column name as timestamp with datatype in mysql to timestamp, but what is the best syntax for storing current date/time to that?
"INSERT INTO table(timestamp) VALUES(now())" //or use timestamp()? or is there such thing?
?
Please help, thanks!
You could use datetime datatype in your table and just store it as NOW() which will store it as YYYY-MM-DD HHHH:MM:SS
Here are some considerations:
Set the column type to BIGINT so you can store 64-bit timestamps
You can insert using the PHP time() function, or MySQL's UNIX_TIMESTAMP() function
Name your column something other than timestamp. It is a permitted word1 see last section, but its also a type in MySQL.
If you store times as a Unix timestamp in MySQL, they are stored in UTC which makes dealing with timezone conversion very easy. In a 64-bit environment, PHP can handle dates up to the year 219,250,468.
Both of these queries are the same:
INSERT INTO `table` (`time`) VALUES(UNIX_TIMESTAMP());
// or
$time = time();
INSERT INTO `table` (`time`) VALUES($time);
Then to display it in PHP:
SELECT `time` from `table` WHERE `id` = 1;
echo date('Y-m-d H:i:s e', $row['time']); // 2012-07-31 23:59:59 America/Los_Angeles
Whatever timezone is set in PHP date_default_timezone_set() will be the timezone used when you output the date in PHP.

Converting Server MySQL TimeStamp To UTC

I've been using the timeago plugin (http://timeago.yarp.com/), it has been working fine on my localhost, which has its MySQL storing its data in the UTC timestamp, which the plugin needs to work.
However, when uploading my project to the server, a different type of timestamp is appearing in it MySQL database. I'm getting a timestamp like this: "Thursday, February 24, 2011 4:29 PM" from the server, whereas I need something like this: "2008-07-17T09:24:17Z"
Any idea how to convert the timestamps using php?
Edit: The timestamps stored in the wrong format in the database are automatically generated by mysql.
Edit 2: It's a field of type "timestamp" and default set to "CURRENT_TIMESTAMP" when row is being inserted in db
You are getting a weird string for MySQL, are you sure that it is in a Datetime field?
You can get a UNIX timestamp (seconds since epoch) from MySQL with the following function, this format is widely accepted over multiple platforms:
SELECT UNIX_TIMESTAMP( table.datetime_field ) as datetime_field FROM table
Using some PHP Functions you can convert this to the format you desire:
echo date( 'c', $record[ 'datetime_field' ] );
I think this would be sufficient for your problem.
SELECT UNIX_TIMESTAMP('your_date') AS your_date; in a query and
$date('whatever_format', $timestamp_from_mysql); in php
Internally a MySQL timestamp column is stored as UTC but when selecting a date MySQL will automatically convert it to the current session timezone.
When storing a date, MySQL will assume that the date is in the current session timezone and convert it to UTC for storage.
To select a timestamp column in UTC format
no matter what timezone the current MySQL session is in:
SELECT
CONVERT_TZ(`timestamp_field`, ##session.time_zone, '+00:00') AS `utc_datetime`
FROM `table_name`
You can also set the sever or global or current session timezone to UTC and then select the timestamp like so:
SELECT `timestamp_field` FROM `table_name`
I made a cheatsheet here: Should MySQL have its timezone set to UTC?
php code
<?php
$pdo = new \PDO($yourconnectionstring);
$sql = "SELECT
CONVERT_TZ(`timestamp_field`, ##session.time_zone, '+00:00') AS `utc_datetime`
FROM `table_name`";
$stmt = $pdo->prepare($sql);
$stmt->exec();
$timeVal = $stmt->fetchColumn();
if isset($timeVal) {
$dt = new \DateTimeImmutable($timeVal, new \DateTimeZone('UTC'));
echo $dt->format(\DateTime::ATOM);
}

Convert MySQL UTC datetime to UNIX timestamp

These both correctly return the current UNIX timestamp:
SELECT UNIX_TIMESTAMP(LOCALTIMESTAMP()); #MySql
echo time(); //PHP
But I'm storing UTC_TIMESTAMPs in my database (not LOCALTIMESTAMPs).
How can I convert a UTC datetime to a UNIX timestamp using MySQL?
Note that LOCALTIMESTAMP() is a synonym for NOW(). So what you're really asking is how to get the current time and convert it to GMT and then convert to a unix timestamp to store in the db. So this will work:
SELECT UNIX_TIMESTAMP(CONVERT_TZ(NOW(), ##global.time_zone, 'GMT'));
As an aside, it's always much better to use the time and date columns of a database rather than unix timestamps. It makes querying and displaying results much easier.
Update: Are you sure you are getting what you think you are? UNIX_TIMESTAMP returns a UTC based seconds since the UNIX epoch. It does not return a MySQL DateTime type. If you have an actual UTC DateTime instance, then you can put that directly into your DateTime column of your database and don't have to use UNIX_TIMESTAMP as an intermediary. What type do you actually have that's in local time?

Categories