Retrieving the last 7 days with RethinkDB during() - php

I have been trying for some hours now to try and return all results in the last 7 days, using RethinkDB and PHP.
Surveying the documentation at https://www.rethinkdb.com/docs/dates-and-times/javascript/ I have found the most appropriate RethinkDB function would be during().
Below is my code that I have come to the realization that this task is far harder than it appears. I have attempted to use the DateTime from PHP directly into the during, but this was also not successful.
$sevenago = new DateTime('7 days ago');
$sevenago->setTimeZone(new DateTimeZone('Asia/Kolkata'));
$sevenago = date_format($sevenago, 'U');
$now = new DateTime();
$now->setTimeZone(new DateTimeZone('Asia/Kolkata'));
$now = date_format($now, 'U');
$ordersLastWeek = r\table("orders")->filter(function($doc) {
return $doc('status')->eq('shipped')
->rAnd($doc('time')->during(r\epochTime($sevenago), r\epochTime($now)));
})->run($conn);
The time field is stored as follows (standard RethinkDB DateTime type):
{"$reql_type$":"TIME","epoch_time":1509557927.661,"timezone":"+00:00"}
Any help would be appreciated.

Try this:
$ordersLastWeek = r\table("orders")->filter(function($doc) use ($sevenago, $now) {
return $doc('status')->eq('shipped')->rAnd($doc('time')->during(r\epochTime($sevenago), r\epochTime($now)));
})->run($conn);
In your code you forgot to use use ($sevenago, $now) for the filter function.

$ordersLastWeek = r\table("orders")->filter(function($doc) {
return $doc('status')->eq('shipped')
->rAnd(($doc('time') > r\epoch_time($sevenago)));
})->run($conn);
Have you tried this. Hope it works.

Related

PHP: DateTime '-1 day'

I want to get the date of yesterday of the current date in a specifc time zone.
I tried like this, but it is not working:
$date = new DateTime(NULL, new DateTimeZone('Pacific/Wake'));
$yesterday = $date->modify( '-1 day' );
$yesterday = $yesterday->format('Y-m-d');
I am still getting today's date.
This problem, according to the documentation for the modify() method, seems to entirely depend on which version of php you're using. In this case, method chaining(which is what you're attempting to do is called), is only available on php version 5.3.0 and up, according to the changelog on the previously linked docs.
That in mind, it explains why your code didn't work, and #Deryck's did. If you ever do upgrade your php version, or get your host to upgrade it, you could likely reduce those three lines to two:
$date = new DateTime(NULL, new DateTimeZone('Pacific/Wake'));
$date = $date->modify( '-1 day' )->format('Y-m-d');
Not much of an improvement, I realize, but there's your reason for why it failed to work.
Below are two of the methods I see of getting around this; one is creation of a class.. which seems like overkill to me unless this is apart of something grander... the other is a creation of a function. Both shove the extra lines into something that takes up less space, in a sense.
class DT {
private $now; //can be null
private $timezone; //DateTimeZone object
public function __construct($tz_str, $now = NULL) {
$this->now = $now;
$this->timezone = new DateTimeZone($tz_str);;
}
public function mod($mod,$format) {
$dt = new DateTime($this->now, $this->timezone);
$dt->modify($mod);
return $dt->format($format);
}
}
function mod_formatted_zone($tz_str, $mod, $format, $now = NULL) {
$timezone = new DateTimeZone($tz_str);
$dt = new DateTime($now,$timezone);
$dt->modify($mod);
return $dt->format($format);
}
The use of either is simple; in the case of the class, it'd be something like..
$dt = new DT('Pacific/Wake');
echo $dt->mod('-1 day', 'Y-m-d');
While in the case of the function, it'd simply be..
echo mod_formatted_zone('Pacific/Wake', '-1 day', 'Y-m-d');
Seems to work once you don't re-assign the $date variable unnecessarily. See below:
<?php
$date = new DateTime(NULL, new DateTimeZone('Pacific/Wake'));
$date->modify("-1 day");
$date = $date->format("Y-m-d");
// echo $date; // just in case you wanna echo - ya dig
?>
View demo
FYI:
Wake Island Time Zone (UTC+12:00)
Which means 1 day before is actually today (for me at least, on the western hemisphere).
I want to get the date of yesterday of the current date in a specifc time zone.
You can specify relative dates in the DateTime constructor. This will work for you:-
$yesterday = new DateTime('- 1 day', new DateTimeZone('Pacific/Wake'));
var_dump($yesterday);
Proof!.

