I am running a sweepstakes page on my wordpress site. I already have the logic setup when create a sweepstakes post that the sweepstakes page already pulls in post based on custom fields for "start_date" and "end_date". The issue I am having is if a sweepstakes is set to start on 03/01/2014 and end on 03/19/2014 once the time hits midnight (12:00) the post is removed when it needs to continue throughout the 19th. Stated below is the query code I am using. And it works for posts with custom fields of start date and end date. I just almost need a default for the post to be removed in this case 03/19/2014 at time 23:59:59. I need a default time for 23:59:59. Is there a global change that will make post remove on the date specified just at 23:59:59? I hope this explains it.
<?php // The Query
$startdate = date('Y-m-d G:i:s');
$enddate = date('Y-m-d G:i:s');
$args = array(
'post_type' => 'page',
'orderby' => 'meta_value_num',
'order' => 'DESC',
'meta_query' => array(
array(
'key' => 'sweepstakes_startdate',
'value' => $startdate,
'compare' => '<='
),
array(
'key' => 'sweepstakes_enddate',
'value' => $enddate,
'compare' => '>='
)
)
);
$the_query = new WP_Query( $args );
No, there's no real shorthand for specifying that, aside from specifying the literal '23:59:59'.
Seems like the quickest patch is just some PHP logic to reset $enddate before it's sent to your query.
If the time component of $enddate is midnight, then add one day and subtract one second to the value sent to the query.
This does change the specification a bit; it means that specifying an enddate value of '2014-03-19 00:00:00' is equivalent to specifying and enddate value of '2014-03-19 23:59:59', which basically means that it's not possible to specify a sweepstakes ending exactly midnight. But you could end a sweepstakes at time 00:00:01.
In MySQL, we'd typically specify the "end" of a period (like you describe) as midnight of the following day (rather than '23:59:59' of the preceding day), and use a "less than" comparison rather than a "less than or equal to" comparison.
For example:
WHERE mydatetimecol >= '2014-03-19'
AND mydatetimecol < '2014-03-20'
rather than
WHERE mydatetimecol >= '2014-03-19'
AND mydatetimecol <= '2014-03-19 23:59:59'
MySQL does have some handy INTERVAL operations on DATETIME values...
WHERE mydatetimecol >= '2014-03-19'
AND mydatetimecol < '2014-03-19' + INTERVAL 1 DAY
If I absolutely had to "back up" one second, I'd use an interval operation, for example:
WHERE mydatetimecol >= '2014-03-19'
AND mydatetimecol <= '2014-03-19' + INTERVAL 1 DAY + INTERVAL -1 SECOND
Note that some temporal values can actually have milliseconds precision, such as '23:59:59.997' where you could potentially leave a gap between the end of one period and the beginning of another, if you used '23:59:59'.
This isn't really a problem with temporal datatypes stored in MySQL (but other RDMBS such as SQL Server can store fractional seconds). And it's probably not a problem for your particular application (but in the more general case, we typically want for rows to fall into a particular bucket, and not fall between the cracks between the buckets.)
And, I'd be leery of adding 86,399 seconds to a date value, depending on whether the timezone is daylight savings time or not, there's some days that are 23 hours or 25 hours.
$start_scheduled_date = date("Y-m-d H:i:s", mktime(0,0,0));
$end_scheduled_date = date("Y-m-d H:i:s", mktime(23,59,59));
output:
2015-12-30 15:15:00
2015-12-31 00:00:00
2015-12-31 23:59:59
Related
I have date conversion issue: The goal is to determine an "order by date" for a book, this should be 13 days prior to the book's "release date", which is in EST. The "order by date" should display the 13 day time frame plus any time diff between the user's time and EST (New York) time. So in my function below, I'm getting the release date, NYC time, user's time and trying to do order_by_date = release_date - ( (nyc/user local time diff) + 13 days). It seemed to be working, but after testing this out with multiple release dates, I'm consistently returning a 14 day difference, not a 13 day one... My main question is why would the function below output a date that is 14 days before a release date and not 13 days? I've tried echoing each time variable and each one looks normal (i.e. for a user in NYC, the time diff is 0, but for someone on PST it's 3hour diff), I wonder if the formatting is having an effect on the value? Thanks for any input:
function get_order_by_date( ) {
$release_date = '26-02-2019 00:00:00'
$ny_timezone = new \DateTimeZone( 'America/New_York' );
$gmt_timezone = new \DateTimeZone( 'GMT' );
$user_date_time = new \DateTime( $release_date, $gmt_timezone );
$offset = $ny_timezone->getOffset( $user_date_time );
$my_interval = \DateInterval::createFromDateString( (string) $offset . 'seconds' );
$user_date_time->add( $my_interval );
$result = $user_date_time->format( 'd-m-Y H:i:s' );
$order_by_date = date( 'F jS', strtotime( $result . ' - 13 days' ) );
return $order_by_date;
}
It might be easier to see why we get a certain date as a result if we simplify the process a little. If I understand correctly the function needs to take the release date and do two things to it:
Shift 13 days prior to it
Set it to the user's timezone
If we start with the release date in the release timezone, making those modifications is more straightforward.
For the purposes of the answer I'm returning the result in a format that includes the time so we can see exactly where those modifications put the result, but you can use whatever format is needed.
<?php
function get_order_by_date(string $release_date, string $user_timezone)
{
$release_timezone = new \DateTimeZone( 'America/New_York' );
$user_timezone = new \DateTimeZone($user_timezone);
// start with the release date in NY time
$orderby_date = new \DateTime($release_date, $release_timezone);
// 13 days prior
$orderby_date->modify('-13 days');
// shift to the user's timezone
$orderby_date->setTimezone($user_timezone);
return $orderby_date->format('Y-m-d H:i:s');
}
Using the date in your example, 26-02-2019 00:00:00 moving thirteen days before would give you 13-02-2019 00:00:00.
At that time in NY, the time in LA would be three hours earlier, so the result would be in the previous day
echo get_order_by_date('26-02-2019 00:00:00', 'America/Los_Angeles'); // 2019-02-12 21:00:00
And the time in GMT would be five hours later, so the result would be in the same day
echo get_order_by_date('26-02-2019 00:00:00', 'GMT'); // 2019-02-13 05:00:00
I have a table, called schedules. It has three columns day, month, year, the the day/month/year that schedule is for. There is no timestamp here. I chose this format so that I could for instance retrieve all the schedules for October, or for the year 2014.
However, is it possible to retrieve the schedules for given range, say from Sept 10, 2014 to Oct 09, 2014? The problem is that if I use
WHERE 'day' > 10 AND 'day' < 9 ...
will not return anything since even though the month October (10) is larger than September (9), the days of the month will miss this up!
Is there a way or do I need to also include a fourth date column with a timestamp?
You can use parenthesis and an or clause:
WHERE ('month' = '9' AND 'day' > 10) OR ('month' = '10' AND 'day' < 9)
However, using a datetime field would be much better, as you can still get month/day/year easily:
WHERE MONTH(field) = 10
WHERE DAY(field) = 3
WHERE YEAR(field) = 2014
and then you also can do
WHERE field >= '2014-09-10' AND field <= '2014-10-09'
See http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html for documentation on all the date/time functions in mysql.
I have created an events calendar with codeigniters calendar class which you can view here: Events Calendar
I have it set up where the events are showing up on the calendar and when you click "view events" on a particular day, all the events with that start date pull up and are shown in a modal window.
Well... the problem is that unless its the START DATE of a particular event, the modal window details don't pull up. I know this is because i'm saying in my query to pull events where the start date equals a certain date...
I'm kind of stumped on how to modify this to say, "pull all records where this day is ANYWHERE BETWEEN the start and end date of the event.
Do I need to run a while loop or something and loop through each day of the month? Any ideas on an easier way to do this are appreciated.
the start and end dates are set up as 'Y-m-d H:i:s' in the database and the $query_date variable being passed in is 'Y-m-d', which i change to the same format in the first few lines of the function.
function get_list_events($query_date) {
$start_date_start = date('Y-m-d H:i:s', strtotime($query_date.' 00:00:00'));
$start_date_end = date('Y-m-d H:i:s', strtotime($query_date.' 23:59:59'));
$this->db->where('active', 1);
$this->db->where("start_date BETWEEN '$start_date_start%' AND '$start_date_end%'", NULL, FALSE);
$query = $this->db->get('events');
$data = array();
foreach ($query->result() as $row) {
$data[] = array(
'id' => $row->id,
'title' => $row->title,
'description' => $row->description,
'cost' => $row->cost,
'image' => $row->image,
'start_date' => $row->start_date,
'end_date' => $row->end_date,
'venue' => $row->venue,
'venue_address' => $row->venue_address,
'venue_city' => $row->venue_city,
'venue_state' => $row->venue_state,
'venue_zipcode' => $row->venue_zipcode,
'contact_name' => $row->contact_name,
'contact_email' => $row->contact_email,
'contact_phone' => $row->contact_phone,
'contact_website' => $row->contact_website,
'create_date' => $row->create_date,
'active' => $row->active,
);
}
return $data;
}
I guess your start_date column has the DATETIME or the TIMESTAMP data type. If that isn't true, please update your question.
There's a common trap in date-range processing in all kinds of SQL, due to the fact that when you compare a pure DATE with a DATETIME, they hardly ever come out equal. That's because, for example, DATE('2011-07-1') means the same thing as 2011-07-01 00:00:00.
So you need
start_date >= '$start_date_start'
AND start_date < '$start_date_end' + INTERVAL 1 DAY
instead of what you have, which is
start_date BETWEEN '$start_date_start%' AND '$start_date_end%' /*wrong!*/
The second clause with the < ... + INTERVAL 1 DAY picks up all possible times on the last day of your interval.
Edit Now that you've disclosed that you have two DATETIME columns, called start_date and end_date, it sounds like you're looking for items which start on or before a specific date, and end on or after that same date. Try something like this:
WHERE DATE(start_date) <= DATE('$specific_date')
AND DATE(end_date) >= DATE('$specific_date')
The trick on queries like this is to spend the majority of your time thinking through and specifying the results you want. If you do this, the SQL is often perfectly obvious.
I am trying to set publish date based on user choice and give it interval in a loop. But after it is substituted with the intervals, the year changed to the current year.
Here is the sample of my code:
$datestart = "2012-03-06";
$datenow = date("$datestart H:i:s", current_time( 'timestamp' ));
$newpostdate1 = $datenow + strtotime("0 years 0 months 1 days 0 hours 0 minutes 0 seconds");
$newpostdate = date("Y-m-d H:i:s", $newpostdate1);
echo $datenow . " " . $newpostdate;
$datenow Will return 2012-03-06 16:19:33 while $newpostdate return the current date plus 1 day i.e: 2014-03-15 17:02:23.
Why $newpostdate returning the current date plus next 1 day instead of 2012-04-06 16:19:33 ?
..because what you're doing doesn't do what you think it does.
First, you set $datenow to a string (not a date object), with value "2012-03-06 " + the current time (assuming that's what current_time returns).
Then you call strtotime with the value "1 days" (well, your string has a bunch of other zero-valued fields, but they don't change the result), which returns the current time + 24 hours as a number (the number of seconds since 1970).
Then you take that value and add it with + to the above string. This causes the string to be interpreted as a number, so it turns into 2012 (and the rest of the string is ignored). So the result is a timestamp representing the current time + one day + 2,012 seconds - or one day, 33 minutes and 32 seconds from the time the code is run. Which you then format as a string.
You could use John Conde's solution to get a more meaningful result. (I assume your real problem is different, else why not just start out by setting the string to '2012-03-07' in the first place?)
The first parameter of date() is the format you want the timestamp passed as the second parameter to be displayed as. So basically you are using date() incorrectly.
I think this is what you are looking for:
$date = new DateTime($datestart);
$date->modify('+1 day');
echo $date->format(Y-m-d H:i:s);
I have a general question on calculating dates with php.
What happens if I store a timestamp like this in my database:
$db_timestamp = '2010-01-31 00:00:00';
and then run a daily script that checks if a month has passed since the timestamp was saved in the database:
if ($db_timestamp == make_unix_timestamp(mktime(0, 0, 0, date("m") - 1, date("d"), date("Y")), TRUE, 'eu')))
{
do something
};
my problem is that i just realized that this wouldn't work for all dates. in this case 'do something' would not be called in February, since February doesn't have a 31st day. any idea on how to implement something like that?
First, your DBMS should have a data type for date/time. They all store timestamps in a similar way.
MySQL then provides a function called UNIX_TIMESTAMP() if you need to return a timestamp PHP can understand.
SELECT UNIX_TIMESTAMP(`createTime`) FROM `articles`;
The opposite function is called FROM_UNIXTIME():
INSERT INTO `articles` (`createTime`) VALUES ( FROM_UNIXTIME(12345678) );
MySQL (or another DBMS for that matter, but I'm using MySQL as an example) has a slew of other functions to calculate time differences. For example, to know if an article is more than one month old, use can use DATE_SUB():
SELECT * FROM `articles`
WHERE `article`.`createTime` <= DATE_SUB(NOW(), INTERVAL 1 MONTH);
(In MySQL5 and above, you can also write it as such)
SELECT * FROM `articles`
WHERE `article`.`createTime` <= (NOW() - INTERVAL 1 MONTH);
$ts = strtotime($db_timestamp);
if ($ts < (time() - 2592000))
{
do something;
}
2592000 seconds = 30 days
You could use date_diff http://us3.php.net/manual/en/datetime.diff.php
or do a comparison of the timestamp in your database with
strtotime("-1 month");
You could check the timestamp using a query:
MySQL:
select date from table where date < now() - INTERVAL 1 MONTH;
It kind of depends on how you consider "one month".
If "one month" means "30 days", a solution would be to compare the timestamp you get from the database with the current timestamp :
$db_timestamp = strtotime('2010-01-31');
$current_timestamp = time();
var_dump( ($current_timestamp - $db_timestamp) / (24*3600) );
If the difference is 30 days... that's it.
A couple of notes :
strtotime converts a date to an UNIX timestamp-- i.e. the number of seconds since 1970-01-01
time returns the current UNIX timestamp
you can compare timestamps : they only represent a number of seconds ; and there are 24*60*60 seconds per day ;-)