My mission is to display the correct day to the correct date for every month. I am so stuck, i would really appreciate some help or pointers in the right way. So far i get out all the days in October since it is october, but i also want to match the days in the loop to the correct date. Am i going this the wrong way?
All i manage to do is to display the same day on every date.
$months = date("n");
$monthsDays = array (
1 => 31,
2 => 28,
3 => 31,
4 => 30,
5 => 31,
6 => 30,
7 => 31,
8 => 31,
9 => 30,
10 => 31,
11 => 30,
12 => 31
);
$day_of_the_week = array (
1 => "Måndag",
2 => "Tisdag",
3 => "Onsdag",
4 => "Torsdag",
5 => "Fredag",
6 => "Lördag",
7 => "Söndag"
);
$dayInteger = date('N', time());
echo $day_of_the_week[$dayInteger];
$day_of_the_week = date("D");
$weekNumber = date("W");
$year = date("Y");
foreach($monthsDays as $key=>$value) {
if($key == $months) {
echo date("M")."<br>";
for($i = 1; $i <= $value; $i++) {
echo '<div class="displayDate">'.$i.'</div>';
}
}
}
Edit
I have deleted the previous answer for the sake of this, more elegant answer:
setlocale(LC_TIME, array('da_DA.UTF-8','da_DA#euro','da_DA','danish'));
$curYear = strftime('%Y');
?>
<h1><?= $curYear; ?></h1>
<?php
for ($month = 1; $month <= 12; $month++) {
$curMonth = strftime('%B', strtotime("01-{$month}-{$curYear}"));
$curMonth = ucfirst($curMonth);
$curMonth = utf8_encode($curMonth);
$totalDays = cal_days_in_month(CAL_GREGORIAN, $month, $curYear);
?>
<h2><?= $curMonth; ?></h2>
<?php for ($day = 1; $day <= $totalDays; $day++) { ?>
<?php
$monthName = ucfirst(strftime('%A', strtotime("{$day}-{$month}-{$curYear}")));
$monthName = ucfirst($monthName);
$monthName = utf8_encode($monthName);
?>
<div class="displayDate"><?= $day; ?> <?= $monthName; ?></div>
<?php } ?>
<?php } ?>
Explanation
There's a lot going on here so I will divulge:
setlocale is a function that will set the locale language to whatever is specified.
The first parameter is what functions are to be affected, the second parameter is the locale to change to. In your case that was Danish.
strftime is very similar to the date function, with the exception that it will return the date in the language set by the locale.
After that it's really just iterating over days and months.
When setting $curMonth, I use strtotime so that I can manipulate it to extract that date in the specified language. Originally, I used DateTime::createFromFormat, but that doesn't respect the locale that is set via setlocale, which is why I used this hack.
$totalDays will return the total number of days in the given month, these means we don't have to hardcode them. The advantages being leap years are accounted for, and if the days of the year change, you don't have to change anything! See cal_days_in_month for how to use this function.
<?= is the equivalent of <?php echo which is a lot easier to write and read - IMO!
The only other interesting things I used are utf8_encode and ucfirst.
The former will convert the string to UTF-8 which is almost a standard these days. The latter will just set the first letter of string to a capital letter.
Note: it might be a good idea to use this solution for setting a capital letter:
$curMonth = mb_convert_case($curMonth, MB_CASE_TITLE);
Thanks to #julp for this answer.
For an explanation of what it does see the documentation for mb_convert_case; but in essence it will simply convert the first letter to a capital regardless of the locale.
try this
echo cal_days_in_month(CAL_GREGORIAN, 8, 2018)
// 8 is month number
// 2018 is year
Related
So I came up with a situation where I want to retrieve the dates that fall under a specific week number. I tried some methods but unfortunately, they did not work out.
So first I am getting the week number of the date that I have/selected/inputed.
$week_number = date('W', strtotime(23/08/2022)) //Will output 34
What I tried to do... But the dates that are being returned are random and not what I am expecting
$dates = array();
for($i = 1; $i <=7; $i++){
$dates[$i] = date('Y-m-d', strtotime($selected_date . ' -' . ($week_number) . ' days +' .
$i . ' days'));
}
What I am expecting:
[1] => 2022-08-22
[2] => 2022-08-23
[3] => 2022-08-24
[4] => 2022-08-25
[5] => 2022-08-26
[6] => 2022-08-27
[7] => 2022-08-28
I don't know if this is a duplicate question but I cannot find what I am looking for.
I just did something very similar not to long ago. I had to find the date of a day in a week in a certain year. My solution was:
function getDateForWeekDay($year, $weekNo, $dayOfWeekNo)
// return the exact date of this weekday, using ISO 8601
{
$date = new DateTime();
$date->setISODate($year, $weekNo, $dayOfWeekNo);
return $date->format('Y-m-d');
}
for instance, echo getDateForWeekDay(2020, 34, 1); will return 2020-08-17, see: https://3v4l.org/bkjUj
See the PHP manual: DateTime::setISODate()
You can easily expand this to generate your array.
for ($day = 1; $day <= 7; $day++) {
$dates[$day] = getDateForWeekDay(2020, 34, $day);
}
print_r($dates);
Which returns the wanted result. See: https://3v4l.org/iDKOu
You can use this to get monday and sunday of a week :
$day = 1; // 1 to 6, monday to saturday.
$dayDate = new \DateTime();
$dayDate->setISODate($date->format('Y'), $date->format('W'), $day);
hi i stored a date that is taken from form in a variable using php and now i want to check whether the date is in the season or not..
the code i written is as follows:
$year = 2012;
$month1 = $_POST["month1"];
$date = $_POST["date"];
$result = "{$year}/{$month1}/{$date}";
echo $result;
and now
// finding first saturday in febraury
$saturday = strtotime('First Saturday '.date('F o', mktime(0,0,0, $month, 1, $year)));
echo "this is the first saturday in the given year:";
echo date('Y/m/d', $saturday);
// calculating first 12 weeks after the first saturday
echo "<br/>";
$season1 = strtotime ( '+12 week' , $saturday);
echo "<br/>this is the first season:";
echo date('Y/m/d', $season1);
echo "<br/>";
// calculating the one week gap after the first 12 weeks
$season2 = strtotime ('+1 week' , $season1);
echo "<br/>this is the first week break:";
echo date('Y/m/d', $season2);
echo "<br/>";
Here what i need to do is to check whether the date given by the user is in season1 or season2..for doing so i tried as
if ($result <= $season1)
{
echo "League yet to be opened";
}
else
{
echo "league 1 is opened";
}
but the condition is not checking here, and like wise i need to check the date entered by the user with 8 seasons how can i do that....any help is much appreciated....thanks in advance..
I'd advice you use such organisation of code and logic
Define current date from POSTed
Don't forget to became sure data is safe
Year, month and date (day) MUST be numerical, for this logic to work.
$year = 2012;
$month1 = $_POST["month1"];
$date = $_POST["date"];
Define your seasons array
$seasons = array(
1 => array(
'season_name' => 'first_season',
'year_start' => 2012, 'year_end' => 2012,
'month_start' => 1, 'month_end' => 2,
'day_start' => 10, 'day_end' => 20
),
2 => array(
'season_name' => 'second_season',
'year_start' => 2012, 'year_end' => 2012,
'month_start' => 2, 'month_end' => 3,
'day_start' => 30, 'day_end' => 15
)
);
Process data to define season
$season_match = array();
foreach($seasons as $season){
if($year >= $season['year_start']) && if($year <= $season['year_end']){
if($month >= $season['month_start']) && if($season<= $season['month_end']){
if($date >= $season['date_start']) && if($season<= $season['date_end']){
$seasons_match[] = $season['season_name'];
}
}
}
}
Test for errors and echo resulting season
if(count($season_match) == 0){
echo 'Date is out of any season';
}
esleif(count($season_match) >1){
echo 'ERROR: Date can be for more then one season at once';
}
else{
echo $season_match; // This is the name of our season!
}
It's general logic for simple and clear solution of your task, I haven't tested it.
My mind seems to be going blank on this one.
I have to write something to figure out which date range todays day/month combination fits into.
I have a set amount of date ranges, which are:
$dateRanges = array(
1 => "16 January to 30 April",
2 => "1 May to 30 June",
3 => "1 July to 15 August",
4 => "16 August to 15 September",
5 => "15 September to 15 October",
6 => "16 October to 15 January"
);
All I'm trying to return is the array key of the range the current date fits into.
At the moment all thats going through my head is I'll have to set up a large if statement to look at the current date('j') and date('n') and match the results up. But surely thats pretty messy and not very efficient?
Any ideas of a better way to approach this problem would be much appreciated!
$today = time();
foreach ($dateRanges as $key => $range) {
list($start, $end) = explode(' to ', $range);
$start .= ' ' . date('Y'); // add 2011 to the string
$end .= ' ' . date('Y');
if ((strtotime($start) <= $today) && (strtotime($end) >= $today)) {
break;
}
}
$key will be either the index of the matching date range, or null/false.
This is a variation on Mark B's answer, but made more efficient by turning this into pure numeric comparisons:
function get_today () {
$dateRanges = array(
0 => 116, // 16th Jan
1 => 501, // 1st May
2 => 701, // 1st July ..etc..
3 => 816,
4 => 916,
5 => 1016
);
$today = (int) date('nd');
foreach ($dateRanges as $key => $date) {
if ($today < $date) {
$result = $key;
break;
}
}
return (empty($result)) ? 6 : $result;
}
Returns an integer matching the keys in your sample array
Create DateTime instances for the values in the array und use simple comparison operators like > and <
Just use strtotime to create a UNIX epoch, then use the inbuilt < and > operators.
http://www.php.net/manual/en/function.strtotime.php
$time_min = strtotime("17 January 2011");
$time_max = strtotime("30 April 2011");
if ($time >= $time_min && $time < $time_max)
{
echo "Time is within range!";
}
You can then just expand this to use the array of ranges you specified.
Dates in PHP are a nightmare for me so please help me out fellow coders... I want to notify customers about the day their order will be delivered. It works like this:
I have 2 shipping zones, A & B. Orders for zone A are delivered each Monday, Wednesday & Friday, whereas zone B is on Tuesday, Thursday, Saturday. For each order, the delivery day is scheduled for the NEXT AVAILABLE day, depending on the zone. Please consider that if someone places an order on Monday the goods will be delivered on the NEXT available date, that would be Tuesday for zone B and Wednesday for zone A.
How can I calculate the NEXT AVAILABLE delivery date and notify the customer?
Thanks.
This will certainly not be the fastest or most clever answer, but it's going to be a pleasure to read the code.
Assuming we are shipping in zone A:
$dates = array(
new DateTime('next monday'), // magic!
new DateTime('next wednesday'),
new DateTime('next friday'),
);
// Seems to work because since PHP 5.2.2 DateTime objects
// can be compared with the < and > operators
$shippingDate = min($dates);
echo $shippingDate->format('Y-m-d');
You might want to take a look at the relative date formats available in PHP, this is the part where the "next monday" magic happens. For information on what you can do with $shippingDate, see the documentation on class DateTime.
Update
For completeness, here is a more old-school version which does not need PHP 5.3 and should also be faster (although speed is practically irrelevant here). I don't like it as much, because it's not easy to verify that it works correctly. In contrast to the version above, this one had a bug when I first wrote it. Simple is good.
$today = date('w');
// These values are from http://www.php.net/manual/en/function.date.php
$shippingDays = array(
1, // mon
3, // wed
5, // fri
);
// Each of these weekdays is how many days into the future?
foreach($shippingDays as &$day) {
$day = (7 + $day - $today) % 7;
}
// Get the earliest one, but not if it's today
// array_filter is used to remove a possible 0
$daysInFuture = min(array_filter($shippingDays));
$shippingDate = new DateTime('+'.$daysInFuture.' days');
echo $shippingDate->format('Y-m-d');
See it in action.
Try this:
// Info
$date = array(date("d"), date("m"), date("Y"));
$zone = "A";
// ------
$zones = array("A" => array(1 => "Monday",
3 => "Wednesday",
5 => "Friday")
,"B" => array(2 => "Tuesday",
4 => "Thursday",
6 => "Saturday"));
$found = false;
$days_plus = 1; // always next day
// Retrieve last day from the zone
end($zones[$zone]);
$last_day = key($zones[$zone]);
do {
$mk = mktime(0, 0, 0, $date[1], ($date[0] + $days_plus), $date[2]);
$week = date("w", $mk);
// if week not passed last day of zone
if ($week <= $last_day)
{
if (!isset($zones[$zone][$week]))
{
$days_plus++;
}
else
{
$found = true;
}
}
else
{
$days_plus++;
}
} while (!$found);
echo "Next date: " . date("d/m/Y - l", $mk);
$timestamp = strtotime('next Monday');
$date = date('Y-m-d', $timestamp);
I need to find a way to get the date of the monday of a week based on another day. So for example, if wednesday is 2011-05-11, i need to somehow tell it that monday of that week was 2011-05-09. Can anyone help?
$res looks like this:
stdClass Object
(
[link_count] => 1
[day] => 2011-05-12
[weekday] => Thu
)
$days = array(1=> 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun');
foreach($res as $r) {
$day = date('N', strtotime($r->day));
$r->weekday = $days[$day];
if($r->weekday == 'Mon') {
$r->weekstarting = $r->day;
} else {
// here's the problem right here, I need to find a way to tell it
// what it's starting day is
$r->weekstarting = ;
}
}
Seems like you have the weekday (like 'Thu'), so you need to get is position in your $days array.
You can get the key with $key=array_search($r->weekday, $days); (returns 4).
Now you know the difference from Monday, so you just have to create the date:
$tempArray=explode('-', $r->day);
$tempArray[2]-=$key-1;
$r->weekstarting = implode('-', $tempArray);
EDIT: Now I see that you already had the array index in $day. So you could use that value instead of the $key I had.
EDIT 2: If you don't want to lose the leading zeros in the day, you could use sprintf() on it .
$tempArray=explode('-', $r->day);
$tempArray[2]=sprintf('%02d', $tempArray[2]-($key-1));
$r->weekstarting = implode('-', $tempArray);
And finally the LAST UPDATE. I was thinking about deleting the whole post and rewriting it again, but I will leave it here for reference... somebody might learn from my mistake.
So the final code that will correctly adjust months also:
list($y, $m, $d)=explode('-', $r->day);
$timestamp=mktime(0,0,0,$m,$d-($day-1),$y);
$r->weekstarting = date('Y-m-d', $timestamp);
Actually this is what I wanted to avoid, converting to a timestamp, but I could not. The trick I'm using here is that mktime() will handle negative numbers for days and calculate the timestamp correctly.
This seems to work fine:
<?php
$dt = new DateTime("11 May 2011");
$dt->modify("last monday");
edit: I remember seeing reports that some people had problems with the "last" modifier (windows users maybe) so this should work if you have problems with that:
<?php
$dt = new DateTime("12 May 2011");
$days = (int)$dt->format('N') - 1;
$dt->modify("-{$days} days");
Please create a testfile and execute it:
<?php
$dates = array(
'11 May 2011',
'2011-04-26',
'2011-05-04',
);
foreach($dates as $date) {
$dt = new DateTime($date);
$dt->modify("last monday");
printf("For %s last monday is %s.\n", $date, $dt->format('Y-m-d'));
}
?>
it should output the following:
For 11 May 2011 last monday is 2011-05-09.
For 2011-04-26 last monday is 2011-04-25.
For 2011-05-04 last monday is 2011-05-02.
In case not, please add your output to your question above.
I'd do something like this:
$dow = date('N', strtotime($r->day)) - 1; // 0 will be Monday, 1 Tuesday, etc.
$start = mktime() - ($dow * 86400); // 86400 is one day in seconds
$startday = date('r', $start);