忍者ブログ

開発者ブログ

忍者ブログの元開発者が送る愛と感動と涙のスペクタクル。プログラムの開発日誌やタダの日記です。

[PR]

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

PHPで日本の祝日判定処理

来年久しぶりに国民の祝日があるらしいので、需要あるかな?と思ってソースを置いておきます。
ご自由にお使いください

2008年以降の日本の祝日の判定です。
2016年から始まる山の日も含まれています。
(今年から祝日が増えるのか!!!と思ってwktkした祝日です。がっかりしました)

2007年以前の過去で使用したい場合は5/4の扱いが変わるのでちょっと書き換える必要があります。

未来については祝日が増えるまでは変えなくて良いはず。
※mktimeを使っているので、環境によっては2038年までしか使えないかもしれません。

・祝日が増える/減る
・地球の自転がおかしくなる

などがあると修正が必要になります。


http://file.samurai.blog.shinobi.jp/Holiday.php


/*
* ZendX_Date_Holiday
*
* 2007年以降の日本の祝日を判定します
*
* 2006年より過去に遡った調査をする場合は要調整(5/4が国民の休日になる)
* wikipedia(http://ja.wikipedia.org/wiki/国民の祝日)とかで確認して$ddやkokumin()、spring()、autumn()辺りを調整してください
*
* @cateogry ZendX
* @package ZendX_Date
* @author misney <mizuno@ninja.co.jp>
*/
class ZendX_Date_Holiday {

/**
* 平日かな?
*
* @return boolean
*/
public static function isWeekday($y, $m, $d) {
if (self::isHoliday($y, $m, $d)) {
return false;
} else {
return true;
}
}

/**
* 祝日かな?
*
* @return boolean
*/
public static function isHoliday($y, $m, $d) {
$t = mktime(0,0,0,$m,$d,$y);
$w = date("w", $t);
$wc = intval($d / 7) + 1;

//祝日定義
$dd = array(
1=>array(1=>true, 'function'=>array('monday2')),
2=>array(11=>true),
3=>array('function'=>array('spring')),
4=>array(29=>true),
5=>array(3=>true, 4=>true, 5=>true),
7=>array('function'=>array('monday3')),
9=>array('function'=>array('autumn', 'monday3', 'kokumin')),
10=>array('function'=>array('monday2')),
11=>array(3=>true, 23=>true),
12=>array(23=>true),
);

//山の日は2016年から
if ($y >= 2016) {
$dd[8] = array(11=>true);
}

if (!empty($dd[$m][$d])) {//決められた祝日
return true;
}

//ハッピーマンデイや春秋分、国民の休日がある月は関数処理
if(!empty($dd[$m]['function'])) {
foreach ($dd[$m]['function'] as $func) {
if (self::$func($y, $m, $d, $w, $wc, $t)) {
return true;
}
}
}

//水曜日までは振替休日をチェック。
if ($w < 4) {
$_w = $w;
$_y = $y;
$_m = $m;
$_d = $d;
while($_w > 0) {
//1日の場合は前月末日を作成する
if ($d == 1) {
$t = $t - 86400;
$_y = date("Y", $t);
$_m = date("m", $t);
$_d = date("d", $t);
} else {
$_y = $_y;
$_m = $_m;
$_d = $_d - 1;
}

if (self::isHoliday($_y, $_m, $_d)) {
$_w--;
if ($_w == 0) {
return true;
}
} else {
break;
}
}
}
return false;
}

/**
* ハッピーマンデーかな?(第2月曜日)
*
* @return boolean
*/
private static function monday2($y, $m, $d, $w, $wc, $t) {
if ($w == 1 && $wc == 2) {
return true;
}
return false;
}

/**
* ハッピーマンデーかな?(第3月曜日)
*
* @return boolean
*/
private static function monday3($y, $m, $d, $w, $wc, $t) {
if ($w == 1 && $wc == 3) {
return true;
}
return false;
}

/**
* 春分の日かな?
*
* 前年2月の最初の平日に制定されるらしい。(官報に掲載される暦要項)
* 地球の運行状態が変化した場合などに変更される可能性はあるらしい(過去には無い)
*
* @return boolean
*/
private static function spring($y, $m, $d, $w, $wc, $t) {
$p = $y % 4;
switch($p) {
case '1':
$_d = '20';
break;
case '2':
if ($y < 2023) {
$_d = '21';
} else {
$_d = '20';
}
break;
case '3':
if ($y < 2056) {
$_d = '21';
} else {
$_d = '20';
}
break;
default:
if ($y < 2089) {
$_d = '20';
} else {
$_d = '19';
}
break;
}
if ($d == $_d) {
return true;
}
return false;
}


/**
* 秋分の日かな?
*
* 前年2月の最初の平日に制定されるらしい。(官報に掲載される暦要項)
* 地球の運行状態が変化した場合などに変更される可能性はあるらしい(過去には無い)
*
* @return boolean
*/
private static function autumn($y, $m, $d, $w, $wc, $t) {
$p = $y % 4;

switch($p) {
case '1':
if ($y < 2042) {
$_d = '23';
} else {
$_d = '22';
}
break;
case '2':
if ($y < 2075) {
$_d = '23';
} else {
$_d = '22';
}
break;
case '3':
$_d = '23';
break;
default:
if ($y < 2009) {
$_d = '23';
} else {
$_d = '22';
}
break;
}

if ($d == $_d) {
return true;
}
return false;
}

/**
* 国民の休日かな?
*
* 祝日と祝日に挟まれた日は祝日というオセロのような祝日。
* 2013年現在は9月21日or22日の火曜日にしか発生しない。
*
* @return boolean
*/
private static function kokumin($y, $m, $d, $w, $wc, $t) {
if (($d == 21 || $d == 22) && $w == 2) {
if (self::isHoliday($y, $m, $d-1, $w-1, $wc, $t) && self::isHoliday($y, $m, $d+1, $w+1, $wc, $t)) {
return true;
}
}
return false;
}

}

