PHP Carbon specialized date format - php

I want to make a function that will output a result like this:
//Assuming that today is 2022-01-20
parse_date("2022-01-20") //Today
parse_date("2022-01-19") //Yesterday
parse_date("2022-01-18") //Tuesday
parse_date("2022-01-17") //Monday
parse_date("2022-01-16") //Sunday
parse_date("2022-01-15") //2022-01-15
The idea is to display Today if the date is today, Yesterday if the date is yesterday, the weekday name if the date is within the current week and Y-m-d for anything else.
The current code I have that works is as follows:
public function parse_date($date) {
$carbonDate = Carbon::parse($date);
if($carbonDate->isToday()) return "Today";
if($carbonDate->isYesterday()) return "Yesterday";
$now = Carbon::now();
$start = $now->startOfWeek(CarbonInterface::SUNDAY)->copy();
if($carbonDate >= $start && $carbonDate <= $now->endOfWeek(CarbonInterface::SATURDAY)->copy()) {
return $carbonDate->format('l');
}
return $carbonDate->format('Y-m-d');
}
What I want to know is if there's a better way to do this using other Carbon functions.

Another way to do it is to check the week, and compare it to the current week. Double-check the values first to make sure this works, or if you need to change the locale, with Carbon::parse($date)->locale('en_US');
public function parse_date($date) {
$carbonDate = Carbon::parse($date);
if($carbonDate->isToday()) return "Today";
if($carbonDate->isYesterday()) return "Yesterday";
if($carbonDate->week == Carbon::now()->week) {
return $carbonDate->format('l');
}
return $carbonDate->format('Y-m-d');
}

Related

how to understand if one date in php is less than another minus one day?

