Pick a value from an array randomly for a particular day - php

I have an array which has the id's and my code is as following,
//Random Offer of the day
$offers = Offer::model()->findAll();
$randomOffer = null;
$dataOffer = new GreenPointsActionDataObj();
if ($offers) {
$randomNo = mt_rand(0, count($offers) - 1);
$randomOffer = $offers[$randomNo];
$dataOffer->id = intval($randomOffer->id);
$dataOffer->title = $randomOffer->name;
$dataOffer->thumbUrl = $randomOffer->thumbUrl;
$dataOffer->description = $randomOffer->description;
}
$data[] = $dataOffer;
I need this to be day based, for example it should be always one for the day and next day another random but should be same the whole day.
how can i get this done ?
This is my suggestion, when an id is taken, i should maintain it with a day stored in DB.

Try this code:
Method 1:
To get the unique offer for year.
$weekday = date('l', time()); // will return the weekday number
$randomOffer = $offers[$weekday];
Method 2
To get the unique offer for year.
$daycnt = date('z', time())+1;
$randomOffer = $offers[$daycnt];
Method 3
To get the unique offer for month.
$cur_date = date('d', time());
$randomOffer = $offers[$cur_date ];

Related

Calculating A Cycle number using dates for a 28 day repeating cycle

I have a job that runs every 28 days. and I want to assign it a cycle number based on a starting reference date.
e.g
1st cycle is 01/27/22. and that cycle number would be 2201.
subsequently I want to calculate the cycle number based on the current date. but for each year there could be either 13 or 14 cycles.
I've managed to figure out the number of cycles since the reference date to figure out the latest cycle date (see below)
const REF_ZERO_DATE = '01/27/2022';
const REF_ZERO_CYCLE_YEAR = "22";
const REF_ZERO_CYCLE_NUM = "01";
$today = new \DateTime("2023/12/29");
echo ("Today = ".$today->format("Y/m/d")."\n");
$ref_zero = new \DateTime(self::REF_ZERO_DATE);
echo ("ref_zero = ".$ref_zero->format("Y/m/d")."\n");
$number_of_days_since_ref_zero = $today->diff($ref_zero)->format("%a");
echo ("Number of days since ref zero = ".$number_of_days_since_ref_zero."\n");
$number_of_cycles_since_ref_zero = floor($number_of_days_since_ref_zero/28);
echo ("Number of cycles since ref zero = ".$number_of_cycles_since_ref_zero."\n");
$interval = 'P' . $number_of_cycles_since_ref_zero*28 . 'D';
echo ("Interval = ".$interval);
$date_of_lastest_cycle = date_add($ref_zero,new \DateInterval($interval));
echo ("last Cycle Date = ".$date_of_lastest_cycle->format("Y/m/d")."\n");
But my math for the cycle adjustment is missing coping with 12 or 13 cycle in a specific year.
It is not explicitly stated whether the cycle of the previous year continues into the next or not.
The scenario in which the cycles can overlap between years is more complicated, so this is assumed.
The interval count code was extracted to the following function:
function calculateIntervalCount($startDate, $endDate, $interval) {
$start = new \DateTime($startDate);
$end = new \DateTime($endDate);
$interval = new \DateInterval($interval);
$periodDays = intval($end->diff($start)->format('%a'));
$intervalDays = intval($interval->format('%d'));
return floor($periodDays / $intervalDays);
}
There are two cases when calculating the interval count of a particular year:
year of start and end are the same year
year of end is after year of start
In the first case the interval count is the same as the interval count of the whole period.
In the second case the interval count of a particular year can be calculated from the difference between the interval counts of the whole period and the period before the end year.
The following function returns the cycle number:
function calculateCycleNumber($startDate, $endDate, $interval) {
$totalCycles = calculateIntervalCount($startDate,$endDate,$interval);
$startYear = intval((new \DateTime($startDate))->format('Y'));
$endYear = intval((new \DateTime($endDate))->format('Y'));
if($startYear < $endYear) {
$endOfLastYearDate = (new \DateTime($endDate))->modify('last day of December last year')->format('Y-m-d');
$cyclesSinceEndOfLastYear = calculateIntervalCount($endOfLastYearDate, $endDate, $interval);
$yearCycle = $totalCycles - $cyclesSinceEndOfLastYear + 1;
} else {
$yearCycle = $totalCycles;
}
$yearCode = substr($endYear,-2);
$yearCycleCode = sprintf('%02d', $yearCycle);
return $yearCode . $yearCycleCode;
}
A cycle number of 2314 was obtained with the inputs provided.
echo calculateCycleNumber('01/27/2022','2023/12/29','P28D');
Note that 14 is possible in case of overlapping cycles.
You can use timestamp, where you add 28 days each time so you get the next date and so on.
Get the next timestamp
$next_date = strtotime('+28 day', $timestamp);
Convert to readable date
echo date('m/d/Y', $next_date);

