I want to explode coma from an array value.
My code is.
$to_ids_string = "";
$to_id = $this->input->post('to');
for ($r = 0; $r < count($this->input->post('to')); $r++) {
if ($to_ids_string != "") {
$to_ids_string = $to_ids_string . "," . $to_id[$r];
} else {
$to_ids_string = $to_id[$r];
}
}
echo $to_ids_string;
$a = explode(',', $to_ids_string);
foreach ($a as $item) {
echo("<li>$item</li>");
exit;
}
when i echo $to_ids_string it will return 2,3 but when i loop in foreach it only return 2 not show 3.
Because of your exit, if you use exit like that, then it is the end of your program and it doesn't echo anymore.
You forget to remove exit; from foreach loop. When you write exit, execution of your code stops. Hence you are not getting desired output.
Happens due to exit.
Please remove exit from your code.
I have a query like this inside for loop in codeigniter. But it executes with another values. Not with the values getting through POST method
$j = $_POST['hidden'];
$inv_id = $_POST['invoice_id'];
$sum = '';
for($i = 1; $i <= $j; $i++){
$wh_quantity1 = $_POST['quantity'.$i];
//print_r($wh_quantity1);
if($wh_quantity1 ==''){
$wh_quantity = 0;
}
else{
$wh_quantity = $wh_quantity1;
}
$query = "UPDATE tb_warehouse_stocks SET wh_product_qty = wh_product_qty - $wh_quantity WHERE invoice_id = '$inv_id'";
$this->db->query($query);
$sum += $wh_quantity;
}
Why it is like that. It always updates with greater values than POST value
Put this in .htaccess file
RewriteEngine On
RewriteRule ^ http://example.com/international/university-english-access-course$ http://example.com/website/page/english-access [R=301,L]
Try this in case your dont have all post index
$j = $this->input->post('hidden');
$inv_id = $this->input->post('invoice_id');
$sum = 0;
for ($i = 1; $i <= $j; $i++) {
$wh_quantity = (int) $this->input->post('quantity' . $i);
$sum += $wh_quantity;
}
$query = "UPDATE tb_warehouse_stocks SET wh_product_qty = wh_product_qty - $sum WHERE invoice_id = '$inv_id'";
$this->db->query($query);
I have a cron "time definition"
1 * * * * (every hour at xx:01)
2 5 * * * (every day at 05:02)
0 4 3 * * (every third day of the month at 04:00)
* 2 * * 5 (every minute between 02:00 and 02:59 on fridays)
And I have an unix timestamp.
Is there an obvious way to find (calculate) the next time (after that given timestamp) the job is due to be executed?
I'm using PHP, but the problem should be fairly language-agnostic.
[Update]
The class "PHP Cron Parser" (suggested by Ray) calculates the LAST time the CRON job was supposed to be executed, not the next time.
To make it easier: In my case the cron time parameters are only absolute, single numbers or "*". There are no time-ranges and no "*/5" intervals.
Here's a PHP project that is based on dlamblin's psuedo code.
It can calculate the next run date of a CRON expression, the previous run date of a CRON expression, and determine if a CRON expression matches a given time. You can skip This CRON expression parser fully implements CRON:
Increments of ranges (e.g. */12, 3-59/15)
Intervals (e.g. 1-4, MON-FRI, JAN-MAR )
Lists (e.g. 1,2,3 | JAN,MAR,DEC)
Last day of a month (e.g. L)
Last given weekday of a month (e.g. 5L)
Nth given weekday of a month (e.g. 3#2, 1#1, MON#4)
Closest weekday to a given day of the month (e.g. 15W, 1W, 30W)
https://github.com/mtdowling/cron-expression
Usage (PHP 5.3+):
<?php
// Works with predefined scheduling definitions
$cron = Cron\CronExpression::factory('#daily');
$cron->isDue();
$cron->getNextRunDate();
$cron->getPreviousRunDate();
// Works with complex expressions
$cron = Cron\CronExpression::factory('15 2,6-12 */15 1 2-5');
$cron->getNextRunDate();
This is basically doing the reverse of checking if the current time fits the conditions. so something like:
//Totaly made up language
next = getTimeNow();
next.addMinutes(1) //so that next is never now
done = false;
while (!done) {
if (cron.minute != '*' && next.minute != cron.minute) {
if (next.minute > cron.minute) {
next.addHours(1);
}
next.minute = cron.minute;
}
if (cron.hour != '*' && next.hour != cron.hour) {
if (next.hour > cron.hour) {
next.hour = cron.hour;
next.addDays(1);
next.minute = 0;
continue;
}
next.hour = cron.hour;
next.minute = 0;
continue;
}
if (cron.weekday != '*' && next.weekday != cron.weekday) {
deltaDays = cron.weekday - next.weekday //assume weekday is 0=sun, 1 ... 6=sat
if (deltaDays < 0) { deltaDays+=7; }
next.addDays(deltaDays);
next.hour = 0;
next.minute = 0;
continue;
}
if (cron.day != '*' && next.day != cron.day) {
if (next.day > cron.day || !next.month.hasDay(cron.day)) {
next.addMonths(1);
next.day = 1; //assume days 1..31
next.hour = 0;
next.minute = 0;
continue;
}
next.day = cron.day
next.hour = 0;
next.minute = 0;
continue;
}
if (cron.month != '*' && next.month != cron.month) {
if (next.month > cron.month) {
next.addMonths(12-next.month+cron.month)
next.day = 1; //assume days 1..31
next.hour = 0;
next.minute = 0;
continue;
}
next.month = cron.month;
next.day = 1;
next.hour = 0;
next.minute = 0;
continue;
}
done = true;
}
I might have written that a bit backwards. Also it can be a lot shorter if in every main if instead of doing the greater than check you merely increment the current time grade by one and set the lesser time grades to 0 then continue; however then you'll be looping a lot more. Like so:
//Shorter more loopy version
next = getTimeNow().addMinutes(1);
while (true) {
if (cron.month != '*' && next.month != cron.month) {
next.addMonths(1);
next.day = 1;
next.hour = 0;
next.minute = 0;
continue;
}
if (cron.day != '*' && next.day != cron.day) {
next.addDays(1);
next.hour = 0;
next.minute = 0;
continue;
}
if (cron.weekday != '*' && next.weekday != cron.weekday) {
next.addDays(1);
next.hour = 0;
next.minute = 0;
continue;
}
if (cron.hour != '*' && next.hour != cron.hour) {
next.addHours(1);
next.minute = 0;
continue;
}
if (cron.minute != '*' && next.minute != cron.minute) {
next.addMinutes(1);
continue;
}
break;
}
For anyone interested, here's my final PHP implementation, which pretty much equals dlamblin pseudo code:
class myMiniDate {
var $myTimestamp;
static private $dateComponent = array(
'second' => 's',
'minute' => 'i',
'hour' => 'G',
'day' => 'j',
'month' => 'n',
'year' => 'Y',
'dow' => 'w',
'timestamp' => 'U'
);
static private $weekday = array(
1 => 'monday',
2 => 'tuesday',
3 => 'wednesday',
4 => 'thursday',
5 => 'friday',
6 => 'saturday',
0 => 'sunday'
);
function __construct($ts = NULL) { $this->myTimestamp = is_null($ts)?time():$ts; }
function __set($var, $value) {
list($c['second'], $c['minute'], $c['hour'], $c['day'], $c['month'], $c['year'], $c['dow']) = explode(' ', date('s i G j n Y w', $this->myTimestamp));
switch ($var) {
case 'dow':
$this->myTimestamp = strtotime(self::$weekday[$value], $this->myTimestamp);
break;
case 'timestamp':
$this->myTimestamp = $value;
break;
default:
$c[$var] = $value;
$this->myTimestamp = mktime($c['hour'], $c['minute'], $c['second'], $c['month'], $c['day'], $c['year']);
}
}
function __get($var) {
return date(self::$dateComponent[$var], $this->myTimestamp);
}
function modify($how) { return $this->myTimestamp = strtotime($how, $this->myTimestamp); }
}
$cron = new myMiniDate(time() + 60);
$cron->second = 0;
$done = 0;
echo date('Y-m-d H:i:s') . '<hr>' . date('Y-m-d H:i:s', $cron->timestamp) . '<hr>';
$Job = array(
'Minute' => 5,
'Hour' => 3,
'Day' => 13,
'Month' => null,
'DOW' => 5,
);
while ($done < 100) {
if (!is_null($Job['Minute']) && ($cron->minute != $Job['Minute'])) {
if ($cron->minute > $Job['Minute']) {
$cron->modify('+1 hour');
}
$cron->minute = $Job['Minute'];
}
if (!is_null($Job['Hour']) && ($cron->hour != $Job['Hour'])) {
if ($cron->hour > $Job['Hour']) {
$cron->modify('+1 day');
}
$cron->hour = $Job['Hour'];
$cron->minute = 0;
}
if (!is_null($Job['DOW']) && ($cron->dow != $Job['DOW'])) {
$cron->dow = $Job['DOW'];
$cron->hour = 0;
$cron->minute = 0;
}
if (!is_null($Job['Day']) && ($cron->day != $Job['Day'])) {
if ($cron->day > $Job['Day']) {
$cron->modify('+1 month');
}
$cron->day = $Job['Day'];
$cron->hour = 0;
$cron->minute = 0;
}
if (!is_null($Job['Month']) && ($cron->month != $Job['Month'])) {
if ($cron->month > $Job['Month']) {
$cron->modify('+1 year');
}
$cron->month = $Job['Month'];
$cron->day = 1;
$cron->hour = 0;
$cron->minute = 0;
}
$done = (is_null($Job['Minute']) || $Job['Minute'] == $cron->minute) &&
(is_null($Job['Hour']) || $Job['Hour'] == $cron->hour) &&
(is_null($Job['Day']) || $Job['Day'] == $cron->day) &&
(is_null($Job['Month']) || $Job['Month'] == $cron->month) &&
(is_null($Job['DOW']) || $Job['DOW'] == $cron->dow)?100:($done+1);
}
echo date('Y-m-d H:i:s', $cron->timestamp) . '<hr>';
Use this function:
function parse_crontab($time, $crontab)
{$time=explode(' ', date('i G j n w', strtotime($time)));
$crontab=explode(' ', $crontab);
foreach ($crontab as $k=>&$v)
{$v=explode(',', $v);
foreach ($v as &$v1)
{$v1=preg_replace(array('/^\*$/', '/^\d+$/', '/^(\d+)\-(\d+)$/', '/^\*\/(\d+)$/'),
array('true', '"'.$time[$k].'"==="\0"', '(\1<='.$time[$k].' and '.$time[$k].'<=\2)', $time[$k].'%\1===0'),
$v1
);
}
$v='('.implode(' or ', $v).')';
}
$crontab=implode(' and ', $crontab);
return eval('return '.$crontab.';');
}
var_export(parse_crontab('2011-05-04 02:08:03', '*/2,3-5,9 2 3-5 */2 *'));
var_export(parse_crontab('2011-05-04 02:08:03', '*/8 */2 */4 */5 *'));
Edit Maybe this is more readable:
<?php
function parse_crontab($frequency='* * * * *', $time=false) {
$time = is_string($time) ? strtotime($time) : time();
$time = explode(' ', date('i G j n w', $time));
$crontab = explode(' ', $frequency);
foreach ($crontab as $k => &$v) {
$v = explode(',', $v);
$regexps = array(
'/^\*$/', # every
'/^\d+$/', # digit
'/^(\d+)\-(\d+)$/', # range
'/^\*\/(\d+)$/' # every digit
);
$content = array(
"true", # every
"{$time[$k]} === 0", # digit
"($1 <= {$time[$k]} && {$time[$k]} <= $2)", # range
"{$time[$k]} % $1 === 0" # every digit
);
foreach ($v as &$v1)
$v1 = preg_replace($regexps, $content, $v1);
$v = '('.implode(' || ', $v).')';
}
$crontab = implode(' && ', $crontab);
return eval("return {$crontab};");
}
Usage:
<?php
if (parse_crontab('*/5 2 * * *')) {
// should run cron
} else {
// should not run cron
}
Created javascript API for calculating next run time based on #dlamblin idea. Supports seconds and years. Have not managed to test it fully yet so expect bugs but let me know if find any.
Repository link: https://bitbucket.org/nevity/cronner
Check this out:
It can calculate the next time a scheduled job is supposed to be run based on the given cron definitions.
Thanks for posting this code. It definitely helped me out, even 6 years later.
Trying to implement I found a small bug.
date('i G j n w', $time) returns a 0 padded integer for the minutes.
Later in the code, it does a modulus on that 0 padded integer. PHP doesn't seem to handle this as expected.
$ php
<?php
print 8 % 5 . "\n";
print 08 % 5 . "\n";
?>
3
0
As you can see, 08 % 5 returns 0, whereas 8 % 5 returns the expected 3. I couldn't find a non padded option for the date command. I tried fiddling with the {$time[$k]} % $1 === 0 line (like changing {$time[$k]} to ({$time[$k]}+0), but couldn't get it to drop the 0 padding during the modulus.
So, I ended up just changing the original value returned by the date function and removed the 0 by running $time[0] = $time[0] + 0;.
Here is my test.
<?php
function parse_crontab($frequency='* * * * *', $time=false) {
$time = is_string($time) ? strtotime($time) : time();
$time = explode(' ', date('i G j n w', $time));
$time[0] = $time[0] + 0;
$crontab = explode(' ', $frequency);
foreach ($crontab as $k => &$v) {
$v = explode(',', $v);
$regexps = array(
'/^\*$/', # every
'/^\d+$/', # digit
'/^(\d+)\-(\d+)$/', # range
'/^\*\/(\d+)$/' # every digit
);
$content = array(
"true", # every
"{$time[$k]} === $0", # digit
"($1 <= {$time[$k]} && {$time[$k]} <= $2)", # range
"{$time[$k]} % $1 === 0" # every digit
);
foreach ($v as &$v1)
$v1 = preg_replace($regexps, $content, $v1);
$v = '('.implode(' || ', $v).')';
}
$crontab = implode(' && ', $crontab);
return eval("return {$crontab};");
}
for($i=0; $i<24; $i++) {
for($j=0; $j<60; $j++) {
$date=sprintf("%d:%02d",$i,$j);
if (parse_crontab('*/5 * * * *',$date)) {
print "$date yes\n";
} else {
print "$date no\n";
}
}
}
?>
My answer is not unique. Just a replica of #BlaM answer written in java because PHP's date and time is a bit different from Java.
This program assumes that the CRON expression is simple. It can only contain digits or *.
Minute = 0-60
Hour = 0-23
Day = 1-31
MONTH = 1-12 where 1 = January.
WEEKDAY = 1-7 where 1 = Sunday.
Code:
package main;
import java.util.Calendar;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class CronPredict
{
public static void main(String[] args)
{
String cronExpression = "5 3 27 3 3 ls -la > a.txt";
CronPredict cronPredict = new CronPredict();
String[] parsed = cronPredict.parseCronExpression(cronExpression);
System.out.println(cronPredict.getNextExecution(parsed).getTime().toString());
}
//This method takes a cron string and separates entities like minutes, hours, etc.
public String[] parseCronExpression(String cronExpression)
{
String[] parsedExpression = null;
String cronPattern = "^([0-9]|[1-5][0-9]|\\*)\\s([0-9]|1[0-9]|2[0-3]|\\*)\\s"
+ "([1-9]|[1-2][0-9]|3[0-1]|\\*)\\s([1-9]|1[0-2]|\\*)\\s"
+ "([1-7]|\\*)\\s(.*)$";
Pattern cronRegex = Pattern.compile(cronPattern);
Matcher matcher = cronRegex.matcher(cronExpression);
if(matcher.matches())
{
String minute = matcher.group(1);
String hour = matcher.group(2);
String day = matcher.group(3);
String month = matcher.group(4);
String weekday = matcher.group(5);
String command = matcher.group(6);
parsedExpression = new String[6];
parsedExpression[0] = minute;
parsedExpression[1] = hour;
parsedExpression[2] = day;
//since java's month start's from 0 as opposed to PHP which starts from 1.
parsedExpression[3] = month.equals("*") ? month : (Integer.parseInt(month) - 1) + "";
parsedExpression[4] = weekday;
parsedExpression[5] = command;
}
return parsedExpression;
}
public Calendar getNextExecution(String[] job)
{
Calendar cron = Calendar.getInstance();
cron.add(Calendar.MINUTE, 1);
cron.set(Calendar.MILLISECOND, 0);
cron.set(Calendar.SECOND, 0);
int done = 0;
//Loop because some dates are not valid.
//e.g. March 29 which is a Friday may never come for atleast next 1000 years.
//We do not want to keep looping. Also it protects against invalid dates such as feb 30.
while(done < 100)
{
if(!job[0].equals("*") && cron.get(Calendar.MINUTE) != Integer.parseInt(job[0]))
{
if(cron.get(Calendar.MINUTE) > Integer.parseInt(job[0]))
{
cron.add(Calendar.HOUR_OF_DAY, 1);
}
cron.set(Calendar.MINUTE, Integer.parseInt(job[0]));
}
if(!job[1].equals("*") && cron.get(Calendar.HOUR_OF_DAY) != Integer.parseInt(job[1]))
{
if(cron.get(Calendar.HOUR_OF_DAY) > Integer.parseInt(job[1]))
{
cron.add(Calendar.DAY_OF_MONTH, 1);
}
cron.set(Calendar.HOUR_OF_DAY, Integer.parseInt(job[1]));
cron.set(Calendar.MINUTE, 0);
}
if(!job[4].equals("*") && cron.get(Calendar.DAY_OF_WEEK) != Integer.parseInt(job[4]))
{
Date previousDate = cron.getTime();
cron.set(Calendar.DAY_OF_WEEK, Integer.parseInt(job[4]));
Date newDate = cron.getTime();
if(newDate.before(previousDate))
{
cron.add(Calendar.WEEK_OF_MONTH, 1);
}
cron.set(Calendar.HOUR_OF_DAY, 0);
cron.set(Calendar.MINUTE, 0);
}
if(!job[2].equals("*") && cron.get(Calendar.DAY_OF_MONTH) != Integer.parseInt(job[2]))
{
if(cron.get(Calendar.DAY_OF_MONTH) > Integer.parseInt(job[2]))
{
cron.add(Calendar.MONTH, 1);
}
cron.set(Calendar.DAY_OF_MONTH, Integer.parseInt(job[2]));
cron.set(Calendar.HOUR_OF_DAY, 0);
cron.set(Calendar.MINUTE, 0);
}
if(!job[3].equals("*") && cron.get(Calendar.MONTH) != Integer.parseInt(job[3]))
{
if(cron.get(Calendar.MONTH) > Integer.parseInt(job[3]))
{
cron.add(Calendar.YEAR, 1);
}
cron.set(Calendar.MONTH, Integer.parseInt(job[3]));
cron.set(Calendar.DAY_OF_MONTH, 1);
cron.set(Calendar.HOUR_OF_DAY, 0);
cron.set(Calendar.MINUTE, 0);
}
done = (job[0].equals("*") || cron.get(Calendar.MINUTE) == Integer.parseInt(job[0])) &&
(job[1].equals("*") || cron.get(Calendar.HOUR_OF_DAY) == Integer.parseInt(job[1])) &&
(job[2].equals("*") || cron.get(Calendar.DAY_OF_MONTH) == Integer.parseInt(job[2])) &&
(job[3].equals("*") || cron.get(Calendar.MONTH) == Integer.parseInt(job[3])) &&
(job[4].equals("*") || cron.get(Calendar.DAY_OF_WEEK) == Integer.parseInt(job[4])) ? 100 : (done + 1);
}
return cron;
}
}