I am putting together a membership site that uses a pro rata system for memberships fees.
EG
$75.00 from 01 Apr YY - 31 Mar YY but if you join at say around Sep YY, then you only pay the pro rata of $38.00
My current coding is working fine - no probs.
But was wondering is there a way to to dynamically change the end date ($your_date) below so I don't have to manually edit it every 12 months?
So for instance, if today's date was 01 Feb 2017, then $your_date below is correct.
However, if todays date was 14 May 2017, then $your_date below of course is incorrect.
Membership year runs from 01 Apr this/last year - 31 Mar this/next year, so it would be
if Today's date <= 31 Mar this/next year && >= 01 Apr this/last year then do something..
<?php
$now = time(); // or your date as well
$your_date = strtotime("2017-03-31");
$datediff = $your_date - $now;
$SOS = floor($datediff/(60*60*24)*0.205);
$ORD = floor($datediff/(60*60*24)*0.115);
$GEN = floor($datediff/(60*60*24)*0.03);
?>
Or have I got a fixation with the code I'm using and there is something a lot simpler?
The PHP below is deliberately verbose in order that each line explains itself:
$Current_Year = date('Y');
$Current_Month = date('n');
$Current_Day = date('j');
$Next_Year = ($Current_Year + 1);
if ($Current_Month < 4) {
$Expiration_Year = $Current_Year;
}
if ($Current_Month > 3) {
$Expiration_Year = $Next_Year;
}
# Checks if date is March 31st
if (($Current_Month == 3) && ($Current_Day == 31)) {
$Expiration_Year = $Next_Year;
}
$Expiration_Date = $Expiration_Year.'-03-31';
It's a little complicated, but I think you want:
If the current date is April or later, then March 31 next year, otherwise it's March 31 this year.
Does that about sum it up? Of course, if they're applying on the 31st of March, that'd be a $0.00 fee...
So I think the code should be:
$your_year = ( date('m')>'3' ? ((int)date('Y')+1) : date('Y') )
$your_date = strtotime( $your_year . "-03-31" )
Related
Financial year starts on 01 April and we are in January so January falls into year 2020 and so is February and March. So if I use April now, it should fall in to year 2019. Currently I used the following code but it doesn't work the way I want it
$month =01;
if ( $month >= 4 ) {
$year = date('Y');
}
else {
$year = date('Y')-1;
}
echo $year;
SO when I set the month to 1 which is January, the year shows as 2019 but it should really be 2020.
Is there anyway to set the year in PHP so when the months will start from April and ends end of March so when I enter a month, I will get the correct year?
Try something like this: Carbon::now()->subMonths(3)->year
This way January, February, and March dates will return 2019, and April will start returning 2020 as year.
I think i managed to fix the issue. Any comments is welcomed
$month =01;
$current_month = date('m');
if ($current_month >= '01' && $current_month < '4'){
if ($month >= '01' && $month < '04'){
$year = date('Y');
}
if ($month >= 4){
$year = date('Y')-1;
}
}
if ($current_month >= 4){
if ($month >= 4){
$year = date('Y');
}
if ($month < 4){
$year = date('Y')+1;
}
}
echo $year;
I hope this will solve your issue
$date=date_create("2020-05-13");
echo "<br> Month: ".date_format($date,"m");
if (date_format($date,"m") >= 4) {//On or After April (FY is current year - next year)
$financial_year = (date_format($date,"Y")) . '-' . (date_format($date,"y")+1);
} else {//On or Before March (FY is previous year - current year)
$financial_year = (date_format($date,"Y")-1) . '-' . date_format($date,"y");
}
echo "<br> FY ".$financial_year;
Something along the lines :
$now = strtotime('now');
$firstApril = strtotime('1st april');
$year = ($now < $firstApril) ? date('Y')-1 : $date('Y');
return $year;
This would compare the timestamp and if its less than 1st april of this year than it will get the previous year.
you can try this:
$month =01;
if($month>=4&&$month<=12){
$year=date('Y')-1;
}
if($month>=1&&$month<=3){
$year=date('Y');
}
echo $year;
It's not a direct answer, but if you handle multiple financial/transactional data for a financial year for your business, you probably are in a similar position as I was a few years back.
Feel free to check this library -> https://github.com/RoussKS/financial-year
It would be an overkill for a single checking (even though considerably lightweight), but if you have more requirements, it could be useful.
Requires the start of the financial year date and the type of the financial year (in your case, it's calendar as per library's spec) and provides ending date, period ranges and more.
Returns a DateTimeImmutable object or a DatePeriod depending the method used (get a date, period, or week for business type financial year only)
In your case, the use case would be like
require_once __DIR__ . '/vendor/autoload.php';
// DateTimeAdapter
// If instantiating with string, it must be of ISO-8601 format 'YYYY-MM-DD'
$startDate = new \DateTime('2019-04-01');
$fy = new \RoussKS\FinancialYear\DateTimeAdapter('calendar', $startDate);
// January is the 10th period for a financial year based on 12 periods starting at 2019-04-01.
// First date of the period would give you 2020-01-01
echo $fy->getFirstDateOfPeriodById(10)->format('Y'); // 2020
Feel free to test and advise
Here's how to get the start date for the current financial year (start date 1st April).
public function getFinancialYear(){
$today = Carbon::today();
$month = $today->format('m');
$year = $today->format('Y');
$firstApril = 'first day of April '.$year;
$financialYear = new Carbon($firstApril);
if($month < 4){
$financialYear->subYear();
}
return $financialYear;
}
function fascal_year(){
$today_year = date("Y");
$today_month = date("m");
$fascal_year = "";
if($today_month <= 6){
$fascal_year = ($today_year - 1) ."-". $today_year;
}else{
$fascal_year = $today_year."-".($today_year + 1);
}
return $fascal_year;
}
I'm working on a little payments system and must generate a list of payment days (monthly) given an initial date and number of payments. So, for example:
Given:
startday: 2015/06/22
qtty: 6
I should get the day from initial date (22) and generate a list of 6 sequential monthly dates:
2015/06/22 (if initial date should be included, and is > than today)
2015/07/22
2015/08/24
2015/09/22
2015/10/22
2015/11/23
As you can see, generated dates should not be weekends (sat/dom) and -if possible- nor holidays
Is there any function that could help me achieve this? TIA
I think this might do what you want, including holidays:
<?php
$startday = strtotime("2015/08/24");
$qtty = 5;
// Add as many holidays as desired.
$holidays = array();
$holidays[] = "4 Jul";
$holidays[] = "25 Dec";
for( $i = 0; $i < $qtty; $i++ ) {
$next_month = strtotime("+".$i." month", $startday); // Also works with "+ 30 days"
while( in_array(date("d M", $next_month), $holidays)) { // Is holiday
$next_month = strtotime("+ 1 day", $next_month);
if( date("N", $next_month) > 5 ) { // Is weekend
$next_month = strtotime("next Monday", $next_month); // or "previous Friday"
}
}
echo(date( "Y-m-d", $next_month) . '</br>');
}
?>
Will echo
2015-08-25
2015-09-25
2015-10-26 // Because of weekend
2015-11-25
2015-12-28 // Because of Christmas and weekend
And with a start date of 2015/10/31 the output will be:
2015-11-02 // Because of weekend
2015-12-01 // Because the 31st of Nov is the 1st of Dec
2015-12-31
2016-02-01 // Because the weekend
2016-03-02 // Because the 31st of Feb is the 2st of Mars (as 2016 is leep year)
As a good extra tips, depending on how you want to solve the 31st of Jan problem, if you want the last of each month, you can always use the following:
$first_of_the_month = strtotime(date("Y-m-1", $startday));
$next_month = strtotime("+ 1 month", $first_of_the_month);
$last_of_the_month = date("Y-m-t", $next_month);
echo($last_of_the_month); // 2015-09-30
In my script, I have a given end date. To get the start date, I subtract 23 months to the end date. Basically, what my script should do is to output 24 months (w/ year) - the last month/year to be printed should always be the specified end date.
For some reason, my script isn't returning my desired results. Given the $end = '2013-07-05', the script returns the result correctly. It prints out Aug 11 to Jul 13 which is correct.
But for some dates (e.g. $end = '2013-07-31'), the output is wrong. The result should be Sep 11 to Aug 13. But in this case, it outputs Aug 11 to Aug 13 which is absolutely wrong.
Here's my code:
<?php
$end = strtotime('2013-07-31 +1 month');
$date = strtotime('2013-07-31 -23 month');
$start = $month = $date;
$months = "";
while($month < $end)
{
$months .= date('M y', intval($month))." ";
$month = strtotime("+1 month", intval($month));
}
echo $months;
?>
I think there's something wrong with strtotime(). Thanks in advance.
You can't really use month calculations like that, especially when dealing with end-of-month values:
e.g. if it's July 31, what's -1 month to strtotime?
php > echo date('r', strtotime('2013-07-31 -1 month'));
Mon, 01 Jul 2013 00:00:00 -0600
A human would probably pick out June 30th, but strtotime isn't human. This DOES work for February 28th and generally any date where the day value is <= 28. Once you get into the 29,30,31 area, then you get these unexepected results
php > echo date('r', strtotime('2013-04-28 -1 month'));
Thu, 28 Mar 2013 00:00:00 -0600
How about
$endMonth = '8';
$year = '2013';
$i = 24;
while( $i > 0 ){
$month = ($endMonth - $i)%12;
if( $month == 0 ){
$year = $year - 1;
$month = 12;
}
$months .= date('M y', strtotime($year.'-'.$month.'-02'));
$i--;
}
Based on Marc B's answer I modified the script to deal with the 29,30,31 of each month. What I did was, if the date is 29, 30, or 31, it will be subtracted with 3 days so that the date will be either 28 or below and would work just fine with the current code that I have. It worked for me so I guess I'll just stick with this for now. Here's the updated code:
<?php
$dt = "2013-07-31";
$dy = strtotime($dt);
$day = date("d", $dy);
if (($day == 29) || ($day == 30) || ($day == 31)){
$dt = strtotime("$dt -3 days");
$dt = date('Y-m-d', $dt);
}
$end = strtotime("$dt +1 month");
$date = strtotime("$dt -23 month");
$start = $month = $date;
$months = "";
while($month < $end)
{
$months .= date('M y', intval($month))." ";
$month = strtotime("+1 month", intval($month));
}
echo $months;
?>
Thanks for your help and insights. :)
I have two dates from-date & to-date.
I have to compare them from existing dates shown below, whether any of the day fall between them or not using php?
i can do for single date checking ,but i am confuse for the two date checking.
Example:
i have to check these dates:-> from=15 March 2013 & 15 April 2013 between the following dates whether any days falls in between these two date or not.
following data from db table
# from date to-date
-----------------------------------------
1 01 April 2013 30 April 2013 //here we will find as falling
2 01 May 2013 15 May 2013
3 01 June 2013 20 June 2013
Currently,in my mind not even a single logic is coming to try. Please give me any logic or suggestions regarding this issue..
The simplest way to compare dates is to convert them to a unix timestamp
Because the unix timestamp is an integer, you can simply use relational operators to compare them.
Example
// set some example data
$referenceDate = '01 April 2013';
$fromDate = '01 January 2013';
$toDate = '01 June 2013';
// convert dates to timestamps (strings to integers)
$referenceTimestamp = strtotime( $referenceDate );
$fromTimestamp = strtotime( $fromDate );
$toTimestamp = strtotime( $toDate );
// isBetween is Boolean TRUE if reference date is greater or equal fromDate and smaller or equal toDate
$isBetween = $referenceTimestamp >= $fromTimestamp and $referenceTimestamp <= $toTimestamp;
EDIT 1
To actually answer your question:
You have two ranges you need to test for overlap, this question has been answered here What's the most efficient way to test two integer ranges for overlap?
// our two ranges overlap if the following conditions are met
$dateRangeOverlaps = $referenceFromTimestamp <= $toTimestamp and $fromTimestamp <= $referenceToTimestamp;
Please try the code,
$ourdate = strtotime('1 April 2013'); // Your date which is to be checked
$from = strtotime('15 March 2013'); // From date
$to = strtotime('15 April 2013'); // To date
if ($ourdate >= $from && $ourdate <= $to)
{
echo "Date falls";
}
else
{
echo "No Date falls";
}
If you need to check several dates, pass it as an array, like below...
$i=0;
$dates= array("11 April 2013","16 April 2013");
foreach($dates as $ourdates)
{
$ourdate= strtotime($ourdates); //Your dates to be checked
$from = strtotime('15 March 2013'); // From date
$to = strtotime('15 April 2013'); // To date
if ($ourdate >= $from && $ourdate <= $to)
{
$i++;
}
}
if($i>0)
{
echo "Date falls";
}
else
{
echo "No Date falls";
}
I was born in 1986-04-21, which is Monday. My next birthday with day name "Monday" is 1997-04-21 and so on.
I wrote the program to find upto 100 year to find which year my birthday comes with matching day name that is monday.
This is the code:
<?php
date_default_timezone_set('Asia/Calcutta');
for($year = 1986; $year < 2086; $year++) {
$timestamp = mktime(0, 0, 0, 4, 21, $year);
if(date('l', $timestamp) == 'Monday') {
echo date('Y-m-d, l', $timestamp) . "\n";
}
}
?>
This is the output of the program:
1986-04-21, Monday
1997-04-21, Monday
2003-04-21, Monday
2008-04-21, Monday
2014-04-21, Monday
2025-04-21, Monday
2031-04-21, Monday
2036-04-21, Monday
Now my problem is why PHP is not supporting before 1970 and after 2040.
So how can I get the birthday after 2040 or before 1970?
There's no need to use any special date processing classes or functions at all.
Your birthday is after the leap day in February, so from one year to the next it'll either be one day (365 % 7) or (on leap years) two days (366 % 7) later in the week than it was the year before.
$year = 1985; // start year
$dow = 0; // 0 for 1985-04-21 (Sunday)
while ($year < 2100) {
$year++; $dow++;
if ($year % 4 == 0 && ($year % 100 != 0 || $year % 400 == 0)) {
$dow++; // leap year
}
$dow %= 7; // normalise back to Sunday -> Saturday
if ($dow == 1) {
printf("%04d-%02d-%02d is a Monday\n", $year, 4, 21);
}
}
This code will work on any version of PHP.
If you're on PHP 5.3, you can use the DateTime class and add DateIntervals. It is based on 64-bit integers and doesn't have the year 2038 problem.
Basic example:
<?php
$year = DateInterval::createFromDateString('1 year');
$date = new DateTime('1986-04-21');
$date->add($year);
echo $date->format('Y-m-d') . "\n"; // Repeat 100 times
documentation on createFromDateString() is here.
For the reason why you can't go before 1970 or past 2038 see the date manual:
The valid range of a timestamp is
typically from Fri, 13 Dec 1901
20:45:54 GMT to Tue, 19 Jan 2038
03:14:07 GMT. (These are the dates
that correspond to the minimum and
maximum values for a 32-bit signed
integer). However, before PHP 5.1.0
this range was limited from 01-01-1970
to 19-01-2038 on some systems (e.g.
Windows).