how to understand if one date in php is less than another minus one day? I mean if for example a date is set to "2018/07/03"; how can I understand if a given date is less than "2018/07/02"
date1 : year1/month1/day1
date2: year2/month2/day2
<?php
if ($year1 >= $year2) {
if ($month1 >= $month2) {
if (($day1 - 1) > $day2) {
echo 'you could do something..';
}
}
}
?>
the above code fails if forexample $year2 = 2017 and $month2 = 11.. can anybody help me? thanks a lot..
Here, this should work.
$date_to_check = new DateTime($yesterday);
$today = new DateTime();
$time_diff = $today->diff($date_to_check)->d;
if($time_diff > 1) {
echo "This is greater than one day.";
}else{
echo "This is not greater than one day.";
$date = strtotime("2018/07/01");
$date2 = strtotime("2018/07/02");
if($date > $date2){
print('date is bigger');
// do stuff when date is bigger than date2
} else {
// else ...
print('date2 is bigger');
}
To convert string to date php has function named strtotime().
Compairing date objects is simple.
There is full information about strtotime()
http://php.net/manual/ru/function.strtotime.php
Another way:
$date = new DateTime("2018/07/01");
$date2 = new DateTime("2018/07/02");
if($date->modify("+1day") > $date2){
print('date is bigger');
// do stuff when date is bigger than date2
} else {
// else ...
print('date2 is bigger or equal');
}
Notice modify modifies $date object itself.
Read more here http://php.net/manual/en/class.datetime.php

Date & time comparison operators >= not showing dates that are equal

I am trying to show events that occur either today or on a later date where today is specifically the problem.
public function getInspirationsMeetingIds()
{
$ids = [];
if (($inspirationMeetings = $this->getCustomField('meetings'))) {
foreach ($inspirationMeetings as $meeting) {
$row = new Inspiration($meeting['meeting']);
$dateFrom = $row->getCustomField('date');
if (strtotime($dateFrom) >= time()) {
$ids[] = $row->getId();
}
}
}
return $ids;
}
For some reason this will only show events that are greater than time() and not the events that are today, but then when i try this:
if (strtotime($dateFrom) <= time()) {
$ids[] = $row->getId();
}
Today's and older events are shown.
I think you need to add a timestamp to your datefrom.
Strtotime will add noon if time is omitted.
See this example https://3v4l.org/cYKO4
if (strtotime($dateFrom ) >= strtotime(date("Y-m-d 00:00"))) {
Will make it show all of datefrom
Edit added the 00:00 at the wrong side
Use the DateTime class http://php.net/manual/en/class.datetime.php
time() gives seconds since Jan 1st 1970. The chance that you hit the exact second is very small, so it will hardly ever match.
Instead, create a date with the time.
$date = new DateTime($dateFrom); // or DateTime::createFromFormat($format, $dateFrom);
$today = new DateTime();
if ($date >= $today) {
// should work
}

Check today's date with specified date range with PHP [duplicate]

This question already has answers here:
How to check if a date is in a given range?
(10 answers)
Closed 5 years ago.
I want to check the today's date with specified range of dates and want it to return true if the today's date is between the specified range dates
Something like this:
if (todaysDate is between "2017-04-24 ... 2017-08-30") {
return true;
}
Is there any way to check this in PHP?
Here is some code that may help you, create a function if you want to.
$today= date('Y-m-d');
$today=date('Y-m-d', strtotime($today));;
$date1= date('Y-m-d', strtotime("01/01/2001"));
$date2= date('Y-m-d', strtotime("01/01/2012"));
if (($today> $date1) && ($today< $date2)){
echo "OK !";
}else{
echo "NO OK !";
}
Just create your own method like so:
function isBetweenDates($dateToCheck, $firstDate, $secondDate){
if (($dateToCheck > $firstDate) && ($dateToCheck <
$secondDate))
{
return true;
}
else
{
return false;
}
}
Then call it with dates:
echo isBetweenDates(date('Y-m-d'),strtotime("01/01/2016"),strtotime("01/01/2018"));
Which will return true, because today's date is between 2016 and 2018.
based on: PHP check if date between two dates
Edit:
You could even generalize the function and use it on ints too:
function isBetween($varToCheck, $lowerLimit, $upperLimit){
if (($varToCheck > $lowerLimit) && ($varToCheck <
$upperLimit))
{
return true;
}
else
{
return false;
}
}
Or even make it super specific by converting the input to dates:
function isBetweenDates($dateToCheck, $start_date, $end_date)
{
$start = strtotime($start_date);
$end = strtotime($end_date);
$date = strtotime($dateToCheck);
// Check that user date is between start & end
return (($date > $start) && ($date < $end));
}

PHP: year when a date occurs the next time

I need a function that returns the year when a given date (day + month) occurs the first time from now on.
function year($day, $month) {
// ...
return $year;
}
$day and $year are two-digit numbers
E.g. the given date is '12/25' it should return '2016' (or '16'), but if the date is '02/25' it should return '2017' (or '17').
[Today is August 30, 2016]
Leap years may be disregarded and input doesn't have to be validated.
EDIT:
My attempt
year($day, $month) {
$today_day = date('d');
$today_month = date('m');
$year = date('y');
if($month > $today_month) {
return $year;
} else if ($month < $today_month) {
return $year + 1;
} else {
if($day >= $today_day) {
return $year;
} else {
return $year + 1;
}
}
}
Just compare the date you are checking against today. If it is today or earlier increment the year of the date. Otherwise do not. Then return that year.
DateTime() functionality makes this easy to do.
function year($day, $month) {
$date = new DateTime("{$month}/{$day}"); // defaults to current year
$today = new DateTime();
if ($date <= $today) {
$today->modify('+1 year');
}
return $today->format('Y');
}
echo year(6, 6); // 2017
echo year(12, 12); // 2016
Demo
I appreciate your effort! It was pretty good, but can certainly use some fine tuning. We could reduce the no. of unnecessary if statements.
The function accepts two parameters: month and date. Please be sure we follow the order while calling the function.
In the function, $date is the input date concatenated with the current year.
E.g: year(12,25) refers to the year where month is December (12) and day is 25.
year(12,25) would make $date as 2015-12-25.
function year($month, $day)
{
$date= date('Y').'-'.$month.'-'.$day;
if (strtotime($date) > time()) {
return date('y');
}
return (date('y')+1);
}
echo year(12,25); // 16
echo year(2,25); // 17
Now, all we need to do is check the timestamp of $date with the current timestamp- time().
strtotime($date) > time() input date timestamp is more than current timestamp. Which implies this date is yet to come in this year. So, we return the current year date('Y').
If the above if is not executed, it's obvious that this date has passed. Hence we return the next year date('Y') + 1.

Maturity date with PHP

Edit :
Maturity date, what is it ?
I'm not native english speaker. Sorry about that. I think the best we can do, is to define Maturity Date.
A maturity date is a date that indicates the deadline for the payment
of an invoice. In BtoB, the maturity date indicates when the customer
wants to pay us, defined during the contract it is usually a later date between 1 and 3 months
after the publishing of the bill. It's a calculated data, and
implemented in my application with the following code.
I have this code in my Invoice module I extracted it for you can tests :
<?php
class Config
{
protected $amountDelayedDays;
protected $paymentDay;
protected $paymentCondition;
public function getAmountDelayedDays()
{
return $this->amountDelayedDays;
}
public function getPaymentCondition()
{
return $this->paymentCondition;
}
public function getPaymentDay()
{
return $this->paymentDay;
}
public function setAmountDelayedDays($days)
{
$this->amountDelayedDays = $days;
return $this;
}
public function setPaymentDay($days)
{
$this->paymentDay = $days;
return $this;
}
public function setPaymentCondition($condition)
{
$this->paymentCondition = $days;
return $this;
}
}
class Test {
/**
* #param DateTime $dateInvoice
* #param Config $config
* #return DateTime
*/
public function calcMaturityDate(\DateTime $dateInvoice, $config)
{
if ($config->getPaymentCondition() == 'delayed') {
$dateMaturity = clone $dateInvoice;
$startDay = $dateMaturity->format('j');
$dateMaturity->modify("+{$config->getAmountDelayedDays()} days");
$endDay = $dateMaturity->format('j');
if ($startDay != $endDay && $endDay < 30) {
$dateMaturity->modify('last day of last month');
} else {
$dateMaturity->modify('last day of this month');
}
if ($config->getPaymentDay() != 0) {
$dateMaturity->modify('+' . $config->getPaymentDay() . 'days');
}
return $dateMaturity;
} else {
return $dateInvoice;
}
}
}
$config = new Config;
$config->setPaymentDay(15);
$config->setAmountDelayedDays(60);
$config->setPaymentCondition('delayed');
$test = new Test;
$date = $test->calcMaturityDate(new DateTime('2015-01-31'), $config);
var_dump($date);
?>
I have to calculate a maturity date from the date of invoice.
If my invoice is dated at 2014-11-30 and my client is configured to be charged 2 month later & on the 15'(=60days + 15 ), I have to produce a maturity date like this :
'2015-02-15'
For doing this I have to variables in my Config class :
$config->getAmountDelayedDays() and $config->getPaymentDay()
My code is not perfect to handle all problems. February changing years, custom value of days... Jumped month...
I think the problem is in
if ($startDay != $endDay && $endDay < 30) {
$dateMaturity->modify('last day of last month');
} else {
$dateMaturity->modify('last day of this month');
}
It's too simple to handle all cases, maybe it's wrong. I can't make my mind clear about this...
Tests case
I have units test testing this function I'm not passing
/**
* Tests MaturityDate
*
*/
public function testCanGiveCorrectMaturityDate()
{
$config = $this->parser->setConfig();
$config->setAmountDelayedDays(60);
$config->setPaymentDay(15);
$config->setPaymentCondition('delayed');
// From February Ok ?
$dateInvoice = new \Datetime('2015-02-28');
$maturityDate = $this->mock->calcMaturityDate($dateInvoice , $config);
$this->assertEquals('15-05-2015', $maturityDate->format('d-m-Y'));
// From February ok ?
$dateInvoice = new \Datetime('2015-02-28');
$config->setAmountDelayedDays(30);
$config->setPaymentDay(0);
$maturityDate = $this->mock->calcMaturityDate($dateInvoice , $config);
$this->assertEquals('31-03-2015', $maturityDate->format('d-m-Y'));
// New years and pass february
$config->setAmountDelayedDays(90);
$config->setPaymentDay(15);
$dateInvoice = new \Datetime('2014-11-30');
$maturityDate = $this->mock->calcMaturityDate($dateInvoice , $config);
$this->assertEquals('15-03-2015', $maturityDate->format('d-m-Y'));
// No delayed
$config->setPaymentCondition('standard');
$dateInvoice = new \Datetime('2014-11-30');
$maturityDate = $this->mock->calcMaturityDate($dateInvoice , $config);
$this->assertEquals('30-11-2014', $maturityDate->format('d-m-Y'));
}
If I get it right, you expect the paymentDay to be always 15th day of month of maturity, or next month, when date of maturity is later than 15th.
With this assumption your class would be:
public function calcMaturityDate(\DateTime $dateInvoice, $config)
{
$dateMaturity = clone $dateInvoice;
$dateMaturity->add(new \DateInterval("P{$config->getAmountDelayedDays()}D"));
$payDay = $config->getPaymentDay();
// patch 0 payDay to last day of month
if (0 == $payDay) {
$payDay = $dateMaturity->format('t');
}
if ($dateMaturity->format('j') > $payDay) {
$dateMaturity->modify('next month');
}
$dateMaturity->setDate(
$dateMaturity->format('Y'),
$dateMaturity->format('m'),
$payDay
);
return $dateMaturity;
}
Few notes:
the class name is a bit misleading, as it returns payment date, not maturity date;
maturity interval is 60 days, not 2 months;
For the last point I would recommend to refactor your config class to return \DateInterval for maturity interval instead of integer, so you will have flexibility to define 2 month interval as "P2M" or 60 days as "P60D" depending on business requirements:
If instead of
public function getAmountDelayedDays()
{
return $this->amountDelayedDays;
}
you have
/**
* #return \DateInterval
*/
public function getDelayInterval()
{
return $this->delayInterval;
}
the ugly line from above
$dateMaturity->add(new \DateInterval("P{$config->getAmountDelayedDays()}D"));
turns to elegant
$dateMaturity->add($config->getDelayInterval());
In these cases a always convert the "friendly date" to a timestamp; do the math; then convert back to a friendly date.
Something like this:
$invoice_date = "2014-11-30";
$ts_invoice_date = time($invoice_date);
$ts_maturity_month = $ts_invoice_date + (60*24*60*60); //60 days*24hrs*60mins*60secs
$maturity_date = date("Y-m-15 00:00:00", $ts_maturity_month);
From documentation: Date and Time
date('Y-m-d', strtotime('+1 week'))
strtotime documentation
Your question:
I have to calculate a maturity date from the date of invoice.
You can use date('Y-m-d', strtotime('+60 days')) and that will handle odd/even number of days in month, as well as fix to hours (if you need that precision)..
A date 2014-11-30 with date('Y-m-d', strtotime('+ $amountDelayedDays days')) yelds the correct date.
I think i get what your trying to do and I have had to do something similar. You basically want something to determine if the current day of the month is less than 15 and if it is it remains the 15th of this month else if its say the 20th of the same month then date is 15th of next month?. I think this is how I am reading this. If this is the case then you need to compare the day of the invoice to the 15th and if less than its the same month or if its greater than then its the next month. It then gets interesting as are you allowing a leverage period of say 5 days before the due date. A factor on what I was working on I used. This could be the case if the date of the invoice was the 14th and you set payment date on the 15th. With the logic the client would only have a day to pay the invoice. I think we went with the 15th minus 5 days.

Categories