mysql ORDER BY "month" with unixtime - php

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.

Related

PHP/Oracle: Time representation

Disclaimer: I'm fully aware that the best way to represent date/times is either Unix timestamps or PHP's DateTime class and Oracle's DATE data type.
With that out of the way, I'm wondering what the most appropriate data types are (in PHP, as well as Oracle) for storing just time data. I'm not interested in storing a date component; only the time.
For example, say I had an employee entity, for which I wanted to store his/her typical work schedule. This employee might work 8:00am - 5:00pm. There are no date components to these times, so what should be used to store them and represent them?
Options I have considered:
As strings, with a standard format (likely 24-hour HH:MM:SS+Z).
As numbers in the range 0 <= n < 24, with fractional parts representing minutes/seconds (not able to store timezone info?).
As PHP DateTime and Oracle DATE with normalized/unused date component, such as 0001-01-01.
Same as above, only using Unix timestamps instead (PHP integer and Oracle TIMESTAMP).
Currently I'm using #3 above, but it sort of irks me that it seems like I'm misusing these data types. However, it provides the best usability as far as I can tell. Comparisons and sorts all work as expected in both PHP and Unix, timezone data can be maintained, and there's not really any special manipulation needed for displaying the data.
Am I overlooking anything, or is there a more appropriate way?
If you don't need the date at all, then what you need is the interval day data type. I haven't had the need to actually use that, but the following should work:
interval day(0) to second(6)
The option you use (3) is the best one.
Oracle has the following types for storing times and dates:
date
timestamp (with (local) time zone)
interval year to month
interval day to second
Interval data types are not an option for you, because you care when to start and when you finish. You could possibly use one date and one interval but this just seems inconsistent to me, as you still have one "incorrect" date.
All the other options you mentioned need more work on your side and probably also lead to decreased performance compared to the native date type.
More information on oracle date types: http://docs.oracle.com/cd/B19306_01/server.102/b14225/ch4datetime.htm#i1005946
I think that the most correct answer to this question is totally dependant on what you are planning to do with the data. If you are planning to do all your work in PHP and nothing in the database, the best way to store the data will be whatever is easiest for you to get the data in a format that assists you with what you are doing in PHP. That might indeed be storing them as strings. That may sound ghastly to a DBA, but you have to remember that the database is there to serve your application. On the other hand, if you are doing a lot of comparisons in the database with some fancy queries, be sure to store everything in the database in a format that makes your queries the most efficient.
If you are doing tasks like heavy loads calculating hours worked, converting into a decimal format may make things easier for calculations before a final conversion back to hours:minutes. A simple function can be written to convert a decimal to and fro when you are getting data from the database, convert it to decimal, do all your calculations, then run it back through to convert back into a time format.
Using unix timestamps is handy when you are calculating dates, probably not so much when you are calculating times though. While there seem to be some positives using this, such as very easily adding a timestamp to a timestamp, I have found that having to convert everything into timestamps to calculations is pesky and annoying, so I would steer clear of this scenario.
So, to sum up:
If you want to easily store, but not manipulate data, strings can be
an effective method. They are easy to read and verify. For anything
else, choose something else.
Calculating as numbers makes for super easy calculations. Convert
the time/date to a decimal, do all your heavy hiting, then revert to
a real time format and store.
Both PHP's Datetime and Oracle's Date are handy, and there are some
fantastic functions built into oracle and PHP to manipulate the
data, but even the best functions can be more difficult then adding
some decimals together. I think that storing the data in the
database in a date format is probably a safe idea - especially if
you want to do calculations based on the columns within a query.
What you plan to do with them inside PHP will determine how you use
them.
I would rule option four out right off the bat.
Edit: I just had an interesting chat with a friend about time types. Another thing you should be aware of is that sometimes time based objects can cause more problems than they solve. He was looking into an application where we track delivery dates and times. The data was in fact stored in datetime objects, but here is the catch: truck delivery times are set for a particular day and a delivery window. An acceptable delivery is either on time, or up to an hour after the time. This caused some havoc when a truck was to arrive at 11:30pm and turned up 45 minutes later. While still within the acceptable window, it was showing up as being the next day. Another issue was at a distribution center which actually works on a 4:00AM starting 24 hour day. Setting up times worked for the staff - and consolidating it to payments revolving around a normal date proved quite a headache.

