119

I'm trying to take a date object that's coming out of my Drupal CMS, subtract one day and print out both dates. Here's what I have

$date_raw = $messagenode->field_message_date[0]['value'];

print($date_raw);

//this gives me the following string: 2011-04-24T00:00:00

$date_object = date_create($date_raw);

$next_date_object = date_modify($date_object,'-1 day');

print('First Date ' . date_format($date_object,'Y-m-d'));

//this gives me the correctly formatted string '2011-04-24'

print('Next Date ' . date_format($next_date_object,'Y-m-d'));

//this gives me nothing. The output here is always blank

So I'm not understanding why the original date object is coming out fine, but then I'm trying to create an additional date object and modify it by subtracting one day and it seems like I can't do that. The output always comes out blank.

td-dev
  • 1,193
  • 2
  • 7
  • 6

9 Answers9

180

You can try:

print('Next Date ' . date('Y-m-d', strtotime('-1 day', strtotime($date_raw))));
Tobias
  • 9,170
  • 3
  • 24
  • 30
  • 1
    You can get the $date_raw same format with `$date_raw = date("r");` – sHaDeoNeR Jan 20 '15 at 16:09
  • 9
    **Be careful!** If you handle dates _beyond 2038_ it will not work because of the integer size limit in PHP (at least on a 32bit platform). In that case, the safest solution is to use `DateTime` ([see here](http://stackoverflow.com/questions/5319710/accessing-dates-in-php-beyond-2038)). – Tip-Sy Jan 27 '16 at 10:24
73
$date = new DateTime("2017-05-18"); // For today/now, don't pass an arg.
$date->modify("-1 day");
echo $date->format("Y-m-d H:i:s");

Using DateTime has significantly reduced the amount of headaches endured whilst manipulating dates.

aberdat
  • 791
  • 5
  • 5
  • 8
    [`date_create`](https://stackoverflow.com/a/36154583/1326147) is the procedural method to invoke the [`DateTime` constructor](http://php.net/manual/en/datetime.construct.php), which allows you to reduce your 3 lines into 1 without using `new`. I.e. `echo date_create('2017-05-18')->modify('-1 day')->format('Y-m-d H:i:s');` – Armfoot Feb 02 '18 at 22:42
  • 3
    well, code from the original asnwer can be also written In 1 line, like: `(new \DateTime("2017-05-18"))->modify("-1 day")->format("Y-m-d H:i:s")` – Scofield Jan 03 '21 at 15:29
67
 date('Y-m-d',(strtotime ( '-1 day' , strtotime ( $date) ) ));
iThink
  • 1,239
  • 3
  • 13
  • 34
29

A one-liner option is:

echo date_create('2011-04-24')->modify('-1 days')->format('Y-m-d');

Running it on Online PHP Editor.


mktime alternative

If you prefer to avoid using string methods, or going into calculations, or even creating additional variables, mktime supports subtraction and negative values in the following way:

// Today's date
echo date('Y-m-d'); // 2016-03-22

// Yesterday's date
echo date('Y-m-d', mktime(0, 0, 0, date("m"), date("d")-1, date("Y"))); // 2016-03-21

// 42 days ago
echo date('Y-m-d', mktime(0, 0, 0, date("m"), date("d")-42, date("Y"))); // 2016-02-09

//Using a previous date object
$date_object = new DateTime('2011-04-24');
echo date('Y-m-d',
  mktime(0, 0, 0,
     $date_object->format("m"),
     $date_object->format("d")-1,
     $date_object->format("Y")
    )
); // 2011-04-23

Online PHP Editor

Armfoot
  • 4,663
  • 5
  • 45
  • 60
28

Object oriented version

$dateObject = new DateTime( $date_raw );
print('Next Date ' . $dateObject->sub( new DateInterval('P1D') )->format('Y-m-d');
Cosmitar
  • 984
  • 12
  • 18
  • your answer adds one day instead of substracting it. Other than that it would be my preferred solution. – Burki Aug 18 '15 at 08:23
17

Not sure why your current code isn't working but if you don't specifically need a date object this will work:

$first_date = strtotime($date_raw);
$second_date = strtotime('-1 day', $first_date);

print 'First Date ' . date('Y-m-d', $first_date);
print 'Next Date ' . date('Y-m-d', $second_date);
Clive
  • 36,918
  • 8
  • 87
  • 113
  • Thanks Clive! That one worked for me...yeah, I didn't really need date objects, I just needed to print the formatted dates. – td-dev Oct 04 '11 at 17:17
14

Answear taken from Php manual strtotime function comments :

echo date( "Y-m-d", strtotime( "2009-01-31 -1 day"));

Or

$date = "2009-01-31";
echo date( "Y-m-d", strtotime( $date . "-1 day"));
cuperto
  • 141
  • 1
  • 3
10

You can add strtotime() in date() with parameter number of day week or month.
Example for day:

date("Y-m-d", strtotime("-1 day"));

For week:

date("Y-m-d", strtotime("-1 week"));

For month:

date("Y-m-d", strtotime("-1 months"));
Militaru
  • 521
  • 5
  • 11
6

How about this: convert it to a unix timestamp first, subtract 606024 (exactly one day in seconds), and then grab the date from that.

$newDate = strtotime($date_raw) - 60*60*24;
echo date('Y-m-d',$newDate);

As apokryfos pointed out: Note, this subtracts an actual day, but if you are in a place with Daylight Savings time, it could cause a problem if you need the same hour of day. However, YOU SHOULDN'T BE USING ANYTHING BUT UTC ON YOUR SERVER! Also technically there could be an issue with leap seconds

user3413723
  • 11,147
  • 6
  • 55
  • 64
  • Good one, only I made it like this : $newDate =date_create($date_raw)->getTimestamp() - 60*60*24; – Yevgeniy Afanasyev Aug 18 '15 at 06:52
  • This assumes that all days are 24 hours long which is not true in those 2 days when a minority of the world moves their clocks by +/- 1 hour to provide an illusion of more or less sunlight. And then there's leap seconds as well. – apokryfos Aug 16 '16 at 14:33
  • that's a great catch @apokryfos. I wouldn't use this for a super scientific calculation, but in the vast majority of cases it should still be just fine. – user3413723 Aug 16 '16 at 18:59