php date_default_timezone_set time() VS mysql now() - php

I am developing online shopping system. Only UK customers can place an order from the website.
I am wondering which is best method for me?
date_default_timezone_set("Europe/London");
$time = time();
or
using mysql function now() ?
Sometime customer can select a time for delivery or collection.
Note: In the UK, we change the time twice a year!

If the time is being sent to the database, use NOW(); less overhead, and the server time zone is hopefully always going to be correct and less mutable than PHP's time zone. If we're just talking about display, without actually doing database work, then it's excessive to run a mysql query solely to get the time.

In PHP I usually do the following:
date_default_timezone_set('GMT');
And then, upon connecting to the MySQL server, I execute the following query:
'SET time_zone = "' . date_default_timezone_get() . '";'
This makes sure that both PHP and MySQL are using the same timezone, so NOW() and date('Y-m-d H:i:s') should both yield the same result.
Regarding the daylight changes, they shouldn't be a problem (if you keep your software updated).

One massive consideration in this question is whether the times are the same between PHP and MySQL?
If the two are running on the same machine then the answer is likely to be 'yes', but if they're on separate machines then there's a strong possibility that they may in fact be different.
Consider a scenario where dates are written to a database using the MySQL NOW() function, and separately you have a query asking for all entries made in the last 24 hours, building the time in the query using the PHP date functions. If the time on the PHP server is out of sync with the SQL server, it opens up the possibility that you may miss records from your report (or get them doubled-up on consecutive days, depending on which way out of sync they are). This could lead to deliveries being missed, etc.
The upshot of this is that you should be careful to be consistent with your use of dates (and in particular datetimes). It doesn't really matter whether you use the PHP or MySQL date functionality, but you should try to use the same platform to query as you used to update.
Of course, it's not always going to be critical in this way, and you can be pragmatic about it - sometimes it's just too inconvenient to go back to the DB, just to find out what the time is! But when it's important, you should be careful.
Naturally, if the two systems are on the same server, this is a non-issue, but you shouldn't assume this will always be the case.

Related

How to deal with PHP + MySQL timezones and MySQL GROUP BY [date] queries?