拍手[0回]

PR

MemcacheとMemcached

こんにちは。misneyです。

今日はPHPのお話。

PHPにはMemcacheMemcachedという二つのクラスがあります。
podさん曰く、Memcachedのがいいんだという話。

早速今作成中のサービスを、MemcacheクラスからMemcachedクラスに変えることにしました。
ということで、インストールメモなのです。

まずはpeclで頑張ってみる。

pecl install memcached-0.1.5

・・・なんかMemcachedを使うにはPHP5.2以上じゃないとだめらしい。
残念ながら5.1.6だったので、PHP5.2にしたい。

yumで入れるのでrepoを変える必要があります。
"remi.repo"を使って、変な依存関係はpodさんに解消してもらってインストール。

もっかいチャレンジ。

pecl install memcached-0.1.5

今度はlibmemcachedがないおと。
確かにインストール手順に書いてあった。

rpmを落としてみる
またインストール失敗。
むしゃくしゃしたのでソースから入れた。

もっかいチャレンジ。

pecl install memcached-0.1.5

これでやっと入ったみたい。

/etc/php.dにmemached.iniを作ってextension=memcached.soを書く。

次にMemcacheとの相違点。

connectがない。変わりはaddServerというメソッド。
最近のPHPはaliasを作ってくれないのかと思った。
まあ、要らないか。

あとはsetが色々な種類になって動かなくなった。

set(key, value)
setMulti(array(key,value)[, expire])

他にもsetByKeyとかsetMultiByKeyなんてのがある。
ちょっと試す時間がないので試してないんだけど、こっちのが楽しそう。

で、ちょっと書き直して終了。

動くは動く。

暇を見つけて、どのくらいの違いが出るのかやってみようと思います。

 

拍手[1回]

Zend Serverについて

こんにちは。水野です。

先日、Zendさんから、Application Serverが出ましたね。

Zend Server
http://www.zend.com/en/products/server/

簡単に読んでみたんですが、以下のようになってるみたいっすね。