What datatype should I use to store time() in MySQL for my application?

I plan to capture the start and end of user initiated activities on my website using time() in php. I'm not sure if this is the best way to capture start/end times. Anyway, the data will be stored in MySQL, but again I'm not sure what datatype I should use.
Based on the answers I've read on stackoverflow, the datatype used depends on the purpose of the application.
Purpose of the application
At it's simplest, I want to record start, stop (and duration) of an
activity. Probably using time().
At it's most complicated I'd like to plot statistics based on when
the user did a certain activity, how much time they spent doing the
activity (in total), and when they were the most successful/least
successful etc, etc. (all based on the start/end times) Something to
keep in mind. The users will be from all over the world.
MORE INFO
If an activity is repeated a new record will be made for it. Records will not be updated.
At first, I had planned on storing unix timestamps in MySQL (as an integer datatype?), but from what I understand this is a bad idea, because I will lose a lot of MySQLs ability to process the information. If I store the information as DATETIME, but then move the server, all the times will change based on the local time of the server. Something I found confusing was that TIMESTAMP in MySQL is not the same as a unix timestamp- which is what I would be getting if I used time().
I'm aware that the unix timestamp can only hold dates up to 2038 for some systems, but that isn't a concern (at the moment).
Question: Should I use time() to capture start and end times for user initiated activities? Based on the purpose of the application, what datatype should I use to store the start and stop of user initiated activities?
THANKS
Thanks for the answers everyone. TBH I'm not convinced either way yet, so I'm still doing some research. I chose the TIMESTAMPS option because I really would like to store my information using UTC (GMT). It's a pity though that I will lose out on some of MySQLs inbuilt time functions. Anyway thanks again for your answers.
If you're going worldwide, MySQL's TIMESTAMP is almost universally a good choice over DATETIME, since it stores the time as UTC instead of local time so DST changes won't cause you problems if analyzing in multiple time zones.
Having a non DST changing time zone as a base can be a life saver, converting between multiple time zones with different DST changeover dates can really cause problems, consider for example having a timestamp during the hour that happens twice in a change from summer- to winter time.
Use DATETIME to store the time and use date('Y-m-d H:i:s') to get the current time to store it. When you fetch this value, you will get the time in this format.
To convert it to a timestamp, use $timestamp=strtotime($fetchedValue) To display this in another format use date('H:i',$timestamp). Read about formats from date manual of php
TIMESTAMP can only store values after Jan 1 1970, since it stores timezone data.
So if you are trying to store a date before Jan 1 1970, its better to use DATETIME.
Frankly, TIMESTAMP is useful only if you are actively syncing raw data between two machines with different timezone

php date_default_timezone_set time() VS mysql now()

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.

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.

Turning TIMESTAMP SQL into 12 hour time

I am writing an app that allows people to schedule things for certain times and then displays them. The time of the event is stored in the database as an SQL TIME, because there are things I'm doing in the DB that need this structure.
However, on the output page I want the time to be in 12:00 am/pm format, but I don't want to run a conversion script every time I step through the database output loop.
I don't want this:
while (database loop){
convert to clean time
output event info, with clean time
}
because I think it is too much strain and unneccesary. Is there a way to do this better short of storing the time in the db twice (once in 24 hour and once in 12)?
You do not state which DBMS and which platform, but most modern ones would have some sort of CONVERT or CAST function that you could use, either at the DB level, or while processing your output.
for sql server use convert with style 100
select convert(varchar(30),getdate(),100)
Feb 6 2009 1:44PM
The output page is your presentation layer. Don't mix up presentation issues into the database layer. Especially don't force a denormalisation just for presentation's sake.
i dont want to run a conversion script every time i step through the database output loop
Whyever not? Depending on what language you're using it shouldn't be any more work than just sending the time through a strftime() operation before plonking it onto the page. It's not going to be slow.
Converting times and dates on the database takes very little resource and will be much faster than doing it in PHP or JavaScript. I would use the date and time functions provided by your database e.g. DATE_FORMAT(date,format) in mySql.

Categories