I'm working with Drupal 7, PHP, and MySQL, and trying to get my head around timezone issues when querying from the MySQL database.
Drupal handles dates pretty well out of the gate: all dates are stored as UTC timestamp int's in the db, and timezone conversion happens on a per-user basis via a timezone setting in each user profile, using PHP 5's built-in timezone capabilities (so each time a PHP script is run the script's timezone is set to the current user's timezone).
So this is all fine and dandy and fairly painless as long as we stick to PHP.
Things start to get tricky when we bring in MySQL, since there doesn't appear to be a way to perfectly synchronize the current PHP script timezone with a given MySQL query. It seems like best practice dictates handling ALL timezone conversion in PHP: only ever querying the database for the raw timestamps, and then converting in PHP as necessary.
This seems reasonable in most cases (even if a bit slower at times), but what am I supposed to do with MySQL GROUP BY [date] queries? For instance, I'm building a module to handle analytics, and frequently want to do things like:
GROUP BY YEAR(FROM_UNIXTIME(u.created)), MONTH(FROM_UNIXTIME(u.created))
So we run into the timezone issue...
Possible solutions that have come to mind:
Hard-code a timezone: Use date_default_timezone_set() within my module to insure that the PHP timezone is always set to the system timezone (so MySQL timezone = PHP timezone). In other words, the analytics timezone will be hard-coded, rather than respecting the timezone of the user viewing the analytics. This really isn't ideal, since we want users in multiple timezones to be able to access the analytics using their timezones. Also, date_default_timezone_set() seems to mess Drupal up, as it sets the timezone for the entire script, instead of just within a particular function...
Forget about using GROUP BY in the queries: just fetch all the raw data from the db (be there tens or hundreds of thousands of rows), then group the results by date in php using for loops... this solution seems like it would be significantly more resource intensive, slower, and somewhat ridiculous.
So I guess what I'm asking is, have I missed something? Is there a best practice here that I'm not aware of?
Thanks a ton for any help!
I would consider an approach such as this
SET time_zone = '+02:00';
http://dev.mysql.com/doc/refman/5.5/en/time-zone-support.html
And have
GROUP BY FROM_UNIXTIME(u.created, '%Y-%m');
Since FROM_UNIXTIME bases it's time on time_zone, this should give desired result.
To undo the time_zone change afterwards, consider saving SELECT TIMEDIFF(NOW(), CONVERT_TZ(now(), ##session.time_zone, '+00:00')); first and then set it to saved value afterwards.

Comparing user inputed string with curdate in mysql

I'm working on a php/mysql app that strongly rely on a correct date. To ensure that the date inserted into the database is always correct and since php/mysql date functions rely on the system clock, i decide to ask users to input the current date in the date form field and then compare it with the current date in the database using CURDATE() before inserting any data into the database.
I don't know if this is the right way to go about it or is their a better solution to enure date integrity?
(Upgrading to an answer)
One would typically rely on the system clock to be correct; it is something that is much more under one's own control than user input, which can be either deliberately or accidentally incorrect.
I would recommend using CURDATE() as a value in your INSERT statement, and undertaking measures such as running a Network Time Protocol client to keep your system clock correct. Most modern operating systems not only include such software by default, but they are typically configured and working out-of-the-box.
If your system is standalone and unable to update its time from the network, you might consider any combination of: receiving a time signal from another source (such by radio, like the NPL signal); verifying the system clock periodically (especially on boot); monitoring the CMOS battery and ensuring that it is replaced in a timely fashion; or employing rechargeable batteries.

PHP + MySQL Building server timezone agnostic scripts?

When building PHP applications I always end up having trouble trying to get everything to play right with server times and timezones.
I generally have a simple timestamp-like field on most of my records that isn't updated - just static for reference purposes. I use it to track when events happened, when users registered, when comments were created etc.
I have been trying to follow the best practices of using a Datetime field to store this value. The problem is that when using different servers they often have different timezones so the datetime's don't match up even close unless I add more code to offset the differences. This can also be a problem when using MySQL replication and NOW() queries since their is often a lag.
I'm wondering if I should go back to using ints since they don't seem to care anything about timezones and only require the server clock is set. The downfall is that all those MySQL date/time functions (I never use) can't be used which might be a problem in the future. The upside is that I can cut the storage space in half by moving back to 4byte ints instead of datetimes.
People also mention that ints will only work until 2037 - why is that a problem? Who expects to be using PHP + MySQL in 2037?
Is there anything I am missing? Is it better to store reference times in an agnostic way like Unix timestamps?
I use date/time fields in all my database work but store everything in GMT. Pretty much the first opportunity my code gets it converts something into GMT, and does all its internal math in gmt, etc. The only time I convert it back out of GMT into local time is when displaying to the user. PHP has unixtime() which is GMT, plus gmstrftime and gmdate, pretty much anything you'll ever need.

mysql ORDER BY "month" with unixtime

I have some dates/events in a database, and I'd like to pull them out ordered by month (year doesn't matter) - right now all the timestamps are in unix in a column named eventDate. How can make that query?
SELECT * FROM calendar ORDER BY eventDate
Obviously that sorts them, but I want to make sure all events across all years are grouped by month - then obviously need to arrange them January, February, March, etc.
Any advice?
Thanks!
You could use FROM_UNIXTIME() function + MONTH() function.
SELECT MONTH(FROM_UNIXTIME(0));
-- 12
But there's no reason to store a unix timestamp over a real timestamp (YYYY-MM-DD HH:II:SS). RDBMS have functions to manipulate dates and if you really need the unix timestamp (I never do, TBH), you can use the UNIX_TIMESTAMP function.
There are plenty of extremely good reasons for using unix time. Good database design hugely impacts how expensive it is to run databases and website, especially successful busy ones.
The best case I know of is..
a really busy server(s) and where time data is required to be stored but the time data is actually accessed rarely compared to the number of reads and writes actually going on in the db. It takes cpu resources to do all the manipulation of that time data, So don't unless you absolutely have to.
A real life example is my own. We needed 4 front end web servers and were going to be adding more. they were old too and needed updating. looking at 6 replacement servers that would be needed it was going to cost us a bundle. decided to look about what we were doing. We now have 2 front end servers instead of 4 or 6. what it took? optimizing the database structure and queries and the code that inserted and read data from them.
One example that took your exact consideration in mind... changed 1 line of php code, changed the time column to unix instead of yyyy-dd-mm hh:mm:ss, added an index to the time column and that one operation went from 0.08 seconds to 0.00031 seconds start to finish.
The multifold impact on cpu resources was huge. the next queued up operations executed faster... etc.
That is why people have jobs as database designers... it really is important.
of course if your website is slow and not busy.. probably no one will notice.
But if you are successfull, it WILL matter.
If you've got a busy site and your servers get sluggish... look at things like this. You might not need a new box or more memmory, you just might need to clean up code and optimize the db.
Timestamps, their form and how they are used and stored DO MATTER.

Why not use MySQL's TIMESTAMP across the board?

If you need your web application to translate between timezones on a per-user basis, why not use TIMESTAMP across the board for all date/time fields? Consider that TIMESTAMP values are stored in UTC and converted to the timezone set for the connection when retrieved.
I have asked this question on IRC, read the MySQL documentation, searched Google extensively, and asked my co-workers, and I have yet to find a compelling reason to not use TIMESTAMP.
Note: I understand TIMESTAMP has a limited range of 1970 - 2038; that is not going to be an issue in my case. Also, I am using PHP with MySQL.
DATETIME is for arbitrary dates and times that you utilize in your data.
TIMESTAMP is for when you want the time to be automatically updated. If you want to know when the row was inserted/updated, use a TIMESTAMP.
Also, keep in mind that a TIMESTAMP is only stored in UTC -- it is converted to the local timezone of the server before it is transmitted back as part of a query.
In your case, you're better off using a DATETIME. If you're worried about UTC, that's fine -- just create your dates in UTC rather than using the local time. Use UTC_TIMESTAMP.
I think your answer is here:
I understand TIMESTAMP has a limited range of 1970 - 2038; that is not going to be an issue in my case.
I would be careful making assumptions about the longevity of projects especially when it comes to database schemas. Databases have a tendency to remain in place and in use long after the applications that used them have gone away.
Randalpho's answer is wrong on many facts!
Timestamps do not need to be automatically updated on creation OR updates.
Also, timestamps are translated to the CLIENT's local time, not the serever's.
Just look at the MySQL docs for datetime.

Categories