Efficient way to convert a lot of dates - PHP - php

I'm trying to prepare importer for my application.
I've a file, very simple but large .txt. It has ~250k rows, in each row I need to change few column's date format to 'Y-m-d'.
I used strtotime() and date(), but there was some problems with that and I start to use class DateTime, now everything is fine, but it takes a lot time to import it (a lot of more than when I use strtotime and date).
//script do it every row
$date= new DateTime($values[1]);
$values[1]=$date->format('Y-m-d');
$date= new DateTime($values[2]);
$values[2]=$date->format('Y-m-d');
In $values[] I have string e.g. Jul 1 2004 12:00AM
There is the more efficient way to use this DateTime class? Something like define $date once and then just change values of it? I google it and tried to do in many ways using DateTime, but found nothing interested.
I'm still try to find out what's wrong was with strtotime(), in some case it don't get right date and put into mysql table -> 1969-12-31. Main problem is I get this file from outside provider and it's run every day by cron.
It appears some of dates in file are in very strange format : 2013-01-30 15:04:30.717000000, after clean this, it start work fine and I can use strtotime which is of course faster than DateTime.

select unix_timestamp('2013-01-30 15:04:30.717000000');
-->
1359587070.717000
and
select cast('2013-01-30 15:04:30.717000000' AS DATETIME(6));
-->
2013-01-30 15:04:30.717000
That is, if this is destined to be in a MySQL database, you could store it as a string, then use the above code to convert to a TIMESTAMP or DATETIME with microsecond precision.

Related

PHP & mySQL : Date + Time Storage

I've been reading about storing and displaying dates and times in mySQL, but I don't seem to find an answer that suits my needs or I'm incapable of coding my own one. I guess being full of doubts doesn't help at all.
The thing is, I have a mySQL table with a field (text) which I would like to contain certain times and dates. At the moment I'm working with "d/m/Y H:i" format, but I'm pretty sure that's not neat. I'm using that format because it's the format I want it to be displayed on the site.
Could anyone tell me what the correct way of handling this issue would be? Maybe I have to store the date and time in another format and convert it when it's going to be be displayed on the site.
You should store them as TIMESTAMP or DATETIME (check the differences here)
and then convert them when you write or read the values, for example:
INSERT INTO table (date_time) VALUES (CURRENT_TIMESTAMP)
SELECT date_format(date_time, '%b %d %Y %h:%i %p') as date_time FROM table ...
i would say your guess would be the best way to do it. Store it in seconds since EPOCH and then convert using any multitude of ways that php offers:
take a look at this:
epoch time stamp
the epoch time stamp is valid for ANY time zone. Which makes your server location not important. You could show time for any time zone as long as your parse it correctly with php (or you could even do it client-side with JS)

What's the best way to store date and time in a MySQL database for later display with PHP?

I want to store the date and time that a user performs an action on my website into a MySQL database. I'd like to be able to do the following with ease:
Store the date and time as one field in the database
Use a built in PHP or MySQL function to generate the date-time of the action
Store the date-time based on my server's time, and not worry about user timezones.
Order By the date-time field when I query MySQL
Later, display the date-time in many different formats using built in PHP methods
Here are my questions:
What data type should I use in MySQL ( eg. timestamp, datetime ... )?
What method should I use to generate the date-time ( eg. MySQL's now(), PHP's date() ... )?
What PHP method should I later use to format the date-time in various pretty ways ( eg. 23/4/2012, 5pm on Monday, July 2012 ... )?
I would store it as a datetime, not a timestamp.
I normally use the PHP date function and that way if you ever want to store the time relative to the user's timezone you can simply change the timezone based off the user's settings.
When you pull it out of the database, use strtotime() to convert it, then you can use all the date() features to display it however you want. Example:
echo date('F j, Y',strtotime($db_datetime)); //Displays as 'March 5, 2012'
I've struggled with this question for years, and I'm beginning to think that the best way might be to store the time as an integer that represents Unix time (number of seconds from Jan 1, 1970). I've done this and it works fine.
Personally I've never used datetime, and I can't think of a situation when I ever would use this. It just carries too many problems with it.
Timestamp is a lot better, but in MySQL it can't store a date later than 2032.
I would love to hear some serious discussion on this topic, but Stack Overflow might not be the best place for this.
If you set the mysql data type to a non-nullable timestamp, then save rows with a null value for that column, mysql will automatically update the timestamp for you.
As for reading it back out again, you can just use php's strtotime and the date object to get it into the format you need.
You should use the datetime datatype for your requirement.
It will store both the date and time from your input field based on your query.
For retrieving the datetime you can use the mysql's date_format() function or PHP's date() function.
The datetime will always be stored according to the server's time and not on the clients time.

date problem in php