Why is my while loop not working when no echo is put inside?

I got a pretty simple code that will take 2 dates and loop my data until the end date is reached.
$start = new DateTime($senddate);
$now = new DateTime("NOW");
$end = new DateTime ($end);
//We check if starting date is >= now()
if ($start->date <= $now->date){
$start = $now;
}
$i=0;
if ($frequency==4){
while ($start->date <= $end->date) {
$calcdate[$i]=$start->date;
$start->modify('+1 month');
$i++;
echo '<!--';
print_r($start);
echo '-->';
}
As you see there is a print_r inside the loop.
Everything work fine :)
BUT, if I remove it, then the loop never end .. I tried to add if($i>50) exit; without anymore success. I don't understand why this loop doesn't work when no pint_r is inside.
Thanks for your help
I would suggest that you have a read of the PHP DateTime manual, there is a lot of good information there that will help you with what you are trying to do.
As far as I can tell, you are trying to carry out an operation on a monthly basis between two dates that span the current date. There is a simpler way of doing it utilising the DatePeriod class.
Something like this:-
$start = new \DateTime('yesterday');// Just for demo purposes
$now = new \DateTime(); //No need for "now" as it is the default
$end = new \DateTime('+ 6 month');// again, for demo purposes
$interval = new \DateInterval('P1M');
if($now >= $start){ // you can do direct comparisons on DateTime objects
$period = new \DatePeriod($start, $interval, $end);
foreach($period as $date){
// Each $date is a DateTime instance that you can
// operate on as you see fit, I have just var_dumped it out.
var_dump($date);
}
}
The above code can be seen working here http://3v4l.org/1I30E
My error came from this line $calcdate[$i]=$start->date;
It seems that this gives somme unexpected behavior (in this case), I tried using $calcdate[]=$start->format('Y-m-d H:i:s'); which gave the expected results ... Don't know why my script didn't worked with the date method. If anyone knows ..

default date() should be 3 months ahead

My server has many application instances.
I came across a problem that one of my application instance needs to be tested with the future date. i.e I want to test the application as it is running in 2013.
If i change the system date then it will work fine but the other instances will also get effected.
I want the future date for only one instance and the rest should work as it is.
i.e if i use date('Y-m-d'); it should jump for 3 months and display the future date.
and i dont want to add seconds to the default date as that might be a huge change in my application.
And that's why you write your application in a way that is testable.
Not good:
function doSomething() {
$date = date('Y-m-d');
...
}
Good:
function doSomething($ts = null) {
if (!$ts) {
$ts = time();
}
$date = date('Y-m-d', $ts);
...
}
you can make your own date function. It would serve as a hook to all date usage.
function mydate($format) {
$jump = ' +3 months';
return date($format, strtotime(date($format) . $jump));
}
you can than change all occurrences of date to mydate. If you decide to switch back to present, just leave $jump = ''
You can just do
date('Y-m-d', time() + 3 * 30 * 24 * 3600);
I recommend using the PHP5 DateTime classes. They're a bit more wordy, but much more powerful than the old-style PHP date handling functions.
$dateNow = new DateTime();
$dateAhead = $dateNow->add(DateInterval::createFromDateString('3 months'));
print $dateAhead->format('Y-m-d');

Bug with Zend_Date calculating subtraction two date

