かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

PHP Carbonを使って週表示のカレンダーを作りたい。

週だけ表示できる良い感じのカレンダーが見つからなかったのでPHPで作ってみました。
日付の処理はLaravelでも使用されているCarbonが便利らしいので、これを使うことにしました。

仕様

  • 簡易に曜日と日付が表示できればOK
  • 週の始めは月曜 / 日曜
  • 前後で月が変わる部分も表示する

CarbonをComposerでインストー

$ composer require nesbot/carbon

週カレンダーを作成するスクリプト

<?php
require 'vendor/autoload.php';
use Carbon\Carbon;

/**
 * 週カレンダーの配列を返す関数
 * @param: $startSun(:Boolean)
 *         true ... 日曜から始める
 *         false ... 月曜から始める
 * @param: $date(:String) ... 今日の日付
 */
function getWeekCalender($isStartSun = true, $date = "") {
  $today = new Carbon( $date );
  $todayDay = $today->day;
  $startDate = getStartDay( $today->toDateString("Y-m-d"), $isStartSun );
  $startDay = $startDate->day;
  // 週の最終日を取得
  // note. コピーを作成しないと元のインスタンスの値が変更される
  $lastDay = $startDate->copy()->addDay(7)->day;

  // 開始日のある月の最終日を取得
  $limitDay = $startDate->copy()->endOfMonth()->day;

  $month = $startDate->month;
  $offset = $limitDay - $startDay;
  $day = $startDay;
  $weekArr = [];
  $i = 0;
  while($i < 7) {
    $day = $startDay + $i;
    // 月を跨いだ時
    if( $day > $limitDay ) {
      $day = $i - $offset;
      if($day === 1) {
        $month += 1;
      }
      if($month > 12) {
        $month = 1;
      }
    }
    if($isStartSun) {
      $week = getWeekByIndex($i);
    } else {
      $week = getWeekByIndex($i+1);
    }
    $weekArr[] = [
      'month' => $month,
      'day'   => $day,
      'week'  => $week,
      'today' => $todayDay === $day? true : false,
    ];
    $i++;
  }

  return $weekArr;
}

/**
 * 週の最初の日を取得
 * @param $today(:String) "Y-m-d"
 */
function getStartDay($today, $isStartSun) {
  $dt = new Carbon( $today );

  // $today が週の内何日目か (Sun = 0)
  $w = $dt->dayOfWeek;

  // 月曜始まりのとき
  if( !$isStartSun ) {
    // 今日が日曜なら前の月曜
    if($w === 0) {
      $w = 7;
    }
    $w -= 1;
  }

  return $dt->subDay( $w );
}

function getWeekByIndex($i) {
  $arr = ['Sun.', 'Mon.', 'Tue.', 'Wed.', 'Thu.', 'Fri.', 'Sat.'];
  $len = count($arr);
  if($i >= $len) {
    $i -= $len;
  }
  return $arr[$i];
}

使い方

<?php
// 今日の日付を指定する場合は第ニ引数で指定
// ex: 月曜始まり 2017年3月3日 のある週カレンダー
$weekCalenderData = getWeekCalender(false, "2017-03-03");

// カレンダーを出力
foreach($weekCalenderData as $val) {
  $th .= "<th>{$val['week']}</th>\n";
  $td .= "<td>{$val['day']}</td>\n";
}
echo "<table><tr>${th}</tr><tr>{$td}</tr></table>";

↓ 出力

Mon. Tue. Wed. Thu. Fri. Sat. Sun.
27 28 1 2 3 4 5

感想とか

Carbon は月末日とか簡単に取得できて凄い便利なのですが、関数を使うと元のオブジェクトの日付が変更されてしまう破壊的メソッド(?)なので、元の日付から色々計算した日付を取得したい時はcopy()メソッドを噛ませてオブジェクトを複製しないとハマりそうだなって思いました。


Signalize!/カレンダーガール

Signalize!/カレンダーガール

CSSで三日月を描く

三日月は地球の影が月に重なってできています。なので、CSSで三日月を描くには同じように月になる円形の上に背景色と同じ円形をずらして重ねればOKなのですが、これでは背景がパターンだったりすると困ります。
月部分以外が透過になっている三日月をCSSで描く方法を考えました。

サンプル

See the Pen CSS CRESCENT MOON by KIKIKI (@chaika-design) on CodePen.

1. borderを使って描く

border-radiusで作った円形の中にborderの円を作り、これをずらして不要な部分をoverflow:hiddenで隠してしまう方法

.moon
  position: relative
  display: block
  margin: 2rem
  width: 10rem
  height: 10rem
  background-color: transparent
  border-radius: 50%
  overflow: hidden
  &:before
    position: absolute
    content: ''
    display: block
    top: -20px
    left: -45px
    width: 10rem
    height: 10rem
    border: 30px solid $moon-color
    border-radius: 50%

