Skip to content

Instantly share code, notes, and snippets.

@s-hiroshi
Last active May 19, 2016 23:28
Show Gist options
  • Save s-hiroshi/5b02a5641bf954c11c53 to your computer and use it in GitHub Desktop.
Save s-hiroshi/5b02a5641bf954c11c53 to your computer and use it in GitHub Desktop.
WordPressの汎用的な日付処理をまとめたユーティリティークラスです。
<?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 );
}
}
<?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