หลายวันก่อนมีสมาชิกในชมรมคนทำเว็บโพสว่า php คิดเดือนให้ผิด เชื่อถือไม่ได้ เราก็ใช้ php มานาน ก็คิดว่าเค้าเขียน code ผิดรึเปล่า แต่เค้าก็บอกว่าลบ code ออกไปแล้ว แต่ก็ให้ตัวอย่างวันที่มา ลองเขียน code date_diff ดูมันนับผิดจริงๆ ลองไล่หาสาเหตุดูเข้าใจว่ามันคิดผิดเพราะนับเป็นวัน สาเหตุ คือ php จะแปลงวันที่เป็นตัวเลข timestamp อย่าง
- 2010-04-28 22:41:43 = 1272508903
- 2007-02-14 20:25:25 จะเป็น 1171502725
และแต่ละเดือนมีวันไม่เท่ากัน แถมบางปีเดือนกุมพาพันธ์ ก็มี 28 / 29 วัน แต่ date_diff ของ php เหมือนจะไม่ได้คิดเรื่องนี้ เอาเวลาตายตัวมาคิด ทำให้ต้องใช้วิธี แยกปี แยกเดือน แล้วเอามาใส่สูตรเอาเอง
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | <?php $dateRanges = [ [ '01/02/2016' , '01/03/2016' ], [ '01/02/2016' , '01/04/2016' ], [ '01/11/2013' , '30/11/2013' ], [ '01/01/2013' , '31/12/2013' ], [ '31/01/2011' , '28/02/2011' ], [ '01/09/2009' , '01/05/2010' ], [ '01/01/2013' , '31/03/2013' ], [ '15/02/2013' , '15/04/2013' ], [ '01/02/1985' , '31/12/2013' ], ]; foreach ( $dateRanges as $range ) { list( $dateStart , $dateEnd ) = $range ; $timeStart = DateTime::createFromFormat( 'd/m/Y' , $dateStart ); $timeEnd = DateTime::createFromFormat( 'd/m/Y' , $dateEnd ); $months = $timeStart ->diff( $timeEnd )->format( '%m' ); echo '<br>' , $dateStart , ' => ' , $dateEnd , ' = ' , $months , ' months' ; } echo '<hr>' ; foreach ( $dateRanges as $range ) { list( $dateStart , $dateEnd ) = $range ; $timeStart = DateTime::createFromFormat( 'd/m/Y' , $dateStart ); $timeEnd = DateTime::createFromFormat( 'd/m/Y' , $dateEnd ); $months = abs (( $timeEnd ->format( 'Y' ) - $timeStart ->format( 'Y' )) * 12 + ( $timeEnd ->format( 'm' ) - $timeStart ->format( 'm' ))); echo '<br>' , $dateStart , ' => ' , $dateEnd , ' = ' , $months , ' months' ; } |
ผลที่ได้คือ
- 01/02/2016 => 01/03/2016 = 1 months
- 01/02/2016 => 01/04/2016 = 2 months
- 01/11/2013 => 30/11/2013 = 0 months
- 01/01/2013 => 31/12/2013 = 11 months
- 31/01/2011 => 28/02/2011 = 0 months
- 01/09/2009 => 01/05/2010 = 8 months
- 01/01/2013 => 31/03/2013 = 2 months
- 15/02/2013 => 15/04/2013 = 2 months
- 01/02/1985 => 31/12/2013 = 10 months
- 01/02/2016 => 01/03/2016 = 1 months
- 01/02/2016 => 01/04/2016 = 2 months
- 01/11/2013 => 30/11/2013 = 0 months
- 01/01/2013 => 31/12/2013 = 11 months
- 31/01/2011 => 28/02/2011 = 1 months
- 01/09/2009 => 01/05/2010 = 8 months
- 01/01/2013 => 31/03/2013 = 2 months
- 15/02/2013 => 15/04/2013 = 2 months
- 01/02/1985 => 31/12/2013 = 346 months
About the author