How to store NSDate to DATETIME with **TIME ZONE**? - php

How to format the date string to get the timezone information stored in a MySQL DATETIME field? Does DATETIME store timezone information at all?

No, neither DATETIME nor TIMESTAMP data types store tz data.
TIMESTAMP values are translated from the current session time zone to UTC upon storage, and translated back to the current session time zone.
What's the current session time zone? Read this.
http://dev.mysql.com/doc/refman/5.5/en/time-zone-support.html

Related

Formatting MySQL / Server timestamp with php?

I have a created a timestamp in MySQL that changes when an account is updated by a users, and this timestamp is echoed on the page. However it is displaying the server time rather than my local time. I can't set the timezone in MySQL, I tried. What is another way to change this, and how can it be implemented?
The problem with timestamp datatype is that
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.
So, it does not really matter what your timezone setting in php is, you need to set either mysql's timezone on a session basis using
SET time_zone = timezone
command, or you need to store the timezone of the client along with the timestamp and adjus the value based on the stored timezone. I would use the latter approach, since a client technically can change timezones and if the client access the timestamp data from a different timezone, then different data will be returned by mysql.
When echoing from a database add in some "filters" seemed to do the trick
<?php echo $row['field name']; strtotime(date("Y-m-d", 1310571061)); ?>
Without the above code it displayed the timestamp as: 2016-02-09 00:00:00
With the above code it displays thus: Tuesday, February 09, 2016

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

Change timezone without changing the value of a DateTime object

Here's the scenario - I have the default timezone in PHP set to UTC. All but one date/time that I work with are set to the current UTC time; when displayed later on, I set the timezone for that particular user and the date comes out in their timezone. Works great.
Except I have one date/time that the user can enter on a form. It comes in as "YYYY-MM-DD HH:MM" in 24 hour time (example: "2014-09-18 17:00"). The user is naturally setting this time in their timezone, not UTC.
If I create a new DateTime object with the input value, it saves in UTC, so when displayed later it's off by several hours (depending on the original timezone). If I set the timezone on the new object, it alters the value, assuming, again, that the input value was UTC.
I've done some Googling but have found nothing in regards to PHP (several answers for C# exist that I've found). Is this possible with the DateTime object (or with Carbon)? Am I stuck with doing a manual addition/subtraction of hours based on the users current timezone to place it in UTC first?
You must set timezone when creating DateTime object, and not when it is already created; then change DateTime object to UTC timezone and save it to you db:
# create DateTime based on user timezone
$dt = new DateTime('2014-09-18 17:00', new DateTimezone('Australia/Sydney'));
# change time to UTC timezone
$dt->setTimezone(new DateTimezone('UTC'));

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)

TIMESTAMP vs. DATETIME for `created` and `updated` columns

I'm using PHP/MySQL and I've always used DATETIME to store created and updated values, but I'm thinking there may be a better way.
Should I be using TIMESTAMP instead, and if so, why?
The documentation states:
TIMESTAMP values are converted from the current time zone to UTC for storage, and converted back from UTC to the current time zone for retrieval. (This occurs only for the TIMESTAMP data type, not 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 described in Section 9.6, “MySQL Server Time Zone Support”. 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.
So you may want to use TIMESTAMP if you want your date/time stored in UTC instead of in the current time zone.
Timestamps are stored in UTC time in the database. Then, depending on your timezone setting, any time you fetch it it will automatically adjust the offset appropriately. If you are concerned with setting timezones for your application then definitely go with Timestamps.

Categories