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.
Related
I have my Apache server and PHP set to date_default_timezone_set("America/Los_Angeles").
In MySQL I save TIMESTAMP fields with CURRENT_TIMESTAMP and some of them EXTRA as "on update CURRENT_TIMESTAMP".
Am I doing this the right way or am I loosing the whole point of TIMESTAMPS? I want the user to be able to choose their own timezone but it seems like it's saving the local timezone to the MySQL instead of a universal reference point.
Should I instead set the server timezone to UTC and in PHP date_default_timezone_set("America/Los_Angeles") or whatever the user timezone is and then save the values to the MySQL fields with something else than CURRENT_TIMESTAMP (which seems to vary depending on the php setting)?
Thank you!
Ideally you want your database to store data in UTC so that way it's not anchored to any particular geography. Incoming data from users is converted according to the user's time-zone, and anything you display can likewise be converted back to the user's preferred time-zone.
Some systems even go so far as to send UTC time over to the client in the HTML, but tag the element with something that JavaScript hooks on to and re-renders, client-side, with the appropriate local time.
It's best to have a user-specified setting that's persisted in their user record and/or session that defines what conversion, if any, should be done to the dates and times they're specifying or being shown.
It's also worth noting that TIMESTAMP fields are limited to the year 2038, so they're already living on borrowed time. It's best to use a more standard DATETIME field which has a much wider range of acceptable values.
I am working on codeigniter application which have users from different time zones. Each user has some notifications based on some dates calculation.
So what should be best way to store date into Mysql? Either timestamp or datetime?
First off, you need to be aware of the locale setting for your mysql server. You want the server to be set to use UTC as a neutral setting. Any data that is stored in the mysql server will be relative to the server's timezone setting.
Unless you are dealing with future data (beyond the year 2032) or conversely really old data, the most efficient mysql datatype is the timestamp datatype. Just be careful to turn off the automatic mysql timestamp functionality when you don't want or need it.
Internally to PHP you want to utilize the DateTime class which includes ways to convert from any one timezone to another.
The missing ingredient that has not been mentioned, is that in order for this to work for end users, you need to store their timezone, or utilize functions in the browser to read from the operating system the current timezone of their workstation.
Timezone strings can be stored, and then used after you fetch data from the server, to then convert it and show it to them relative to their timezone.
But again to be clear, all data should be stored as UTC, and this requires that the server be configured to utilize UTC. Well it's a bit more complicated than that, but you can save yourself a lot of trouble when you insure there isn't a mismatch. By the same token your web/application servers (and in fact all servers) ought to be set to UTC, and of course to sync their time using NTP. Most cloud based servers are going to do this by default.
Format doesn't matter as long as you keep your date as DataTime Object. Using PHP you can easily manipulate dates. My personal choice is using UTC offset because is easier for debug purpose. You can easier figure out if your time difference calculation is correct looking on the offset then on time zone name.
More information you will find under DataTime class.
Implementation is basically the same regardless format as long as you are using DataTime Object. This is the best way to calculate time differences in different time zones.
With datetime you get a rich set of tools for interacting with the data (including converting between timezones) and the opportunity to handle dates prior to 1st Jan 1970 and after 19th Jan 2038.
Although the same tools are also applicable to TIMESTAMP, the automatic timezone conversion can get messy.
A further consideration is that TIMESTAMP also acquires some subtle timezone conversions which get rather messed up if you move to maxdb mode or back. Indeed, datetime data will be more portable across different systems.
It does not matter as long as you are using UTC value. However, timestamps are better way to store data from different timezones as it always represents and stored as the standard time(UTC) irrespective of the timezone of client/server.
But, as you are taking the data from user's input it does not make a difference.
For the accurate standard time(UTC), you just need to convert it right according to the user's timezone.
You can retrieve user's timezone either from browser headers(which is a less accurate method) or you can ask the user himself(using a input).
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.
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.
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.