Last active
May 19, 2016 23:28
-
-
Save s-hiroshi/5b02a5641bf954c11c53 to your computer and use it in GitHub Desktop.
WordPressの汎用的な日付処理をまとめたユーティリティークラスです。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* InfoTown_Utils_Dateテスト | |
* | |
* @package InfoTown | |
* @subpackage tests | |
* @author Hiroshi Sawai <[email protected]> | |
* @copyright Hiroshi Sawai | |
* @version 1.0.0 | |
* @since 1.0.0 | |
*/ | |
class InfoTown_Utils_Date_Test extends WP_UnitTestCase { | |
public static function setUpBeforeClass() { | |
parent::setUpBeforeClass(); | |
require_once( dirname( dirname( dirname( __FILE__ ) ) ) . '/inc/utils/class.date.php' ); | |
} | |
/** | |
* @group date | |
*/ | |
public function test_is_day_pass_true() { | |
$d = new \DateTime(); | |
$d->sub( new \DateInterval( 'P11D' ) ); | |
$this->assertTrue( InfoTown_Utils_Date::is_day_pass( $d, 'P10D' ) ); | |
} | |
/** | |
* @group date | |
*/ | |
public function test_is_day_pass_boundary() { | |
$d = new \DateTime(); | |
$d->sub( new \DateInterval( 'P10D' ) ); | |
$this->assertFalse( InfoTown_Utils_Date::is_day_pass( $d, 'P10D' ) ); | |
} | |
/** | |
* @group date | |
*/ | |
public function test_is_day_pass_false() { | |
$d = new \DateTime(); | |
$d->sub( new \DateInterval( 'P9D' ) ); | |
$this->assertFalse( InfoTown_Utils_Date::is_day_pass( $d, 'P10D' ) ); | |
} | |
/** | |
* @expectedException PHPUnit_Framework_Error | |
* | |
* @group date | |
*/ | |
public function test_is_day_pass_exception() { | |
$d = 'a'; | |
InfoTown_Utils_Date::is_day_pass( $d ); | |
} | |
/** | |
* @group date | |
*/ | |
public function test_get_the_past() { | |
$options = [ | |
'text' => 'Old', | |
'outer' => 'div', | |
'class' => 'old', | |
]; | |
$expected = '<div class="old">Old</div>'; | |
$actual = InfoTown_Utils_Date::get_the_past( new \DateTime( '2016/3/20' ), 'P10D', $options ); | |
$this->assertEquals( $actual, $expected ); | |
} | |
/** | |
* @group date | |
*/ | |
public function test_get_the_no_past() { | |
$options = [ | |
'text' => 'New', | |
'outer' => 'div', | |
'class' => 'new', | |
]; | |
$expected = '<div class="new">New</div>'; | |
$d = new \DateTime(); | |
$d->sub( new \DateInterval( 'P10D' ) ); | |
$actual = InfoTown_Utils_Date::get_the_no_past( $d, 'P10D', $options ); | |
$this->assertEquals( $actual, $expected ); | |
} | |
/** | |
* @group date | |
* | |
* @dataProvider additionProvider | |
*/ | |
public function test_get_day( $d, $expected ) { | |
$actual = InfoTown_Utils_Date::get_day( $d ); | |
$this->assertEquals( $actual, $expected ); | |
} | |
public function additionProvider() { | |
$data = [ | |
[ '2016/4/17', 'Sunday' ], | |
[ '2016/4/18', 'Monday' ], | |
[ '2016/4/19', 'Tuesday' ], | |
[ '2016/4/20', 'Wednesday' ], | |
[ '2016/4/21', 'Thursday' ], | |
[ '2016/4/22', 'Friday' ], | |
[ '2016/4/23', 'Saturday' ], | |
]; | |
return $data; | |
} | |
/** | |
* @group date | |
*/ | |
public function test_get_oldest_year() { | |
$cat = $this->factory->category->create_and_get( | |
[ | |
'name' => 'Year test category', | |
'slug' => 'year_test' | |
] | |
); | |
$this->factory->post->create( | |
[ | |
'post_category' => [ $cat->term_id ], | |
'post_date' => '2010-01-01 00:00:00' | |
] | |
); | |
$args = [ 'category_name' => 'year_test' ]; | |
$actual = InfoTown_Utils_Date::get_oldest_year( $args ); | |
$this->assertEquals( 2010, $actual ); | |
} | |
/** | |
* @group date | |
*/ | |
public function test_get_latest_year() { | |
$cat = $this->factory->category->create_and_get( | |
[ | |
'name' => 'Year test category', | |
'slug' => 'year_test' | |
] | |
); | |
$this->factory->post->create( | |
[ 'post_category' => [ $cat->term_id ] ] | |
); | |
$args = [ 'category_name' => 'year_test' ]; | |
$actual = InfoTown_Utils_Date::get_latest_year( $args ); | |
$date = new \DateTime(); | |
$date->setTimezone( new \DateTimeZone( 'UTC' ) ); | |
$expect = (int) $date->format( 'Y' ); | |
$this->assertEquals( $expect, $actual ); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* 日付処理 | |
* | |
* @package InfoTown | |
* @subpackage Utils | |
* @author Hiroshi Sawai <[email protected]> | |
* @copyright Hiroshi Sawai | |
*/ | |
class InfoTown_Utils_Date { | |
/** | |
* 日付の経過を検証 | |
* | |
* 引数のDateTimeオジェジュクトが現在時刻から$diffで渡した期間を経過しているか検証します。 | |
* | |
* @param \DateTime $past 比較対象のDateTimeオブジェクトです。 | |
* @param string $diff 期間を指定します(P1Dなら1日経過、2週間ならP14D)。 | |
* | |
* @return boolean 現在時刻から$diffが経過しているときはtrueを返します。未経過のときはfalseを返します。 | |
* @throws InvalidArgumentException 第1引数がDateTime型でないときはInvalidArgumentExceptionを返します。 | |
*/ | |
public static function is_day_pass( \DateTime $past, $diff = 'P7D' ) { | |
if ( ! $past instanceof \DateTime ) { | |
throw new InvalidArgumentException( 'DateTime型のオブジェクトではありません' ); | |
} | |
$timezone = $past->getTimezone(); | |
$now = new \DateTime( '', $timezone ); | |
$past->add( new \DateInterval( $diff ) ); | |
if ( $now > $past ) { | |
return true; | |
} | |
return false; | |
} | |
/** | |
* 指定時間を経過しているときオプションをもとにマークアップを構築 | |
* | |
* @param \DateTime $past 現時刻と比較するDateTimeオブジェクトです。 | |
* @param string $diff 期間を指定します。 | |
* @param array $options 作成するマークアップ情報です。 | |
* | |
* @return string 引数の\DateTimeオブジェクトが現在時刻から$diffが経過いるときプションにもとづき作成したマークアップをかえします。 | |
* 経過していないときは空文字を返します。 | |
*/ | |
public static function get_the_past( $past, $diff = 'P7D', array $options = [] ) { | |
$default = [ | |
'text' => 'Past', | |
'outer' => 'div', | |
'class' => '', | |
]; | |
$options = array_merge( $default, $options ); | |
$is_past = self::is_day_pass( $past, $diff ); | |
$data = ''; | |
if ( $is_past ) { | |
$class = ( ! empty( $options['class'] ) ) ? ' class="' . $options['class'] . '"' : ''; | |
$data = '<' . $options['outer'] . $class . '>' . $options['text'] . '</' . $options['outer'] . '>'; | |
} | |
return $data; | |
} | |
/** | |
* 指定時間が未経過のときオプションをもとに作成したマークアップ取得 | |
* | |
* @param \DateTime $past 現時刻と比較するDateTimeオブジェクトです。 | |
* @param string $diff 期間を指定します。 | |
* @param array $options 作成するマークアップ情報です。 | |
* | |
* @return string 引数の\DateTimeオブジェクトが現在時刻から$diff経過していないときプションにもとづき作成したマークアップをかえします。 | |
* 経過しているときは空文字を返します。 | |
*/ | |
public static function get_the_no_past( $past, $diff = 'P7D', array $options = [] ) { | |
$default = [ | |
'text' => 'No Past', | |
'outer' => 'div', | |
'class' => '', | |
]; | |
$options = array_merge( $default, $options ); | |
$is_past = self::is_day_pass( $past, $diff ); | |
$data = ''; | |
if ( ! $is_past ) { | |
$class = ( ! empty( $options['class'] ) ) ? ' class="' . $options['class'] . '"' : ''; | |
$data = '<' . $options['outer'] . $class . '>' . $options['text'] . '</' . $options['outer'] . '>'; | |
} | |
return $data; | |
} | |
/** | |
* Y/n/j文字列から英語表記の曜日取得 | |
* | |
* @param string $raw Y/n/j形式の文字列です。 | |
* @param string $timezone タイムゾーンです。 | |
* | |
* @return string 曜日の英語表記を返します。 | |
* | |
*/ | |
public static function get_day( $raw, $timezone = '' ) { | |
$timezone = ( '' === $timezone ) ? date_default_timezone_get() : $timezone; | |
$datetime = new DateTime( $raw ); | |
$datetime->setTimezone( new DateTimeZone( $timezone ) ); | |
$datetime->format( 'Y/n/j' ); | |
$day = $datetime->format( 'l' ); | |
return $day; | |
} | |
/** | |
* 最も新しい投稿年取得 | |
* | |
* @param array $args get_postsへ渡す引数です。 | |
* | |
* @return bool|int 投稿年を返します。投稿がないときはfalseを返します。 | |
*/ | |
public static function get_latest_year( $args ) { | |
$default = [ 'order' => 'DESC' ]; | |
$args = array_merge( $default, $args ); | |
$latest_posts = get_posts( $args ); | |
if ( ! empty( $latest_posts ) ) { | |
$dt = new \DateTime( $latest_posts[0]->post_date ); | |
return (int) $dt->format( 'Y' ); | |
} | |
return false; | |
} | |
/** | |
* 最も古い投稿年取得 | |
* | |
* @param array $args get_postsへ渡す引数です。 | |
* | |
* @return bool|int 投稿年を返します。投稿がないときはfalseを返します。 | |
*/ | |
public static function get_oldest_year( $args ) { | |
$default = [ 'order' => 'ASC' ]; | |
$args = array_merge( $default, $args ); | |
$old_posts = get_posts( $args ); | |
if ( ! empty( $old_posts ) ) { | |
$dt = new \DateTime( $old_posts[0]->post_date ); | |
return (int) $dt->format( 'Y' ); | |
} | |
return false; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment