I had a technical test and one of the things I had to do is a program that has an input of two dates, and has to output the months with 5 sundays between these two dates. A string $dates has the two dates in the same line
example: juny 2014 october 2014
I need to use these two dates to do stuff.
In this point, I was thinking to do two separate strings to work with each date, like this:
$arrayDates = split(" ",$dates);
Then:
$firstDate = $dates[0].$dates[1];
$secondDate = $dates[2].$dates[3];
But I see this way of doing things too obvious and not dynamyc. Somebody knows a better or more elegant/apropriate way to do this?
Edit: this is the full code
<?php
date_default_timezone_set('UTC');
//output month with five sundays
foreach(file($argv[1]) as $date){
$totalDays=prepareDateArray($date);
calculateSundays($totalDays,$date);
}
function prepareDateArray(&$date){
$regexPattern = "/([a-z]+ [0-9]{4})/i";
$matchCount = preg_match($regexPattern, $date, $matches);
if($matchCount == 0)return;
$date = preg_replace("# +#",' ',$date);
$date = split(' ',$date);
$totalDays = parseDate($date);
return $totalDays;
}
function parseDate(&$date){
$nIndex = count($date);
if($nIndex%2==0){
//Add first day of the month to first Date
$date[0] = '01-'.$date[0].'-'.$date[1];
//Get lastMonthDay
$lastMonthDay = date('t', strtotime($date[2].'-'.$date[3]));
//Add last day of the month to secondDate
$date[1] = $lastMonthDay.'-'.$date[2].'-'.$date[3];
//Calculates distance between dates in days
$firstDate = strtotime($date[0]);
$secondDate = strtotime($date[1]);
if($firstDate>$secondDate)exit('First date must be earlier than second date');
$datediff = $secondDate - $firstDate;
unset($date[2],$date[3]);
return $datediff/(60*60*24);
}else{
exit('Insert valid input');
}
}
function calculateSundays($totalDays,$tempDate){
$sundays=0;
$output=0;
for($day=1;$day<=$totalDays;$day++)
{
$dayOfWeek = date('w', strtotime($tempDate[0].' + '.$day.' days'));
if($dayOfWeek == 0)$sundays++;
if($sundays == 5){
$output++;
$sundays = 0;
}
}
if($output == 0)print("Wrong date \n");
else print($output."\n");
}
?>
You can create a simple regex for this operation can you check out the code below;
<?PHP
header('Content-Type: text/plain; charset=utf8');
$regexPattern = "/([a-z]+ [0-9]{4})/i"; //This will match a letters + space + 4 digit number together
$inputString = "juny 2014 october 2014 february 2016 march 2017 july 2010 FEBRUARY 2014";
$matchCount = preg_match_all($regexPattern, $inputString, $matches);
print_r($matches);
?>
You will get an output like that;
Array
(
[0] => Array
(
[0] => juny 2014
[1] => october 2014
[2] => february 2016
[3] => march 2017
[4] => july 2010
[5] => FEBRUARY 2014
)
[1] => Array
(
[0] => juny 2014
[1] => october 2014
[2] => february 2016
[3] => march 2017
[4] => july 2010
[5] => FEBRUARY 2014
)
)
And working example is here http://ideone.com/LuQqEN
i use same as cihan-uygun code but my Regx expression is little change
here is code
example :
I need dates output from these strings
2020 Ice Harbor All-Ages Master/Expert - Nov 21, 2020
2020 Ice Harbor Scholastic Open (Nov 21, 2020 - Nov 22, 2020)
<?php $regexPattern = "/[A-Z]{3} [0-9]{2}\, [0-9]{4}/i";
preg_match_all($regexPattern, $stringgosehere, $matches); ?>
Related
Background information:
The log file is copied and read out at regular intervals.
Log file lines do not have a year specification.
Months are continuous.
Before January is always the previous year.
If January lines do not appear in the log file, then it is only about the current year. Example:
2023 mar,
2023 apr,
2023 may,
2023 jun
If January occurs one or more times in the month cycle, then the current year is from the beginning of the last occurrence (January). Example:
2021 nov,
2021 dec,
2021 dec
2022 jan, // new year
2022 jan,
2022 feb,
...
2022 dec,
2023 jan, // new year, last jan = actual year
2023 jan,
2023 feb,
...
Code:
Recognize which year it is based on the 3-letters and lines and add the correct year to each line.
$arr = [
// without first Dec, Jan and Jan lines:
// all subsequent lines are the current year
"Dec 23 21:37:56 hello",
"Jan 12 02:08:23 hello",
"Jan 16 17:34:33 hello",
"Feb 4 12:21:09 hello",
"Mar 19 17:07:26 hello",
"Apr 1 00:00:03 hello",
"Apr 12 23:07:39 hello",
"May 21 04:09:34 hello",
"Jun 7 23:34:56 hello",
"Jul 1 14:45:34 hello",
"Aug 13 11:37:23 hello",
"Sep 29 07:36:03 hello",
"Oct 30 09:01:00 hello",
"Nov 10 11:00:03 hello",
"Dec 25 21:47:51 hello"
];
Create a function to find the years.
function setYear()
{
global $arr, $y;
$first = explode(' ', $arr[array_key_first($arr)]);
// if the 1st line doesn't start with Jan, then it's the previous year.
if (!in_array('01', $first)) {
$y = date("Y", strtotime("-1 year"));
} else {
$y = date("Y");
}
return $y;
}
Convert date year and month integer
$arr = preg_replace_callback(
'/^(\w+)\s+(\d+)\s/',
function ($matches) {
global $y;
$yy = setYear($y);
return date($yy . ' m d', strtotime($matches[0] . ' ' . date("Y"))) . ' ';
},
$arr
);
echo '<pre>';
print_r($arr);
echo '</pre>';
Unexpected result:
Array
(
[0] => 2022 12 23 21:37:56 hello
[1] => 2022 01 12 02:08:23 hello
[2] => 2022 01 16 17:34:33 hello
[3] => 2022 02 04 12:21:09 hello
[4] => 2022 03 19 17:07:26 hello
// ...
[9] => 2022 11 10 11:00:03 hello
[10] => 2022 12 25 21:47:51 hello
)
Expected result:
Array
(
[0] => 2023 12 23 21:37:56 hello
[1] => 2022 01 12 02:08:23 hello
[2] => 2022 01 16 17:34:33 hello
[3] => 2022 02 04 12:21:09 hello
[4] => 2022 03 19 17:07:26 hello
// ...
[9] => 2022 11 10 11:00:03 hello
[10] => 2022 12 25 21:47:51 hello
)
Use a static variable instead of bringing global variables into scope with global. The static keyword will ensure that the previous iterations' declaration is retained and is accessible. If Jan is encountered or was encountered before, set the flag as true. Until the flag is set to true, subtract 1 year from the date's year.
Code: (Demo)
var_export(
preg_replace_callback(
'/^([a-z]{3}) +\d+/i',
function($m) {
static $encounteredJan = false;
$encounteredJan = $encounteredJan || $m[1] === 'Jan';
return date('Y m d', strtotime($m[0] . ($encounteredJan ? '' : ' -1 year')));
},
$arr
)
);
If you cannot rely on Jan existing in the dataset, then (assuming you never need to jump more than one year forward), just check if the current month is less than the last encountered month. If, say, going from Sep to Apr (10 to 4), then you can safely assume that the year should be increased/incremented.
Code: (Demo)
var_export(
preg_replace_callback(
'/^([a-z]{3}) +\d+/i',
function($m) {
static $lastMonthInt = 0;
static $year = null;
$year ??= date('Y', strtotime('-1 year'));
$currentMonthInt = date('n', strtotime($m[1]));
if ($currentMonthInt < $lastMonthInt) {
++$year;
}
$lastMonthInt = $currentMonthInt;
return "$year " . date('m d', strtotime($m[0]));
},
$arr
)
);
Final edit:
To ensure that the highest generated year is the current year, use array_reverse() to process the data from latest entry to the earliest entry. Compare the standardized timestamp expression against the previous timestamp. When the current stamp is greater than the last, decrement the year. When finished processing, call array_reverse() on the result to return it to its original order.
Code: (Demo)
var_export(
array_reverse(
preg_replace_callback(
'/^[a-z]{3} +\d+ \d\d:\d\d:\d\d/i',
function($m) {
static $lastStamp = null;
static $year = null;
$year ??= date('Y');
$currentStamp = date('m d H:i:s', strtotime($m[0]));
if ($currentStamp > ($lastStamp ?? $currentStamp)) {
--$year;
}
$lastStamp = $currentStamp;
return "$year $currentStamp";
},
array_reverse($arr)
)
)
);
I have created an array of the next 10 days, with a 2 days buffer (i.e. if it is a Monday, the array starts on Wednesday). I am now trying to remove weekends from my array but unsure how to go about doing this. Below is my PHP and the returned array:
$date_buffer = strtotime('+2 days');
$days = array();
for ($i = 0; $i < 10; $i++) {
$days[date($date_buffer)] = date("l, jS M", $date_buffer);
$date_buffer = strtotime('+2 days', $date_buffer);
}
print_r($days);
This returns:
Array (
[1548192409] => Tuesday, 22nd Jan
[1548365209] => Thursday, 24th Jan
[1548538009] => Saturday, 26th Jan
[1548710809] => Monday, 28th Jan
[1548883609] => Wednesday, 30th Jan
[1549056409] => Friday, 1st Feb
[1549229209] => Sunday, 3rd Feb
[1549402009] => Tuesday, 5th Feb
[1549574809] => Thursday, 7th Feb
[1549747609] => Saturday, 9th Feb
)
Can somebody help me understand how I would filter out any Saturdays or Sundays from the above
http://php.net/manual/en/function.date.php
$date_buffer = strtotime('+2 days');
$days = array();
for ($i = 0; $i < 10; $i++) {
if (!in_array(date('w',$date_buffer), [0,6])) {
$days[date($date_buffer)] = date("l, jS M", $date_buffer);
}
$date_buffer = strtotime('+2 days', $date_buffer);
}
print_r($days);
This is a good job for the DatePeriod class. We set up a period of 10 recurrences of 2 days from the start time (in 2 days), and then can iterate through the dates, checking for a weekend day (day of week = 0 or 6) to exclude them from the output:
$start = new DateTime('+2 days');
$period = new DatePeriod($start, new DateInterval('P2D'), 9);
foreach ($period as $date) {
$dow = (int)$date->format('w');
if ($dow != 0 && $dow != 6) {
$days[$date->format('U')] = $date->format('l, jS M');
}
}
print_r($days);
Output:
Array (
[1548194036] => Tuesday, 22nd Jan
[1548366836] => Thursday, 24th Jan
[1548712436] => Monday, 28th Jan
[1548885236] => Wednesday, 30th Jan
[1549058036] => Friday, 1st Feb
[1549403636] => Tuesday, 5th Feb
[1549576436] => Thursday, 7th Feb
)
If you wanted 10 consecutive days (excluding weekends) from 2 days from today, you would just change the second line of the code to:
$period = new DatePeriod($start, new DateInterval('P1D'), 9);
and the output would be:
Array (
[1548197829] => Tuesday, 22nd Jan
[1548284229] => Wednesday, 23rd Jan
[1548370629] => Thursday, 24th Jan
[1548457029] => Friday, 25th Jan
[1548716229] => Monday, 28th Jan
[1548802629] => Tuesday, 29th Jan
[1548889029] => Wednesday, 30th Jan
[1548975429] => Thursday, 31st Jan
)
Demo on 3v4l.org
Here is a simple answer using the while loop.
https://3v4l.org/0lpGX
<?php
$x = 1; // Start
$y = 10; // Iterations Needed
$days = []; //Empty Array
while($x <= $y) {
// Set Buffer
$buffer = 2 + $x;
// Get Date with Buffer
$date = date(strtotime("+$buffer days"));
// If the day is a weeday
if(date('N', $date) < 6){
// Add to array
$days[$date] = date("l, jS M", $date);
// If not, increase max iteration (example: 10 to 11)
}else{
$y++;
}
// Go to next loop
$x++;
}
echo "<pre>";
print_r($days);
?>
Which prints out
Array
(
[1548283397] => Wednesday, 23rd Jan
[1548369797] => Thursday, 24th Jan
[1548456197] => Friday, 25th Jan
[1548715397] => Monday, 28th Jan
[1548801797] => Tuesday, 29th Jan
[1548888197] => Wednesday, 30th Jan
[1548974597] => Thursday, 31st Jan
[1549060997] => Friday, 1st Feb
[1549320197] => Monday, 4th Feb
[1549406597] => Tuesday, 5th Feb
)
This question already has answers here:
PHP Carbon, get all dates between date range?
(11 answers)
Closed 4 years ago.
Good day.
Ive been trying to get the days from the current day using Carbon in Laravel. So if today is the December 20 I want to get an array with:
December 20, 2018
December 21, 2018
December 22, 2018
December 23, 2018
December 24, 2018
I want to do it for 2 weeks or maybe even 3 weeks. This is what I got so far.
$currentdate = Carbon::now()->format('m/d/Y');
$ts = strtotime($currentdate);
$year = date('o', $ts);
$week = date('W', $ts);
$datearray = [];
for($i = 1; $i <= 7; $i++) {
$ts = strtotime($year.'W'.$week.$i);
array_push($datearray,date("m/d/Y", $ts));
}
The code above gives me for the week from the starting of the week and not from the day going forward.
If you are already using Carbon, use its power!
use \Carbon\Carbon;
// how many days you want in your array
$count = 7;
$dates = [];
$date = Carbon::now();
for ($i = 0; $i < $count; $i++) {
$dates[] = $date->addDay()->format('F d, Y');
}
// Show me what you got
print_r($dates);
Output is:
Array
(
[0] => December 22, 2018
[1] => December 23, 2018
[2] => December 24, 2018
[3] => December 25, 2018
[4] => December 26, 2018
[5] => December 27, 2018
[6] => December 28, 2018
)
Try this,
$datearray = [];
for($i = 0; $i < 7; $i++) {
array_push($datearray, date('F d, Y', strtotime($i == 0 ?'today UTC':'today +'.$i.'day')));
//push to array as 'December 20, 2018'
}
enjoy coding~! :)
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 have a date in the following format
November 18, 2009, 3:00PM
How can i break that up so that i can store each value as its own variable?
such as...
$month //November
$day //18
$year //2009
$hour //03
$minute //00
$ampm //PM
Use the 'date_parse' (http://nl2.php.net/manual/en/function.date-parse.php) function. It returns an array with the parsed items:
Array
(
[year] => 2006
[month] => 12
[day] => 12
[hour] => 10
[minute] => 0
[second] => 0
[fraction] => 0.5
[warning_count] => 0
[warnings] => Array()
[error_count] => 0
[errors] => Array()
[is_localtime] =>
)
Convert your date into a timestamp, then with the timestamp you can easily get your parts. An other way is using a regular expression.
$str = "November 18, 2009, 3:00PM";
list($month,$day,$year,$time) = preg_split('/[ ,]/',$str,false,PREG_SPLIT_NO_EMPTY);
preg_match('/([0-9]+):([0-9]+)([AP]M)/',$time,$timeparts);
list($time,$hour,$minute,$ampm) = $timeparts;
echo "\$month $month\n";
echo "\$day $day\n";
echo "\$year $year\n";
echo "\$hour $hour\n";
echo "\$minute $minute\n";
echo "\$ampm $ampm\n";
Output
$month November
$day 18
$year 2009
$hour 3
$minute 00
$ampm PM
More complex solution.
If your dates may be in the different standards you can use date() function (http://php.net/manual/en/function.date.php) + strtotime() function (http://php.net/manual/en/function.strtotime.php), which parse string and returns the unix timestamp.
For example, if you want to get a year from your date string you could write next code:
$date = 'November 18, 2009, 3:00PM';
$year = date('Y', strtotime($date));
Or, if you want to know how much days in the month in date you get, you could write such code:
$date = 'November 18, 2009, 3:00PM';
$num_of_days = date('t', strtotime($date));
't' returns the number of days in the given month.