HTTPD (Apache or IIS)
PHP
Zend Framework
MySQL
Built in DB Connectivity
Java connector
Admin Console
Debugger Interface
Bytecode Acceleration
Caching API

さらに有料版は以下の物が。

Page Caching
Application monitoring
Application Problem diagnostics
Software updates and hot fixes
support

・・・・いまいち使い道が沸かない。
僕はなんだかこういうのが苦手なのです。
触る前にこんな記事を書くのもあれですが、簡単に素敵なシステムが作れちゃうって感じですかね。
xamppのリッチ版みたいな。

パフォーマンスの向上は以下のような機能があるっぽい

Code Acceleration
Full page caching
Partial page caching

簡単なキャッシュ機能で軽いっぽく・・・って感じですかね。
手軽に効率良く出来るのかも知れないのですが、どうなんでしょうか。
パーシャルキャッシュとか考えるのが結構大変なので、その辺で作業効率が上がるなら素敵かも?
動作効率も作業効率も良くなったりしたら最高ですね。

もう少し経って使い倒したレビューなどを見た頃に、しっかりと調べてみたいと思いました。
どこかのPodさんが使い倒してくれるのを楽しみにしています。

拍手[1回]

PHPの最適化 12 PHP Optimization tips の話。

こんばんわ。misneyです。

今日はPHPの話を。

先日、会社の開発者向けMLであった話。
これを使うと遅いから、こっちを使おうよ!って話なんですが、実際どれくらい違うのかなーと思って、調べてみました。

ただ、自分で調べたので結構違うかも。

1.static使えるならstaticを使えば良いじゃんって話
速度が4倍速いらしい。

method 0.040376/ms
static method 0.037899/ms


4倍は言いすぎな気がするけど早い。



2.require_onceよりもrequireを使おうって話

require_onceはコストが高いらしい

require_once 0.246451/ms
require 0.245562/ms


ちょっと早い。


3.requireは絶対パスだと速いよって話

確かにそうだろうなと思う。
(inclue_pathが2種類の場合)

絶対パス 0.185428/ms
相対パス 0.209057/ms (1種類だと0.188036/ms)


もっと沢山のPATHが登録されていると重くなりそう。



4.time()より$_SERVER['REQUEST_TIME'] が良いって話し
確かにそうかも。

time() 0.043423/ms
$_SERVER['REQUEST_TIME'] 0.043805/ms


それほどでもない。



5.preg_matchよりstrpos

preg_match("/a/", $str)と strpos($str, "a")の違い

preg_match 0.129704/ms
strpos 0.050249/ms


これはかなり違う。事足りるなら文字列関数のが良さそう



6.preg_replace >> str_replace > strtr

strtrが一番早いよって話

preg_replace 0.129719/ms
str_replace 0.049164/ms
strtr 0.049107/ms


strtrはもう少し早かったかも。2回目の計測はstr_replaceとほぼ一緒。
preg_は使うなということで。



7.エラー制御演算子(@)のコストが高い

コストが高いらしい。

最初に$a ='';の宣言をつける場合と
$a = @$str;と
$a = (isset($a)) ? $a : '';でチェック。

@ 0.041778/ms
isset 0.044086/ms
宣言 0.036695/ms


最初に宣言できればそれ。$_POST['param']とか必要な物は@のがいいかも。



8.$row[id]より$row['id']のが7倍早い

これは速さ以前にNOTICEエラー。

[id] 0.043816/ms
['id'] 0.036614/ms


そして遅い。



9.for($i=0;$i<count($arr);$i++){}は、前もって$len = count($arr);に

良く聞く話です。

for($i=0;$i<count($arr);$i++){} 0.056426/ms
$l=count($arr);for($i=0;$i<l;$i++){} 0.055037/ms


繰り返し回数5回での差。いっぱいあるほど顕著に現れるかも。
$arrの数が変わるような場合だけ使う。


あと3つあるんですが、再現で悩んでしまったので省略しました。
この結果は環境によって変わりそうですし、私ですし、多分おかしな点があります。
@の方がisset()より早いとは思えない。
そんな訳で参考までに。



