I am trying to generate the range of days, from 1 to 28, with the English ordinal suffix for the day of the month. For example: 1st of month, 2nd of month...
for($i = 1; $i <= 28; $i++)
{
$arrayRange[] = date('dS', strtotime($i));
}
echo "<pre>";
print_r($arrayRange);
echo "</pre>";
Output:
Array
(
[0] => 01st
[1] => 01st
[2] => 01st
...
[26] => 01st
[27] => 01st
)
What am I doing wrong..?
You should pass correct timestamp as the second parameter of date function and use j (without leading zero) day format:
list($m, $y) = explode('-', date('m-Y'));
for($d = 1; $d <= 28; $d++)
{
$arrayRange[] = date('jS', mktime(0, 0, 0, $m, $d, $y));
}
echo "<pre>";
print_r($arrayRange);
echo "</pre>";
Try this, it uses the contextual date functionality of '+1 day' etc to register your integer as a day :)
To answer your second question - as in what you're doing wrong - you're passing an integer to a function that expects a string.
<?php
for($i = 0; $i <= 27; $i++)
{
//The February is there to keep '1st' a '1st' even on days when it's not
//the '31st'
$arrayRange[] = date('dS', strtotime("1st february +".$i.' day'));
}
echo "<pre>";
print_r($arrayRange);
echo "</pre>";
Output:
Array
(
[0] => 01st
[1] => 02nd
...
[28] => 28th
)ยจ
Edit:
To remove the 0s, you can use ltrim() like this:
$arrayRange[$i] = ltrim(date('dS', strtotime("1st february +".$i.' day')), "0");
Which will give you an output like this
[0] => 1st
[1] => 2nd
...
[28] => 28th
Edit 2:
Fixed it. Props to MLF for noticing the mistake.
You can use something like this:
$arrayRange[] = (new DateTime('Aug '.$i))->format('jS');
Related
I need to add days (input type number + input type date) but the result must be an array so I can INSERT one after another into the Database.
Here's the code (After HTML Form submitted):
<?php
$start_date = '2017-12-22';
$duration = '3';
$d = new DateTime($start_date);
$t = $d->getTimestamp();
// loop for X days
for($i=0; $i <= $duration; $i++){
// add 1 day to timestamp-
$addDay = 86400;
// get what day it is next day
$nextDay = date('w', ($t + $addDay));
// if it's Saturday or Sunday get $i-1
if($nextDay === 6 || $nextDay === 7) {
$i --;
}
// modify timestamp, add 1 day
$t = $t + $addDay;
$d->setTimestamp($t);
$day_off = $d->format( 'Y-m-d' ). "<br />";
echo $day_off;
$query = "INSERT SQL";
}
?>
From echo $day_off result I get:
2017-12-23
2017-12-24
2017-12-25
2017-12-26
Instead of 23, 24, 25, 26. I need to get the result below:
2017-12-22
2017-12-25
2017-12-26
2017-12-27
22 is the input date, start from 25 because 23 and 24 are Sat and Sun and weekends need to be excluded.
How can I achieve this result? I've been searching on the net but unfortunately, I couldn't find what I needed.
#C. Geek answer made it to works, but I have a more complex question here, since my account are not eligible to ask more question so I'll ask here.
So here's what I've tried so far (with #C. Geek answer) :
<?php
// loop for X days
for($i=0; $i < $duration; $i++){
$d = strtotime("$start_date +$i weekdays");
$t = strftime("%Y-%m-%d",$d);
$day_off[] = $t;
foreach($day_off as $dayoff) {
$data_holiday = mysqli_fetch_array(mysqli_query($con, "SELECT * FROM `holiday_master_data` WHERE `date` = '$dayoff' "));
}
$holiday[] = $data_holiday['date'];
$date = array_diff($day_off, $holiday);
$dayoff_ = $holiday;
?>
Start date : 2017-12-29
Duration : 5 days
From print_r($day_off); I'm getting this result :
Array ( [0] => 2017-12-29 ) Array ( [0] => 2017-12-29 [1] => 2018-01-01 ) Array ( [0] => 2017-12-29 [1] => 2018-01-01 [2] => 2018-01-02 )
And from print_r($holiday); I'm getting this result :
Array ( [0] => ) Array ( [0] => [1] => 2018-01-01 ) Array ( [0] => [1] => 2018-01-01 [2] => ) Array ( [0] => [1] => 2018-01-01 [2] => [3] => ) Array ( [0] => [1] => 2018-01-01 [2] => [3] => [4] => )
The national date fetched from database is 2018-01-01 with 5 looping result, the final date result I need to make are 29 Dec, 02 Jan 03 Jan and 04 Jan, 05 Jan.
Any help will be much appreciated.
Thanks.
https://stackoverflow.com/a/4261223/6288442
If you are limiting to weekdays use the string weekdays.
echo date ( 'Y-m-j' , strtotime ( '3 weekdays' ) );
This should jump you ahead by 3 weekdays, so if it is Thursday it will
add the additional weekend time.
Source: http://www.php.net/manual/en/datetime.formats.relative.php
As for formatting:
http://php.net/manual/en/function.strftime.php
string strftime ( string $format [, int $timestamp = time() ] )
If you need more help with writing the code than these, please do tell in a comment
Here is my full answer:
$start_date = '2017-12-22';
$duration = 3;
$arr=null;
for($i=0; $i <= $duration; $i++){
$d = strtotime("$start_date +$i weekdays");
$t = strftime("%Y-%m-%d",$d);
$arr[]=$t;
}
Get the holidays before the looping, then in the loop, check if date is in_array before adding it to $arr.
e.g.
$start_date = '2017-12-22';
$data_holiday = mysqli_fetch_array(mysqli_query($con, "SELECT * FROM `holiday_master_data` WHERE YEAR(`date`) BETWEEN YEAR('$start_date') AND YEAR('$start_date')+1 "));
$holidays =
$duration = 3;
$arr=null;
for($i=0; $i <= $duration; $i++){
$d = strtotime("$start_date +$i weekdays");
$t = strftime("%Y-%m-%d",$d);
if(!in_array($t,$data_holiday))
$arr[]=$t;
}
FINALLY!! After several hours I fixed everything. Here's the code how I manage to skip (Sun and Monday) and also Skip the Holiday's fetched from the database (based on #C.Geek answers + several tweaking):
<?php
include 'conn.php';
$start_date = mysqli_real_escape_string($con, $_POST['start_date']);
$duration = mysqli_real_escape_string($con, $_POST['duration']);
// loop for X days
for($i=0; $i <= $duration; $i++){
$d = strtotime("$start_date +$i weekdays");
$t = explode(", ", strftime("%Y-%m-%d", $d));
foreach ($t as $date) {
$to_encode = array("date" => $date);
$date_where = $to_encode['date'];
$data_holiday = mysqli_fetch_array(mysqli_query($con, "SELECT `date` AS '0' FROM `holiday_master_data` WHERE DATE(`date`) BETWEEN DATE('$date_where') AND DATE('$date_where') + 1 GROUP BY `id` "));
$encode_holiday = array("date" => $data_holiday[0]);
break;
}
$holiday = array_unique($encode_holiday);
$dayoff = array_diff($t, $holiday);
foreach($dayoff as $date) {
$query = mysqli_query($con, "INSERT INTO ");
if ($query) {
echo "<script>alert('Absence Saved'); window.location ='document.php' </script>";
} else {
echo "<script>alert('Gagal'); window.location ='document.php' </script>";
}
}
}
?>
Hope this helps anyone seeking the same problem I had.
Cheers.
I'm a new to PHP and don't know if my request is possible:
I'd need to get an array with the days of the current week and also indicate for each day if it's the first, second, third, fourth or fifth occurrence of that date for the month.
Examples
For the 1st week of August 2016, it would be:
monday1
tuesday1
wednesday1
thursday1
friday1
saturday1
sunday1
But for the last week of August 2016 (which begins in August and ends in September) it would be:
monday5
tuesday5
wednesday1
thursday1
friday1
saturday1
sunday1
I tried this, but it only works for the current day.
$week_of_the_month = ceil(date('d', $time)/7);
$jd = cal_to_jd(CAL_GREGORIAN,date("m"),date("d"),date("Y"));
echo jddayofweek($jd,1).$week_of_the_month;
$d = new DateTime();
$days = [];
for ($i = 0; $i < 7; $i++) {
$date = $d->format('j');
$days[$date] = $d->format('l - ') . ceil($date/7);
$d->add(new DateInterval('P1D'));
}
That will work for the current date, but you can test it on weeks that cross over two months by setting a specific date to work with:
$d = new DateTime('2016-08-31');
The result is as follows:
print_r($days);
Array
(
[31] => Wednesday - 5
[1] => Thursday - 1
[2] => Friday - 1
[3] => Saturday - 1
[4] => Sunday - 1
[5] => Monday - 1
[6] => Tuesday - 1
)
If you want the dates to always start on the Monday of the current week, the DateTime constructor allows you to pass in a string as such:
$d = new DateTime('monday this week');
Today is Thursday, but it gives:
Array
(
[1] => Monday - 1
[2] => Tuesday - 1
[3] => Wednesday - 1
[4] => Thursday - 1
[5] => Friday - 1
[6] => Saturday - 1
[7] => Sunday - 1
)
Changing Language
If you want to change the language of the date output, that is a separate topic (see here). You will need to have the locales/extensions installed on your system. If you don't want to go down that route, you could just map the days into your language yourself:
$intlDays = [
'Monday' => 'Lundi',
'Tuesday' => 'Mardi',
'Wednesday' => 'Mercredi',
'Thursday' => 'Jeudi',
'Friday' => 'Vendredi',
'Saturday' => 'Samedi',
'Sunday' => 'Dimanche'
];
$d = new DateTime('monday this week');
$days = [];
for ($i = 0; $i < 7; $i++) {
$date = $d->format('j');
$output = $d->format('l - ') . ceil($date/7);
$output = str_replace(array_keys($intlDays), $intlDays, $output);
$days[$date] = $output;
$d->add(new DateInterval('P1D'));
}
I have fetched a current month from my DB which is basically a join date of the user. Lets say the use joined this month and it is May. The code I do to fetch the month name is like this:
$months = array();
array_push($months,date("F",strtotime($me['joinTime'])));
In this case I add the start month to the array, which in this case is May... Now what I'd like to do is as the months go by, I'd like to add each new month to the array.. So for instance in a few days its June, and when June kicks in, I'll add that Month as well to the array.. So my question here is, how can I get the rest of the month names from the start date (May).
I need June, July, August, September, October, November, December...
If the start month was April I'd add May into the array as well...
Can someone help me out with this ?
First you need to get he month number and than you need to use a loop through to end of the year that is 12. For each month number you also need the month name so use DateTime createFromFormat.
Online Check
$months = array();
$num = date("n",strtotime($me['joinTime']));
array_push($months, date("F", strtotime('2016-05-17 16:41:51')));
for($i = ($num + 1); $i <= 12; $i++){
$dateObj = DateTime::createFromFormat('!m', $i);
array_push($months, $dateObj->format('F'));
}
print_r($months); // Array ( [0] => May [1] => June [2] => July [3] => August [4] => September [5] => October [6] => November [7] => December )
Yo can also put it like
$array = array();
array_push($array, date('F')) ;
for ($i=1; $i<= 12 - date('m'); $i++ ){
array_push($array, date('F', strtotime("+$i months"))) ;
}
print "<pre>";print_r($array);
Here we will be using DatePeriod which allows iteration over a set of dates and times, recurring at regular intervals, over a given period.
So we got the end date and we have the start date and then calculated the interval. And then looping over the period we got the array of months.
// current date : 20 Feb 2019
$startDate = new \DateTime('first day of next month');
$endDate = new \DateTime('1st january next year');
$interval = new \DateInterval('P1M');
$period = new \DatePeriod($startDate, $interval, $endDate);
// Start array with current date
$dates = [];
// Add all remaining dates to array
foreach ($period as $date) {
array_push($dates, $date->Format('F'));
}
// output
print_r($dates); die;
Array ( [0] => March [1] => April [2] => May [3] => June [4] => July [5] => August [6] => September [7] => October [8] => November [9] => December )
I was wondering if there is a better solution to loop through an array from mid to end then from start to mid. Particularly for an associative array.
So for example if there is an associative array with the keys
$dow = array(Mon => etc, Tue => etc, Wed => etc, Thr => etc .. to .. Sun => etc).
I would start searching the array from Thurs to find the next day with something specific which could be anyday but happens to be on Tues, I usually iterate from Thurs (by index) to Sunday then, reset and start again from Monday to Wed and find the target when reaching Tues.
I count the index via an id and when it reaches 6 reset the id to 0
$id = 3 // Found day is Thursday id
//Loop function starts here
$id++; // start search from one day above found day
if ($id >= 6){ //when reaching Sunday
$id = 0 // start search from monday
}
// check array here for that specific thing
So the question is to ask if there is a more simple solution than this, ie split array from index thursday to sunday and add it onto the beginning of the array and then do the loop without having to count an index or if there are any other solutions without using the count index.
You can try with array_splice:
$array = array(1,2,3,4,5,6,7);
$lastDays = array_splice($array, 3);
$firstDays = $array;
print_r(array('first days' => $firstDays, 'last days' => $lastDays));
If the day is not in $lastDays (use a boolean like $matchFound) then you would search in $firstDays.
Or just use with array_merge:
$array = array(1,2,3,4,5,6,7);
$array = array_merge(array_splice($array, 3), $array);
print_r($array);
where output is:
Array
(
[0] => 4
[1] => 5
[2] => 6
[3] => 7
[4] => 1
[5] => 2
[6] => 3
)
and then you can search with a foreach.
maybe a foreach would be more efficient. hope this helps.
$id = 3 // Found day is Thursday id
$i =0;
//Loop function starts here
foreach($dow as $idx)
if($id == $i):
else if($i > $id):
endif;
if($i == count($dow)){$i=0;}else{$i++;}
endforeach;
<?php
$dow = array("mon","tue","wed","thu","fri","sat","sun");
$pick_a_day = 2; // user input; NON zero based. monday = 1
$pick_a_day--; // make it zero based to use in code
foreach($dow as $inc => $an_element )
{
echo $dow[($pick_a_day+(count($dow))) % (count($dow))]." - loop number:".($inc+1)."\n";
$pick_a_day++;
}
?>
output
tue - loop number:1
wed - loop number:2
thu - loop number:3
fri - loop number:4
sat - loop number:5
sun - loop number:6
mon - loop number:7
Maybe not the best solution, but a solution:
function half($array) {
$h = sizeof($array) / 2;
$a1 = array_splice($array, $h);
$a2 = array_splice($array, 0);
$res = array_merge($a1, $a2);
return $res;
}
$dow = array('Mon' => 'etc1', 'Tue' => 'etc2', 'Wed' => 'etc3', 'Thr' => 'etc4', 'Fri' => 'etc5', 'Sat' => 'etc6', 'Sun' => 'etc7');
$b = half($dow);
Now you can go through with a foreach, or how would you like. Result of $b:
Array
(
[Thr] => etc4
[Fri] => etc5
[Sat] => etc6
[Sun] => etc7
[Mon] => etc1
[Tue] => etc2
[Wed] => etc3
)
I have an array with timestamps. If this timestamps are between two given dates I need to collect them into another array.
Let me use an example:
Lets say $array1[] has:
Array ( [0] => 1299147500 [1] => 1299147453 [2] => 1299146476 [3] => 1299143220 [4] => 1297934349 [5] => 1297845742 [6] => 1297695551 [7] => 1296134251 [8] => 1295948452 [9] => 1295554308 [10] => 1295369389 [11] => 1295345559 [12] => 1295261432 [13] => 1295014784 [14] => 1294929846 [15] => 1294832875 )
I need to create $array2[] with those values from $array1[] that are between Thursday February 17, 2011 and Thursday March 3, 2011
How can I do this?
Thanks a ton
$low = strtotime('Thursday February 17, 2011');
$high = strtotime('Thursday March 3, 2011');
$array2 = array();
foreach($array1 as $timestamp) {
if ($low <= $timestamp && $timestamp <= $high) {
$array2[] = $timestamp;
}
}
an alternative using array_filter which will maintain the keys.
$low = strtotime('Thursday February 17, 2011');
$high = strtotime('Thursday March 3, 2011');
$array2 = array_filter($array1, function($timestamp) use ($low, $high) {
return $low <= $timestamp && $timestamp <= $high;
});
Convert first and last date to timestamps using strtotime()
For each item in the array, if it is between min and max, copy it to the second array.
Sort the array of timestamps
http://codepad.org/mDvRJ534
<?php
$array1 = array(1299147500,1299147453,1299146476,1299143220,1297934349,1297845742,1297695551,1296134251,1295948452,1295554308,1295369389,1295345559,1295261432,1295014784,1294929846,1294832875);
$array2 = array();
$date1 = strtotime('Thursday February 17, 2011');
$date2 = strtotime('Thursday March 3, 2011');
foreach($array1 as $timestamp){
if($timestamp <= $date2 && $timestamp >= $date1)
$array2[] = $timestamp;
}
echo 'date1 = '.$date1."\n";
echo 'date2 = '.$date2."\n";
print_r($array2);
Someone answered this in another post over here mate How to check if a date is in a given range?