borderの円の位置をtopとleftで調整して三日月にするのですが調整が少し難しいです。

2. box-shadow を使って描く

border-radiusで作った円形の内側にbox-shadowを使って描く方法

.moon
  display: block
  margin: 2rem
  width: 10rem
  height: 10rem
  background-color: transparent
  box-shadow: inset -12px 5px 0 3px $moon-color
  border-radius: 50%

こちらの方がシンプルで描画やアニメーションを付けるにも調整しやすい感がありました。
box-shadow サポート状況


f:id:kikiki-kiki:20170613072232g:plain
全く関係ないけど、LGTMが透過で付けれるサービスが欲しい…
練習がてら自分で作ろうかな。

おうち用 NEW マシンをセットアップしたお話。

家族が使ってるマシンが古いせいか遅すぎてストレスがあると言うことだったので、新しいマシンを見繕いました。

  1. ちょっとしたWEB閲覧くらいでしか使用しない
  2. 起動などの動作が軽快であること
  3. 持ち運びが簡単だと良い
  4. 老眼になってきているので拡大できると良い

上記の条件から、新しいiPad (第5世代) を導入してみることにしました。(新しいiPadお安いですし)
f:id:kikiki-kiki:20170530135144j:plain
こんな感じです

自宅使用でのメールなどはやはりキーボードの方が書きやすいので、Apple純正の1つ前のキーボード(MC184J/B)を導入。JIS版でもBluetooth接続でiPad (第5世代) で問題なく使用できており、英数・かな キーでiPadの入力言語を切り替えられるのでMacのUSキーに慣れて無くても使用することができます!(最新のMagic Keyboardは上下キーが打ちにくいので、使わなくなったらこのキーボードは僕が貰おうと企んでる)

また、外出時でも使えるようにSIMフリー版にして、DMM mobileの1Gプラン(月額500円程度)を入れています。
DMMのプランはその月に余った分が持ち越しできるので、ほぼ自宅使用なら1Gでも十分ですし、なによりランニングコストが格安なので助かります。
SIMフリーで使えるセルラー版はAppleのストアでしか購入できないという点だけが少しメンドーでした。

現状はiPadスマートフォン的な使い方への慣れの問題で戸惑う部分もあるようですが、起動の速さや、設定で最初から大きな文字にできたり、WEBページを拡大できたりする部分での満足度は高いようです。
それと、自宅の机上で使うときとかに高さが出せるスタンドが、覗き込む姿勢になったり、片手でずっと持っておかなくて済むので楽で良いと好評でした。
 
今回やりたい事や今までPCでやってた事を聞いて、iPadを導入してみて使っているのを見ている限り、ネットとかあまり詳しくない家族がPCでやってた範囲のことはタブレット端末で出来ることで十分なように感じました。
個人的にラップトップとかデスクトップとかは、特にマウスとかは将来的にはプログラマとか研究施設とか特殊な仕事の人が使うものになっていって、タッチペンでノートのように使えるタブレットが一般家庭や事務職とかで使われていくようになるんじゃないかなぁ〜なんて考えてましたが、改めてそうなっていきそうだなって思いました。
(それより、Facebookでよく見る人のページをブラウザでブックマークしていたのを、「Facebookでブックマークしたからアプリでもブックマークしたの見れるはずだ!」とか言い張られた時にはビックリしました。ブラウザ自体の機能と、そこに表示されているWEBページ・WEBアプリ内の機能の違いを理解してないって結構あるんだろうなぁ〜って学びになりました。  

以下 今回導入したモノのリスト。

SIMフリー版 (セルラー版) は今の所Appleでしか取り扱ってないらしい…

Apple Wireless Keyboard (JIS) MC184J/B

Apple Wireless Keyboard (JIS) MC184J/B

個人的に上下キーがこちらの方が使いやすいという理由で導入。
JIS配列の英数・かなでiPad(第5世代)の入力言語の切替可。

iPadを縦・横置きできるスタンド。
常にiPadを持っておかなくて済む・机の上において覗き込む姿勢にならなくて済むという事で好評。
付いてる粘着シートはかなり強力。粘着シート使わなくても結構安定してます。

保護シート。
シートというよりガラス板だったけど、貼る用のガイドも付いていて大きな画面でもズレずに貼ることができた。(予備シートは無し)
ただ、厚さがそれなりにあるのでタッチパネルの反応は少し悪くなってるかもしれません。

iPad (第5世代)はnano SIM。
データ持ち越しプランは凄い!
(後はDMMが2段階認証と複数の決裁カードを登録できるようになるととてもありがたいです…)

なぜかAmazonでDMMのSIMが売っていて、ここで買うと初期手数料が掛からないらしいですが… 試してないので真実や如何に?