カタコト日記さん(http://d.hatena.ne.jp/koto2/20080518/1211070116
というブログで63+ Best practice optimize PHP code performanceという記事を和訳されたページがあり、これがまた面白いです。


とりあえず、正規表現を良く使ってしまうので、文字列関数を使うように心がけたいと思いました。

拍手[1回]

ZendFrameWorkとかjavascriptでPHPのserialize化とか

こんばんわ。
misneyです。
結構この名称、まだ恥ずかしかったりします。

たまには仕事の話をしようかなーと思いました。

今日家から帰ってきて、パソコンに向かっていたのですが、ZendFrameWorkのページを見る機会があったのです。

私は普段PHPを使ってプログラムを作っているのですが、フレームワークは昔から使ってる自分のフレームワークだったりするんです。
そう。頭悪いので、他人様のソースを使うのが苦手なんです。

今日はZend_Controllerってのを見てたのですが、これが結構自分のやり方に似ていたのです。
なんか、これなら自分でも使えるかもしれないなーと思いました。
ソースも自分とは比べ物にならないほど綺麗ですし、処理も凄く纏まってる。
ZendStudioも良い動きしますし、Zendさんはスゴイですね。

しかし、相変わらずこの手の解説は難しいのです。
解説書の解説書が欲しいところです。


さて、ついでにもう一個。
最近、SQUiのアイテム取得部分の処理を修正しました。
まだ修正状態を更新してないので、見ることは出来ないのですが。

$CHさんから、「私が登録したい画像が取得されないわよ!!」と怒られたので、ちゃんと取得するようにしようと思ったのです。

SQUiのアイテム取得は、ブックマークレットの処理でHTMLに含まれる商品の画像など、いくつかの情報を取ってくるってな感じの処理なのです。

HTMLの情報の中から、最も適した順に画像を並べるのが理想なのですが、今は何の処理も入れてません。外したのです。重かったので。

なので、今度は軽い処理で実装できる物を考えてみました。
単純にjavascriptで解析してあげればいいかなーって考えたのです。

getElementByTagName('img')で取ってきたnodeから、alt , width , height の値を取ってくる。
その情報から最適化を行えばいいじゃーんて。
SQUiで最初に作ったプロトタイプがこのバージョン。

さて、このデータをどうやって送ろうかなーと考えたときに思ったのが、PHPのserialize形式で送ってみようかなーって方法だったのです。

serialize化の形式は何となく解かってたので、同じようなのを作ってみたんです。

動くところまでは思っていたより簡単に出来たのですが、ごく稀にエラーが。
どうもマルチバイト文字のbyte計算がたまに間違うようで。

さらにURL入力の方で違った取得方法になってしまうということから、お蔵入りになっちゃいました。
久しぶりの自信作だったのにザンネン。

結局サーバーサイドで最適化処理を入れました。
今度の処理は軽いので結構いい感じです。

javascriptのserializeは、そのうち何かで使ってみたいなーって思いました。
上手く動くようになったらここで公開してみようと思います。


ちなみに、その後serialize化は誰かが作ってるんだろうなーって思って探したら、やっぱりありました。

ASPAN PHP serializer

でも、マルチバイト対応じゃないから、日本語が入ると動かないと思う。
obj.lengthのとこはcharAt + escapeとかでバイト計算をしてやらないとだめ。
バイト計算と言っても時給 × 時間じゃない。

拍手[4回]

おまとめボタン

忍者カウンター

忍者ビジター

忍者アド

ブログ内検索

最新コメント

プロフィール

HN:
mizuno
年齢:
43
HP:
性別:
男性
誕生日:
1974/02/13
職業:
主に侍などを少々
趣味:
SEO(「申し訳ございません」や「指ぱっちん」「指定したサイトへは接続できませんでした」でググルと上位に。)
自己紹介:
母子手帳の仮死と書かれてる場所に丸されてます。

フリーエリア

忍者ツールズプロフィール

忍者ツールズプロフィールは終了しました