I have I'm having to workout the days difference between 2 columns one of which is a timestamp and the other being a varchar
timestamp - 2016-01-25 23:55:23 and varchar - 24/12/2015
not the best format for dates, but given that I'm unable to change the columns type is it possible to work out the difference in days between those 2 columns?
Many thanks
Max
The DateTime Class in PHP is very powerful and flexible, specially using the createFromFormat() method to load dates of different formats quite happily. Used together with the ->diff() method you should get what you want.
Here is an example
<?php
$ts = '2016-01-25 23:55:23';
$vc = '24/12/2015';
$tsdate = DateTime::createFromFormat('Y-m-d H:i:s', $ts);
$vcdate = DateTime::createFromFormat('d/m/Y', $vc);
$interval = $vcdate->diff($tsdate);
echo $interval->format('%R%a days');
Alternatively you could get MYSQL to do the heavy lifting and use its STR_TO_DATE() function when you query this odd varchar field
SELECT tsCol, STR_TO_DATE(varcharColumn, '%d/%m/%Y) as otherDate
Then when you see it in PHP it will be converted to a MySQL DATETIME column
Or going even further and getting MySQL to do all the work you could use MySQL's TIMESTAMPDIFF
SELECT TIMESTAMPDIFF(DAY, tsCol, STR_TO_DATE(varcharColumn, '%d/%m/%Y)) as differenceInDays;
Related
I need to select all rows from a table based on year, however the only field I can query is a DATETIME field that could read e.g. 2020-05-08 14:30:34.
How can I return entries based only off of the year?
$records = MedicalRecord::find()
->where(['dateCreated' => '2020'])
->all();
You can use YEAR() function, try this:
$records = MedicalRecord::find()
->where(['YEAR(dateCreated)' => 2020])
->all();
You can use andWhere() and compare against beginning and end of the year dates.
Probably worth keeping in mind that this would be the equivalent of comparing dates as strings, but since the ordering is YY-mm-dd, it works.
$records = MedicalRecord::find()
->where(['>=', 'dateCreated', '2020-01-01 00:00:00'])
->andWhere(['<', 'dateCreated', '2021-01-01 00:00:00'])
->all();
This way yii generates the code that runs against the database
If you can guarantee that you will be only running your application against a database engine that supports the YEAR() function, then Serghei's answer is probably best. But if you wanted to migrate to PostgreSql, Oracle... It would stop working.
Is there any sql command which I can insert into the stated query so I can convert the timestamp. Although it could be done separately which I have seen so far but I am trying to find something which I can add to the stated query as that would be helpful because I am using other queries to retrieve the data as well. If you any other questions please do mention. Addition: rating_timestamp contains both time and date.
SELECT rating_id,
rating_postid,
rating_posttitle,
rating_rating,
rating_timestamp,
rating_username,
rating_userid
FROM wp_ratings;
In cases of date arithmetic, it is especially important to specify the DBMS you are using - Oracle's math is different from Postgres' math is different from SQL Server's math is different from MySQL's math is...
This assumes that you are using SQL Server. Since there is no built in command to do this conversion, you need to create your own function to do that. The function below takes a UNIX / Linux timestamp and converts it to an SQL Server datetime.
CREATE FUNCTION dbo.fn_ConvertToLocalDateTime (#unixdate BIGINT)
RETURNS DATETIME
AS
BEGIN
DECLARE #UTCTimeOffset BIGINT
,#LocalDatetime DATETIME;
SET #UTCTimeOffset = DATEDIFF(second, GETUTCDATE(), GETDATE())
SET #LocalDatetime = DATEADD(second, #unixdate + #UTCTimeOffset, CAST('1970-01-01 00:00:00' AS datetime))
RETURN #LocalDatetime
END;
GO
I wast sure about about Sql version before. This worked perfectly for me.
FROM_UNIXTIME(rating_timestamp,'%h:%i:%s %D %M %Y')
My purpose is since the time I login my page, I want my web to show how many updated data in the database. My code is like this
$current = $_SESSION['date'];
$query2 = "SELECT * FROM gmaptracker1 WHERE datetime >= '$current'";
When I echo the $current, it showed 27/09/14 : 06:53:24, so the $current is correct, however, when I request the number of database where date>='$current', I get zero, although I have inserted to the database the data with datetime 28/09/14 : 06:53:24 and 29/09/14 : 06:53:24.
Can anyone help me to get out of this, please?
Few things,
It seems like your code is vulnerable to SQL Injection. Just because you retrieve the content of the date from a session, it doesn't mean that it's safe.
Also, why do you need it to be in a session variable? If you always want to retrieve dates bigger than NOW() you can just write your query this way:
SELECT * FROM gmaptracker1 WHERE datetime >= NOW()
The part that caught my attention was the format you're storing the dates.
You said that when you echo'ed $_SESSION['date'] the value was: 27/09/14 : 06:53:24
Now, that does not look like the date format at all. Is your column actually a datetime or timestampcolumn?
If it's a VARCHAR or any other type other than datetime or timestamp, then there's no way for MySQL to know that you're trying to retrieve dates that occur in the future.
If you already have data stored, then it isn't going to be as easy as changing the data type because you already have data, and your data is in the wrong format. The format that MySQL stores datetime information is as follows:
YYYY-MM-DD HH:MM:SS
Based on the comments you left, you don't need the time > NOW(), you need the time when you log in. Now it makes sense why you're storing that time in a variable.
The problem is the format you're storing it.
Since you're using PHP, then you have to store the time this way:
$time = new DateTime();
$_SESSION['date'] = $time->format("Y-m-d H:i:s");
I want to be able to work out the number of days between two dates. One date is the current date, the other is from a database of events.
So far, I have tried this in my Model:
this_date = DateTime.parse(self.date.to_s)
the_date = Time.now
between = (this_date.to_i - the_date.to_i)
Which was a suggestion from another question (well, kinda).
The date format from the database is 'YYYY/mm/dd', and the date from Time.now is a lot different which is what I cannot work out.
Any help would be appreciated.
Thanks
What data type is the db column for self.date in your model? I note you're casting it to a string so what was it originally? If it's a datetime type then you can skip the DateTime.parse and just compare the two dates directly to get the difference in seconds:
difference = self.date - Time.now
The fun part is then converting that difference to usable values. This question has an excellent answer to that.
Edit: for a Date column you can do:
difference = (self.date - Date.today).to_i
Which will give you a difference in whole days.
this_date = Date.parse self.date
remaing_days = (Date.today - this_date)
select (unix_timestamp(first_date)-unix_timestamp(second_date))/84600 from table
84600 is seconds in one day
unix_timestamp is date as seconds since 1970-01-01
So you don't need Ruby :-)
Even though it is answered, but I am posting my solution to this problem, that helped me to solve my problem. I have used:
Time.zone.now > e.start && Time.zone.now < e.end + 1.day
I have this query for MySQL database:
Article.where('DAY( created_at ) = DAY( ? )', day)
And I try to use the query above also in the PostgreSQL database, specifically I am trying something like this:
Article.where("DATE_PART('day', created_at) = DATE_PART('day', ?)", today)
But I am getting the error PGError: ERROR: function date_part(unknown, unknown) is not unique
Why is there that error? I thought I have the syntax by documentation...
It seems today is a string of the pattern YYYY-MM-DD. You could just extract the rightmost two characters, instead of casting to date and then extracting a number. Would be faster and simpler:
Article.where("date_part('day', created_at::date)::int
= right(?, 2)::int", today)
right() requires PostgreSQL 9.1 or later. In older version you can subsitute:
... = substring(?, 9)
Because you want characters 9 and 10.
This should work, too:
Article.where("date_part('day', created_at::date)::int
= date_part('day', ?::date)", today)
Note, that you must cast '2012-01-16' to date, not to interval. '2012-01-16'::interval would be nonsense.
According to the documentation there are two functions:
date_part(text, timestamp)
date_part(text, interval)
so database cannot choose which one you want. Cast the second parameter to timestamp, e.g. like this:
DATE_PART('day', created_at::interval) = DATE_PART('day', ?::interval)