Extract only the number of the day of the date and compare it with the current one

I need to extract only the day number of a user's registration date.
And extract only the day number of the current date.
Simply in an if loop, say if the day number the user registered is equal to the day number of the current date, do this, or do that.
Code:
$manager = "Manager";
$managerPRO = "ManagerPRO";
$q = $connessione->prepare("
SELECT * FROM collaboratori
WHERE cat_professionisti = ?
OR cat_professionisti = ?
");
$q->bind_param('ss', $manager,$managerPRO);
$q->execute();
$r = $q->get_result();
while($rr = mysqli_fetch_assoc($r)){
/*REGISTRATION DATE*/
$registrazione = $rr['data_registrazione'];
$timestamp = strtotime($registrazione);
echo date("d", $timestamp) .'=' ;
/*CURRENT DATE*/
$data_corrente = date('Y-m-d');
$timestamp_uno = strtotime($data_corrente);
echo date("d", $timestamp_uno);
/*CONTROL*/
if ($timestamp == $timestamp_uno){
echo "yes".'<br>';
}else{
echo "no".'<br>';
}
}
Result:
18=18no
17=18no
16=18no
16=18no
Why in the first case if 18 = 18 gives me false?
However, if I change the date of the user's registration and therefore the first 18, from 2020/11/18 to 2020/12/18, then the current month gives me yes!
I need that regardless of the month, just by checking the day if it is the same, tell me yes, where am I wrong?
You are comparing timestamps, which are measured in seconds. What you are doing is effectively comparing two different points in time, not the days of the month.
You really should be using DateTime. If you want to compare only the day part then you can do something like this.
$dt1 = new DateTime($registrazione);
$dt2 = new DateTime(); // defaults to now
if($dt1->format('d') === $dt2->format('d')) {
echo "Yes, it's the same day of the month";
} else {
echo 'no!';
}

auto generated purchase order number base from year in laravel

I have this code which should generate purchase number automatically with year attached to the number.
$record = Ponumbers::latest()->first();
$expNum = explode('-', $record->purchase_num);
//check first day in a year
if ( date('l',strtotime(date('Y-01-01'))) ){
$nextPoNumber = 'po'.date('Y').'-000001';
} else {
//increase 1 with last invoice number
$nextPoNumber = $expNum[0].'-'. $expNum[1]+1;
}
but it doesn't seems to work because it display only the this,
I am guessing it only displayed what's in this line
$nextPoNumber = 'po'.date('Y').'-000001';
any suggestion? thanks you so much in advance!
date('l',strtotime(date('Y-01-01'))) returns first weekday name for 2019, which is Tuesday. That is truthy value so the if is always true and $nextPoNumber is always po2019-000001.
If I understand your code correctly this is what you like it to do:
$record = Ponumbers::latest()->first();
$expNum = explode('-', $record->purchase_num);
$nextPoNumber = 'po'.date('Y').'-'.sprintf("%06d",$expNum[1]+1);
Try this :
$record = Ponumbers::latest()->first();
$expNum = explode('-', $record->purchase_num);
//check first day in a year
$first_day = gmdate('j', strtotime('first day of january this year'));
if (date('j') == $first_day){
$nextPoNumber = 'po'.date('Y').'-000001';
} else {
//increase 1 with last invoice number
$nextPoNumber = $expNum[0].'-'. $expNum[1]+1;
}

get average of given dates in php

I try to get an average of given dates but I failed when dates are from two different years. I need something like this
given dates:
2017-06-1
2017-06-3
2017-06-4
2017-06-3
2017-06-5
output : 2017-06-4
this is my code:
$total = 0;
foreach ($dates as $date) {
$total+= date('z', strtotime($date))+1;
}
$avg_day = $total/sizeof($dates);
$date = DateTime::createFromFormat('z Y', $avg_day . ' ' . date("Y"));
but my code is not working for
given dates:
2016-12-29
2016-12-31
2017-01-1
2017-01-5
2017-01-3
You can work with timestamp of the date and use avg() method of the Illuminate\Support\Collection
$dates = [
'2016-12-29', '2016-12-31', '2017-01-1', '2017-01-5', '2017-01-3'
];
$dateCollection = collect();
foreach($dates as $date){
$dateCollection->push((new \DateTime($date))->getTimestamp());
}
$averageTimestamp = $dateCollection->avg(); //timestamp value
$averageDate = date('Y-m-d', $average);
Or using Carbon package:
$dateCollection->push(Carbon::parse($date)->timestamp);
...
$averageDate = Carbon::createFromTimestamp($average)->toDateString();
Your code is not working for your base dates. The correct output for
2017-06-1 2017-06-3 2017-06-4 2017-06-3 2017-06-5
is
2017-06-03
According to OpenOffice calc, and overall logic (a date is represented by epoch number)
Check out this script
$dates = ['2017-06-1 ', '2017-06-3', '2017-06-4', '2017-06-3', '2017-06-5'];
$dates = array_map('strtotime', $dates);
$average = date('Y-m-d', array_sum($dates) / count($dates)); // 2017-06-03 (1496490480)
echo $average;
Keep simple tasks simple
I think you have problem with averaging year. So, You can do this to get average.
Just an algorithm:
Find smallest date among your dates at first as $smallest
Initiate a variable $total = 0;
Add difference of each date in days with smallest date.
Find average from total.
Add this total to smallest date.
Here, You have smallest as $smallest = '2016-12-29'
$total = 0;
$dates = ['2016-12-29', '2016-12-31', '2017-01-1', '2017-01-5', '2017-01-3'];
$smallest = min($dates);
$smallest = Carbon::parse($smallest);
foreach($dates as $date){
$d = Carbon::parse($date);
$total = $total+$smallest->diffInDays($d);
}
$average_day = $total/sizeof($dates);
$average_date = $smallest->addDays($average_day);
Hope, This might help you.

Get an averange of visitors in Laravel

I want to have an averange of visitors per day. I'm using Laravel 4.
The database structure I have is this:
Name: visitor
Now I tried to use the avg() function of Laravel, but I can't find a right solution. Could someone help me please with this?
I already have an controller wich one looks like this:
public function index()
{
//$select_stats = Visitor::where('visit_date', '>=', Carbon::now()->startOfMonth())->get();
$begin = date('Y-m-01');
$end = date('Y-m-t');
$visits = Tracker::selectRaw('date, count(ip)')->groupBy('date')->whereRaw("date between '$begin' and '$end'")->get();
//get total visits per month
$get_visits = Visitor::whereRaw("date between '$begin' and '$end'")->count();
//get averange visits
return View::make('admin.home.index')->with('stats', $visits)->with('get_visits', $get_visits)/*->with('get_avg_visits', $get_avg_visits)*/;
}
Basically, you've got everything you need for calculating the average count of visitors, no additional query needed :) You just have to divide the total number of visits by the number of days of the month:
public function index()
{
$begin = date('Y-m-01');
$end = date('Y-m-t');
// ...
//get total visits per month
$get_visits = Visitor::whereRaw("date between '$begin' and '$end'")->count();
// get average visits
// transform dates to DateTime objects (we need the number of days between $begin and $end)
$begin = new \DateTime($begin);
$end = new \DateTime($end);
$diff = $end->diff($begin); // creates a DateInterval object
$days = (int)$diff->format('%a'); // %a --> days
$average_visits = $get_visits / $days;
// ...
}
Try like this-
$avrage_visit= Visitor::select(DB::raw('avg("date") as date_avg')))->groupBy('date')
->get();
Reference -
http://laravel.com/docs/4.2/queries

Categories