MySQL Where Date (not datetime) as Week of year - php

I have the following query using Symfony2, I want to convert i.fechaInicio which is date field Y-m-d (2013-08-31) to current week number so I can fetch results from current week...
$now = new \DateTime();
$semana = $now->format('W'); // Week Number
$query = $this->getEntityManager()
->createQuery("
SELECT i
FROM PgeIncidenciasBundle:Incidencia i
WHERE i.fechaInicio = :semana // This is wrong because compares
// Y-m-d with W so no results found...
")
->setParameters(array(
'semana' => $semana
))
;
try {
return $query->getResult();
}
catch (\Doctrine\ORM\NoResultException $e)
{
return null;
}

Use BETWEEN operator :
$from = new DateTime;
$from->setIsoDate($from->format('o'), $from->format('W'));
$to = clone $from;
$to->modify('+6 day');
$query = $this->getEntityManager()
->createQuery("
SELECT i
FROM PgeIncidenciasBundle:Incidencia i
WHERE i.fechaInicio BETWEEN :from AND :to
")
->setParameters(array(
'from' => $from->format('Y-m-d'),
'to' => $to->format('Y-m-d'),
));

Found a solution using WHERE IN() and generating an array of dates for current week.
public function findCounter()
{
$now = new \DateTime();
$semana = $now->format('Y-m-d');
$query = $this->getEntityManager()
->createQuery("
SELECT i
FROM PgeIncidenciasBundle:Incidencia i
WHERE i.fechaInicio IN (:semana)
")
->setParameters(array(
'semana' => $this->week_from_monday($semana)
))
;
try {
return $query->getResult();
}
catch (\Doctrine\ORM\NoResultException $e)
{
return null;
}
}
private function week_from_monday($date) {
list($year, $month, $day) = explode("-", $date);
$wkday = date('l',mktime('0','0','0', $month, $day, $year));
switch($wkday) {
case 'Monday': $numDaysToMon = 0; break;
case 'Tuesday': $numDaysToMon = 1; break;
case 'Wednesday': $numDaysToMon = 2; break;
case 'Thursday': $numDaysToMon = 3; break;
case 'Friday': $numDaysToMon = 4; break;
case 'Saturday': $numDaysToMon = 5; break;
case 'Sunday': $numDaysToMon = 6; break;
}
$monday = mktime('0','0','0', $month, $day-$numDaysToMon, $year);
$seconds_in_a_day = 86400;
for($i=0; $i<7; $i++)
{
$dates[$i] = date('Y-m-d',$monday+($seconds_in_a_day*$i));
}
return $dates;
}

Related

Get 3 future day dates with php

I want to creat a table for listing 3 future days with day name and date for my online shopping.
I try this code but it doesn't work correctly :
function week_from_monday($date) {
// Assuming $date is in format DD-MM-YYYY
list($day, $month, $year) = explode("-", $_REQUEST["date"]);
// Get the weekday of the given date
$wkday = date('l',mktime('0','0','0', $month, $day, $year));
switch($wkday) {
case 'Monday': $numDaysToMon = 0; break;
case 'Tuesday': $numDaysToMon = 1; break;
case 'Wednesday': $numDaysToMon = 2; break;
case 'Thursday': $numDaysToMon = 3; break;
case 'Friday': $numDaysToMon = 4; break;
case 'Saturday': $numDaysToMon = 5; break;
case 'Sunday': $numDaysToMon = 6; break;
}
// Timestamp of the monday for that week
$monday = mktime('0','0','0', $month, $day-$numDaysToMon, $year);
$seconds_in_a_day = 86400;
// Get date for 7 days from Monday (inclusive)
for($i=0; $i<7; $i++)
{
$dates[$i] = date('Y-m-d',$monday+($seconds_in_a_day*$i));
}
return $dates;
}
$ddate = date('Y-m-d');
$date = new DateTime($ddate);
$week = $date->format("W");
$week_number = $week;
$year = date('Y');
for($day=5; $day<=30; $day++)
{
echo date('m/d/Y', strtotime($year."W".$week_number.$day))."\n";
}
Here is my code but I want to get this :
today : Sun
Monday 30
Tuesday 31
Wednesday 1
To get the next 3 upcoming dates, you can simplify this a lot using date and strotime.
Try this code:
function nextThreeDays($date) {
$dateTs = strtotime($date);
// Dont need this, but I leave it for educational purpose:
// $day_of_week = date("N", $dateTs) - 1; // Mon=0 Tue=1 Wed=2 ...
// $monday_time = strtotime(date("d.m.Y H:i:s", $dateTs) . " -".$day_of_week." days"); // timestamp of monday of week of $date
for($i = 1; $i <= 3; $i++) {
echo date('m/d/Y', strtotime(date("d.m.Y H:i:s", $dateTs) . " +".$i." days"))."\n";
}
}
// Put in "today : Sun"
nextThreeDays("29.01.2023");
Outputs:
// Monday 30 Tuesday 31 Wednesday 1
01/30/2023
01/31/2023
02/01/2023

show the list time from start time until end time with block time php

I have a problem to show the list time.
I saved start time, end time, interval time and block time in mysql.
e.g.
for start time : 09:00
for end time : 15:00
interval : 3
block time : 10:00-11:00;13:00-14:00
static function getListTime($time_interval,$s_hour, $e_hour, $peakTimesConfig){
switch ($time_interval) {
case '1':
$interval = new DateInterval('PT15M');
break;
case '2':
$interval = new DateInterval('PT30M');
break;
case '3':
$interval = new DateInterval('PT1H');
break;
case '4':
$interval = new DateInterval('PT2H');
break;
}
$result = array();
$time = new DateTime($s_hour);
$eTime = new DateTime($e_hour);
$bookingTimeIntervalSecond = $time_interval * 60;
$unavaibaleTimes = explode(';', $peakTimesConfig);
$arrUnavaibaleTimes = [];
foreach ($unavaibaleTimes as $unavaibaleTime) {
$strTime = explode('-', $unavaibaleTime);
$startTime = strtotime($strTime[0]);
if (!isset($strTime[1])) {
$endTime = $startTime + $bookingTimeIntervalSecond;
} else {
$endTime = strtotime($strTime[1]);
}
$arrUnavaibaleTimes[]=['startTime'=>$startTime,'endTime' => $endTime];
}
//sorting
for($i = 0; $i < count($arrUnavaibaleTimes); $i ++) {
for($j = 0; $j < count($arrUnavaibaleTimes); $j ++) {
if ($arrUnavaibaleTimes[$i]['startTime'] < $arrUnavaibaleTimes[$j]['startTime']) {
$sorting = $arrUnavaibaleTimes[$i];
$arrUnavaibaleTimes[$i] = $arrUnavaibaleTimes[$j];
$arrUnavaibaleTimes[$j]= $sorting;
}
}
}
$i = 0;
while ($time < $eTime) {
foreach($arrUnavaibaleTimes as $times){
if ($time->getTimestamp() < $times['startTime'] || $time->getTimestamp() >= $times['endTime']) {
if(!in_array($time->format("H:i"), $result)){
$result[] = $time->format("H:i");
}
}
else{
break;
}
}
$time->add($interval);
$i++;
}
return $result;
}
My question is : I want to show time slot from start time to end time without the block time.
e.g.
result : 09:00, 11:00, 12:00, 14:00, 15:00
Personally, I would do this with a class with something like the following. Note: Very little error checking on the data. You would need to test for garbage input.
The following class will display:
09:00, 11:00, 12:00, 14:00, 15:00
Changing the start value to 09:15 would currently render the following which may not be the result you want, but it is what I would want:
09:15, 11:00, 12:00, 14:00, 15:00
And changing start to 10:00 renders:
11:00, 12:00, 14:00, 15:00
And one final test, changing interval to 2:
09:00, 09:30, 11:00, 11:30, 12:00, 12:30, 14:00, 14:30, 15:00
The code:
// This would be from your mysql.
$raw = array(
'start'=>'09:00',
'end'=>'15:00',
'interval'=>3,
'block'=>'10:00-11:00;13:00-14:00'
);
$ts = new TimeSlot($raw);
echo 'Result: '.$ts->result();
// Note: Very little error checking on the input data!
class TimeSlot {
private $interval = 60;
private $block = null;
private $start = null;
private $end = null;
public function __construct($data=null) {
if ($data) {
if ($data['interval']) {
$this->setInterval($data['interval']);
}
if ($data['block']) {
$this->setBlock($data['block']);
}
if ($data['start']) {
$this->setStart($data['start']);
}
if ($data['end']) {
$this->setEnd($data['end']);
}
}
}
public function result() {
$result = null;
if (($this->start) && ($this->end)) {
$t = explode(':',$this->start);
$hs = $t[0];
$ms = $t[1];
do {
$t = $hs.':'.str_pad($ms,2,'0');
if (! $this->block[$t]) {
$result .= $t.', ';
}
$ms += $this->interval;
if ($ms >= 60) {
$ms = 0;
$hs++;
}
} while($t != $this->end);
}
return (strlen($result) > 5) ? substr($result,0,-2) : $result;
}
private function setInterval($interval) {
switch($interval) {
case 1:
$this->interval = 15;
break;
case 2:
$this->interval = 30;
break;
case 4:
// you would need to code for this option
$this->interval = 120;
break;
default:
$this->interval = 60;
}
}
private function setBlock($block) {
if ($block) {
$tmp = explode(';',$block);
foreach($tmp as $k=>$v) {
$b = explode('-',$v);
if (is_array($b)){
$ts = explode(':',$b[0]);
$hs = $ts[0];
$ms = $ts[1];
$n = $b[0];
do {
$t = $n;
$this->block[$t] = $t;
$ms += 15;
if ($ms >= 60) {
$ms = 0;
$hs++;
}
$n = $hs.':'.str_pad($ms,2,'0');
} while ($n != $b[1]);
}
}
}
}
// no error check at all!
private function setStart($start) {
$this->start = $start;
}
// no error check at all!
private function setEnd($end) {
$this->end = $end;
}
}

Change Time format in Zend Framework

Want to show Date, Time and Hours?
please help me to find out how to modify this code now its showing hours ago and days ago...
Screen Shot
enter code here
abstract class Rss_Model_Feed_Abstract extends Core_Model_Default {
protected $_news = array();
protected function _parse() {
$feed = Zend_Feed_Reader::import($this->getLink());
$this->_news = new Core_Model_Default(array(
'title' => $feed->getTitle(),
'link' => $feed->getLink(),
'dateModified' => $feed->getDateModified(),
'description' => $feed->getDescription(),
'language' => $feed->getLanguage(),
'entries' => array(),
));
$data = array();
foreach ($feed as $entry) {
$picture = null;
if($entry->getEnclosure() && $entry->getEnclosure()->url) $picture = $entry->getEnclosure()->url;
$description = "";
if($entry->getContent()) {
$content = new Dom_SmartDOMDocument();
$content->loadHTML($entry->getContent());
$content->encoding = 'utf-8';
$description = $content->documentElement;
$imgs = $description->getElementsByTagName('img');
if($imgs->length > 0) {
foreach($imgs as $k => $img) {
if($k == 0) {
$img = $imgs->item(0);
if($img->getAttribute('src') AND stripos($img->getAttribute('src'), ".gif") === false) {
$picture = $img->getAttribute('src');
$img->parentNode->removeChild($img);
}
}
$img->removeAttribute('width');
$img->removeAttribute('height');
}
}
$as = $description->getElementsByTagName('a');
if($as->length > 0) {
foreach($as as $a) {
$a->setAttribute('target', '_self');
}
}
$description = $content->saveHTMLExact();
}
$timestamp = $entry->getDateCreated() ? $entry->getDateCreated()->getTimestamp() : null;
$updated_at = null;
if($timestamp) {
$updated_at = $this->_getUpdatedAt($timestamp);
}
$edata = new Core_Model_Default(array(
'entry_id' => $entry->getId(),
'title' => $entry->getTitle(),
'description' => $description,
'short_description' => strip_tags($description),
'dateModified' => $entry->getDateModified(),
'authors' => $entry->getAuthors(),
'link' => $entry->getLink(),
'content' => $description,
'enclosure' => $entry->getEnclosure(),
'timestamp' => $timestamp,
'updated_at' => $updated_at,
'picture' => $picture,
));
$data[] = $edata;
}
$this->_news->setEntries($data);
return $this;
}
protected function _getUpdatedAt($timestamp) {
$date = new Zend_Date($timestamp);
$now = Zend_Date::now();
$difference = $now->sub($date);
$seconds = $difference->toValue() % 60; $allMinutes = ($difference->toValue() - $seconds) / 60;
$minutes = $allMinutes % 60; $allHours = ($allMinutes - $minutes) / 60;
$hours = $allHours % 24; $days = ($allHours - $hours) / 24;
switch($days) {
case 0: $days = false; break;
case 1: $days .= " {$this->_('day')}"; break;
default: $days .= " {$this->_('days')}"; break;
}
switch($hours) {
case 0: $hours = false; break;
case 1: $hours .= " {$this->_('hour')}"; break;
default: $hours .= " {$this->_('hours')}"; break;
}
switch($minutes) {
case 0: $minutes = false; break;
case 1: $minutes .= " {$this->_('minute')}"; break;
default: $minutes .= " {$this->_('minutes')}"; break;
}
switch($seconds) {
case 0: $seconds = false; break;
case 1: $seconds .= " {$this->_('second')}"; break;
default: $seconds .= " {$this->_('seconds')}"; break;
}
$updated_at = '';
if($days) {
$updated_at = $days;
} elseif($hours) {
$updated_at = $hours;
} elseif($minutes) {
$updated_at = $minutes;
} elseif($seconds) {
$updated_at = $seconds;
}
return $this->_('%s ago', $updated_at);
}
}
Hello I think you ask time date formatting
// to show both date and time,
$date->get('YYYY-MM-dd HH:mm:ss');
// or, to show date only
$date->get('YYYY-MM-dd')
this will help to get time and date
I'm going to trust the naming i see in your code and assume the $timestamp is really a time stamp :)
In which case all you need is to format it in a desired shape using the PHP's date method, in other word you wont need the _getUpdatedAt method in your code.
so you have to change:
$timestamp = $entry->getDateCreated() ? $entry->getDateCreated()->getTimestamp() : null;
$updated_at = null;
if($timestamp) {
$updated_at = $this->_getUpdatedAt($timestamp);
}
to
$timestamp = $entry->getDateCreated() ? $entry->getDateCreated()->getTimestamp() : null;
$updated_at = date('Y-m-d H:i:s', $timestamp);
In the above example the displayDate will be something like 2015-09-28 10:34:56 which you can modify by amending the date's method first parameter 'Y-m-d H:i:s'

PHP DateInterval. Go back to the beginning of the year

I would like to write a method which I can give a period of time (Like: yearly, monthly...) and it returns me an anterior date according to this period of time given.
Here is my code:
public function callRuleCeilling($period)
{
$start = new \DateTime();
switch ($period) {
case 'weekly':
$dateInterval = 'P7D';
break;
case 'monthly':
$dateInterval = 'P1M';
break;
case 'quaterly':
$dateInterval = 'P3M';
break;
case 'half-yearly':
$dateInterval = 'P6M';
break;
case 'yearly':
$dateInterval = 'P1Y';
break;
default:
$dateInterval = 'P1Y';
}
$start->sub(new \DateInterval($dateInterval));
return $start
}
My example problem:
If I put a starting date in the middle of the year with a yearly period. I want it to stop at the beginning of the year.
And I would like the same for monthly period (Stop at the beginning of the month) etc...
Does it exist a PHP function with do that? I can't find it.
Please highlight me.
Thanks fo the highlight. It allowed me to did that way:
public function callRuleCeilling($period)
{
$start = new \DateTime();
$month = 'January';
switch ($period) {
case 'weekly':
$timestampMonday = strtotime('last monday', strtotime('tomorrow'));
$start = $start->setTimestamp($timestampMonday);
break;
case 'monthly':
$month = $start->format('F');
$start = new \DateTime('first day of '.$month);
break;
case 'quaterly':
$monthNumber = $start->format('n');
if($monthNumber >= 1) $month = 'January';
if($monthNumber >= 5) $month = 'May';
if($monthNumber >= 9) $month = 'September';
$start = new \DateTime('first day of '.$month);
break;
case 'half-yearly':
$monthNumber = $start->format('n');
if($monthNumber >= 1) $month = 'January';
if($monthNumber >= 7) $month = 'July';
$start = new \DateTime('first day of '.$month);
break;
case 'yearly':
$start = new \DateTime('first day of January');
break;
default:
$start = new \DateTime('first day of January');
}
return $start;
}

Calculate a due date in PHP

One of my co-workers recently installed an open-source script into our billing system. The purpose is to re-calculate the next due date for a service when the customer's service is paid for late. Example being service is due 11/20/2012, is suspended the next day, and then they pay for it 11/25/2012. This script is supposed to update the next due date to 12/25/2012, but is malfunctioning and changing (monthly) dates that should be 12/25/2012 to 1/25/2013 for some reason.
I think the issue is with the way the $month variable is being handled, but can't quite figure out where the issue is.
function calculate_postpone_due_date($billingcycle)
{
switch($billingcycle)
{
case "Monthly": $months = 1; break;
case "Quarterly": $months = 3; break;
case "Semi-Annually": $months = 6; break;
case "Annually": $months = 12; break;
case "Biennially": $months = 24; break;
case "Triennially": $months = 32; break;
default: $months = 0; break;
}
//we return FALSE for any other billing cycles: "One Time", "Free Account" etc, they are not recurring
if ($months == 0)
return FALSE;
//a bit complex calculation based on day of the month
//exactly like native whmcs logic do
$year = date("Y");
$month = date("m");
$day = date("d");
for ($i=1; $i<=$months; $i++)
{
$month++;
if ($month == 13)
{
$month = 1;
$year++;
}
}
if (checkdate("$month", $day, $year))
{
return "$year-$month-$day";
}
else
{
//getting last day of the month
$last_day = date("t", mktime(0, 0, 0, $month, 1, $year));
return "$year-$month-$last_day";
}
}
function calculate_postpone_due_date($billingcycle)
{
switch($billingcycle)
{
case "Monthly": $months = 1; break;
case "Quarterly": $months = 3; break;
case "Semi-Annually": $months = 6; break;
case "Annually": $months = 12; break;
case "Biennially": $months = 24; break;
case "Triennially": $months = 36; break;
default: $months = 0; break;
}
if ($months == 0)
return FALSE;
$today = date('Y-m-d');
$next_due_date = strtotime($today.' + '.$months.' Months');
return date('Y-m-d', $next_due_date);
}
Try this (not tested):
function calculate_postpone_due_date($billingcycle)
{
switch($billingcycle)
{
case "Monthly": $months = 1; break;
case "Quarterly": $months = 3; break;
case "Semi-Annually": $months = 6; break;
case "Annually": $months = 12; break;
case "Biennially": $months = 24; break;
case "Triennially": $months = 32; break;
default: return FALSE;
}
$expires = new DateTime('plus '.$months.' months');
$expires->modify('last day of this month');
return $expires->format('Y-m-d');
}
function countDueDate($policy_start_date,$months){
$next_due_date = strtotime($policy_start_date.' + '.$months.' Months');
if($next_due_date<time()){
return countDueDate(date('Y-m-d', $next_due_date), $months);
}else{
return date('Y-m-d',$next_due_date);
}
}
function getModeMonth($premium_mode){
switch ($premium_mode){
case 'yearly': $q=12;break;
case 'monthly': $q=1;break;
case 'quarterly': $q=3;break;
case 'half year': $q=6;break;
default : $q=12;break;
}
return $q;
}
$date=countDueDate(date('Y').'-'.date('m-d',strtotime($policy_start_date)), getModeMonth($premium_mode));

Categories