I write this function:
public function calcDifferentDate($dateStart, $dateEnd = false, $output = Zend_Date::DAY)
{
$dateEnd = $dateEnd ? $dateEnd : Zend_Date::now()->toString('YYYY-MM-dd');
$dateStartZD = new Zend_Date($dateStart, 'YYYY-MM-dd');
$dateEndZD = new Zend_Date($dateEnd, 'YYYY-MM-dd');
return $dateEndZD->sub($dateStartZD)->toString($output);
}
If call this:
echo calcDifferentDate('2011-11-10');
and today is: '2011-11-14'
the output returned is 05 and not 04
why? where am I doing wrong?
P.S. I use ZF 1.11.11 version
I found the solution
this work right! :D
public function calcDaysDiffDate($dateStart, $dateEnd = '')
{
$dateEnd = !empty($dateEnd) ? $dateEnd : Zend_Date::now()->toString('YYYY-MM-dd');
$dateStartZD = new Zend_Date($dateStart, 'YYYY-MM-dd');
$dateEndZD = new Zend_Date($dateEnd, 'YYYY-MM-dd');
$dateStartZD->sub($dateEndZD);
return $dateStartZD->getTimestamp() / (60 * 60 * 24);
}
Try returning this instead:
$newDate = new Zend_Date($dateEndZD->sub($dateStartZD), 'YYYY-MM-dd');
return $newDate->get($output);
The calculations are incorrect, I will try to get to that later. But for now, you'll need your logic to be similar to that, because like I said in my comment, your method was resulting in a fatal error due to the fact that your date subtraction was returning an integer instead of a Zend_Date object from which to call toString().
Edit
Sorry about my presumptuous, not well-thought-out previous answer. After more careful testing I believe I found your issue. The sub() function accepts an optional second param $part which is the part of the date will be returned from the resulting date subtraction. No need to call a toString() now even if you could.
So without further adieu, here it is with the fixed return statement:
public function calcDifferentDate($dateStart, $dateEnd = false, $output = Zend_Date::DAY)
{
$dateEnd = $dateEnd ? $dateEnd : Zend_Date::now()->toString('YYYY-MM-dd');
$dateStartZD = new Zend_Date($dateStart, 'YYYY-MM-dd');
$dateEndZD = new Zend_Date($dateEnd, 'YYYY-MM-dd');
return $dateEndZD->sub($dateStartZD, $output); // <-- fixed
}
Second Edit
After chatting with OP, it appears that my solution will not work for ZF 1.11.x due to the differences in the Zend_Date::sub() method.
The accepted answer for this question: How to compare the date parts of two Zend_Date objects? recommends using DateTime instead of Zend_Date in the following way (I've modified the code a bit to suit your needs):
$date1 = new DateTime('2011-11-14');
$date2 = new DateTime('2011-11-10');
$diffDays = $date1->diff($date2)->days;
I've tried it and it seems to return the correct result. It could be a good alternative to Zend_Date, if you are not absolutely required to use it.
Hope that helps,
I find solution:
public function calcDaysDiffDate($dateStart, $dateEnd = '')
{
$dateEnd = !empty($dateEnd) ? $dateEnd : Zend_Date::now()->toString('YYYY-MM-dd');
$dateStartZD = new Zend_Date($dateStart, 'YYYY-MM-dd');
$dateEndZD = new Zend_Date($dateEnd, 'YYYY-MM-dd');
$dateStartZD->sub($dateEndZD);
return $dateStartZD->getTimestamp() / (60 * 60 * 24);
}

I am trying to do looping but I can't

I am trying to make for loops using date function but I can't. In my case, I am trying to loop 2001-feb to 2009-jan and want to insert date but I can't. Can anyone help me? Here is my code:
for($start_year; $start_year<= $end_year; $start_year++)
{
for($start_month; $start_month<= $end_month; $start_month++)
{
$date_input = $start_year."-".$start_month."-27";
}
}
Looks like PHP.
for($start_year; $start_year<= $end_year; $start_year++)
You've not specified a starting value for $start_year, so unless you've defined that variable elsewhere, this is a syntax error. As well, since you're starting/ending on different months, you can't really use a loop for that without jumping through hoops. You'd probably be better off with something like this:
$date = strtotime("2001-02-01 00:00:00");
$end = strtotime("2009-01-01 00:00:00");
do {
echo date('Y-m', $date), "-27";
$date = strtotime("+1 month", $date);
} while ($date <= $end);
Note that strtotime is only one way of doing this. You could use the DateTime object with a 1-month DateInterval, but that's for PHP 5.3+ only.

Categories