In my php application I have this code:
<?php echo date("d/m/ Y ",strtotime($row["m_date"]));?>
In it, $row["m_date"] is fetching from a database.
The problem is that all the dates are printing perfectly except 27/2/2011. It's printing 1/1/1970 instead.
The date in the database is fine, and prints correctly in a PDF.
I'll assume you're getting the date from the database as the string 27/2/2011 because that's most probably what happens (correct me if I'm wrong).
PHP considers the string 27/2/2011 as being in the m/d/Y format, not d/m/Y and tries to parse under that assumption. Because the date is not valid under that format strtotime returns false. Giving false as the timestamp parameter to date is taken as 0, which is the timestamp for January 1st 1970.
What you need to do is either get your date in another format (or better still, as a timestamp) from the database, or parse it yourself (say using explode).
Good luck,
Alin
The database should be able to return the date to you as a UNIX timestamp. For example, MySQL has the UNIX_TIMESTAMP() function.
SELECT UNIX_TIMESTAMP(date_column) FROM table;
Postgres has date_part
SELECT DATE_PART('epoch', date_column) FROM table;
Most other databases should have similar features. If you can get the date out as a UNIX time stamp you can pass that directly to date() without having to use strtotime() as well.
All of this does of course assume you're using a temporal datatype for the columns in question (timestamp, datetime, timestamp with time zone, etc) and not just storing a string. You are using a temporal type, right? If not, then why not?
if you are storing the date in the database as a timestamp this should work
<?php echo date("d/m/Y",$row["m_date"]);?>
if you are storing the date in the database as a date or datetime this should work
<?php echo date("d/m/Y",strtotime($row["m_date"]));?>
How is the m_date stored in the databases? Is it a datetime object? Or a string.
Problem with strtotime is that it isn't real good at deciphering written dates. So something like 27/2/2011 gives problems while 27/02/2011 gives no problems at all.
So there are 2 solutions:
Make sure all the dates that get entered into the database are of the correct format (dd/mm/yyyy).
Write a regular expression that adds a leading zero to all single characters.

Convert time to MySQL Time

I'm trying to store a week schedule (e.g. Monday, 9am-5pm, etc.). I do not have the need to store the dates; I just need to save the following: day, from time, to time.
So, say I have the following time values:
1:20pm
1320
8:00 AM
etc
Assuming that the values are actual valid times, how do I convert these strings into MySQL Time type? And how do I do the reverse? (I'm using PHP.)
Also, how do I query for something like this: find every store that is open on Mondays between 2pm and 3pm? Do I just do something like: WHERE day = 1 AND from_time >= 2pm AND to_time <= 3pm (changing '2pm' and '3pm' to whatever their converted values are, of course)? Or is there some MySQL function better suited for such queries?
MySQL has built in conversion for unix timestamps to a MySQL date:
INSERT INTO table (the_date) VALUES (FROM_UNIXTIME(your_timestamp));
…and the other way around…
SELECT UNIX_TIMESTAMP(the_date) FROM table;
You can use the DAY() and DAYOFWEEK() functions in your WHERE conditionals to convert your MySQL timestamps into the relevant units for you to do your query.
You might need to play around a bit with your schema to determine the best structure to allow you to get the functionality you need here. E.g. it might not make sense to store the day-of-week in a datetime field at all.
MySQL has a TIME data type - it will store values in the hh:mi:ss format, and you can use the TIME_FORMAT function to change the presentation to however you'd like.
Try not to rely on functions applied to the column for comparison - IE:
WHERE TIME_TO_SEC(column) = 123
...because it will render an index, if one exists on the column, useless -- ensuring a table scan (worst performing option).
MySQL understands the ISO 8601 date format, so you have to give time in the form "08:00:00" for 8:00 AM.
You can just use a string with a valid ISO 8601 time in your WHERE clause.
http://en.wikipedia.org/wiki/ISO_8601
http://dev.mysql.com/doc/refman/5.1/en/time.html
http://dev.mysql.com/doc/refman/5.1/en/datetime.html

MySQL datetime into PHP

I have found a proper solution to my "problem" but even after reading mysql pages, I don't understand the logic behind it.
I currently store registration information in my system in a "datetime" formatted field in one of my tables (YYYY-MM-DD hh:mm:ss).
When I want to display the data on one of my php pages, simply posting the exact field data shows the format mentioned above.
I would THINK simply using date("Y-m-d",$row["DATE"]) where $row["DATE"] corresponds to the particular row value would return the desired format.
Instead I have to use:date("Y-m-d", strtotime($row["DATE"])).
Why is this? My $row["DATE"] field is not a string in the first place. Should I be able to simple rearrange the data stored in a datetime field? Wasn't that the purpose of rebuilding my entire tableset to accomodate datetime?
MySQL has a built in function called date_format which you can use to display the date how you want to.
SELECT DATE_FORMAT(date_field, '%Y-%m-%d') as date_field FROM table_name
The manual has the list of formats and the variables needed to display it that way. Using this method there will be no need to have PHP convert it etc. Plus it is less code on PHP side for something MySQL can handle easily.
EDIT
Sorry, just read you were looking for an explanation.
PHP's date function takes in a UNIX timestamp, which MySQL is not using. MySQL uses a real date format IE: YYYY-MM-DD HH:MM:SS, as you know, this is to be compliant for years later. The UNIX timestamp has a limited range from something like 1969 to 2037 that it is valid for, which makes it really useful for "timestamping" of items such as a chat box message or items they are not expected to be around post those dates, where as the MySQL DATETIME should not die out until the year changes to 5 digits or the world ends.
Read the WIKI on UNIX timestamp for more information on it.
MySQL does allow you to select dates in unix timestamp format, which allows them to be used more easily in PHP, exactly as you requested.
The previous answer seemed to ignore this point, or downplay it due to the range restriction on the unix timestamp, but if it's what you're looking for...
SELECT UNIX_TIMESTAMP(datefield) as u_datefield FROM table
will give you the date in timestamp format, which you can use as you suggested in PHP:
<?php
$showdate = date("Y-m-d",$row['u_datefield']);
?>
As the previous answer suggests, unix timestamps do have a limited range, so if you need dates prior to 1970 or after 2038 it may not be suitable, but for everyday use today it's great.
The main advantage of using timestamps over date strings is that timestamps can be added and subtracted, which is much harder with a date in string format.

Categories