Turning TIMESTAMP SQL into 12 hour time - php

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.

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

Faster to use MySQL's CURDATE() or PHP's date()?

Is it faster to use the mysql query:
SELECT CURDATE() as today
or the PHP statement:
$curdate = date('Y-m-d');
Does the same answer apply to using date() VS MySQL's NOW() and CURTIME()?
If you're simply doing the query to get a date into a PHP script, then use the PHP function. In both cases, PHP and MySQL will call the system clock, mangle that time value into the formatted string, and return it. The MySQL version will have the added overhead of query parsing/compiling, and the roundtrip from PHP->MySQL->PHP. And if you're talking to MySQL via TCP socket, you've got added overhead of building/sending/receiving a TCP connection and packets.
On the other hand, if you're using that data value within a query, you'd be better off keeping it within MySQL. For instance, by random chance, you may start a script immediately before midnight, so that PHP generates "May 24/2011 23:59:59.999" for its timestamp, but the query doesn't execute in MySQL until "May 25/2011 00:00:00.001", so now the dates don't match.
It really depends.
It's almost always faster to keep a functions result inside its native habitat.
If you're going to use the date inside php, use the php date() function.
If you're going to use the date in a query use the MySQL NOW() function.
If php and MySQL run on different machines, definitely keep the data inside each machine for as long as possible. The roundtrip on the network will dwarf all other considerations.
It a good rule of thumb to strive for the minimum amount of network traffic.
if it is an INSERT statement it's better to use the mysql built-in functions but if it's a SELECT, it faster to use the php function 'date();'.
If the question is "in the PHP app, should I get the current date through mysql_query('SELECT CURDATE() as today'), or with $curdate = date('Y-m-d')?", then definitely use the PHP statement - the overhead for database roundtrip alone will dwarf that one call to a simple built-in PHP function (plus network latency if appserver != dbserver), that's not to mention the additional code you'll need to get the db result back (mysql_fetch_*() et al.).
You can try this at home ;) and measure the difference (which I would highly recommend), but IMHO date will be faster every time, barring some crazy convoluted scenario.
The PHP one is faster. Issuing a query to MySQL just to enquire as to the current date/time entails a round trip of data between PHP and the running MySQL server, which is considerably more work for the system than just PHP doing it itself.
Whichever method causes the least communication between the two platforms will be the faster one.
If the result of the statement is to be updated or inserted into the database, use CURDATE().
If the result is to be used in PHP only, use date().

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.

Categories