2019年9月30日月曜日

node.jsでの日付時刻処理(moment.jsを使ってみる) その2


オフィス狛 技術部のJoeです。

前回、moment.jsを記事にしたのですが、一部機能しか紹介できなかったので、便利だなと思った機能を追加でご紹介します。

日付時刻の比較、差分、タイムゾーンの変換は、前回の記事を参照ください。
node.jsでの日付時刻処理(moment.jsを使ってみる)

※下記の例は、moment.jsのバージョン「2.22.2」で取得した結果になります。
バージョンにより、メソッド名やオブジェクト名などが異なる場合がありますので、ご注意ください。
公式ドキュメント

【フォーマット(format)】

// フォーマットを指定
console.log(moment('2019-08-28 01:05:07').format('YYYY年MM月DD日(ddd) HH時mm分ss秒'));  // 2019年08月28日(Wed) 01時05分07秒

// 曜日を日本語表示する場合、事前にロケールを設定します
moment.locale("ja");
console.log(moment('2019-08-28 01:05:07').format('YYYY年MM月DD日(ddd) HH時mm分ss秒'));  // 2019年08月28日(水) 01時05分07秒

// フォーマットを指定して、momentオブジェクトが作成可能です
const date1 = moment("2019年08月28日(水) 01時05分07秒", "YYYY年MM月DD日(ddd) HH時mm分ss秒");
console.log(moment(date1).format('YYYY/MM/DD(ddd) HH:mm:ss'));  // 2019/08/28(水) 01:05:07

// フォーマットが英語表記の場合は、事前にロケールを変更します
moment.locale("en");
const date2 = moment("Fri Aug 28 01:05:07 am 2019", "ddd MMM DD HH:mm:ss a YYYY");
console.log(moment(date2).format('YYYY/MM/DD(ddd) HH:mm:ss'));  // 2019/08/28(Wed) 01:05:07

【加減算(add、subtract)】

// 加算
console.log(moment('2019-08-30').add(2, 'days').format('YYYY年MM月DD日(ddd)'));  // 2019年09月01日(日)

// 減算
console.log(moment('2019-08-01').subtract(2, 'days').format('YYYY年MM月DD日(ddd)'));  // 2019年07月30日(火)

// 加減算する値は、オブジェクトで指定可能です(x年xヶ月x日後など)
console.log(moment('2019-08-30').add({year :2, month :3, day :5}}).format('YYYY年MM月DD日(ddd)'));  // 2021年12月05日(日)

【開始・終了(startOf、endOf)】

// 年の開始の日
console.log(moment('2019-09-04').startOf('year').format('YYYY/MM/DD(ddd) HH:mm:ss'));  // 2019/01/01(火) 00:00:00

// 週の最後の日
console.log(moment('2019-09-04').endOf('week').format('YYYY/MM/DD(ddd) HH:mm:ss'));  // 2019/09/07(土) 23:59:59

【月の日数(daysInMonth)】

// 月の日数
console.log(moment("2020-02", "YYYY-MM").daysInMonth()) // 29

// 月末の日を取得しても同じです
console.log(moment("2020-02", "YYYY-MM").endOf('month').get('date'));  // 29

【期間内判定(isBetween)】

// 期間内の場合、trueを返します(デフォルトでは、指定した開始、終了と一致する場合、falseを返します)
console.log(moment('2019-10-19').isBetween('2019-10-19', '2019-10-25'));  // false
console.log(moment('2019-10-20').isBetween('2019-10-19', '2019-10-25'));  // true
console.log(moment('2019-10-25').isBetween('2019-10-19', '2019-10-25'));  // false

// 第3パラメータで判定基準(年、月など)を指定できます
console.log(moment('2019-10-20').isBetween('2019-09-19', '2020-11-25', 'month'));  // true
console.log(moment('2019-10-20').isBetween('2019-09-19', '2020-11-25', 'year'));  // false

// 第4パラメータで、指定した開始、終了を含む「[]」、含まない「()」を指定できます
console.log(moment('2019-10-19').isBetween('2019-10-19', '2019-11-25', null, '[]'));  // true
console.log(moment('2019-10-19').isBetween('2019-10-19', '2019-11-25', null, '(]'));  // false

【うるう年判定(isLeapYear)】

// うるう年の場合、trueを返します
console.log(moment("2020", "YYYY").isLeapYear());  // true
console.log(moment("2019", "YYYY").isLeapYear());  // false

【オブジェクトのコピー(clone)】

// 値渡しでコピーされます(参照渡しではないです)
const date1 = moment('2019-08-28 01:05:07');
const date2 = date1.clone();
// コピー元を更新
console.log(date1.year(2020).format('YYYY/MM/DD(ddd) HH:mm:ss'));  // 2020/08/28(Fri) 01:05:07
// コピー先は変更されない
console.log(date2.format('YYYY/MM/DD(ddd) HH:mm:ss'));  // 2019/08/28(Wed) 01:05:07

【ロケールをカスタマイズする】

ロケールを新たに定義して、カスタマイズすることが可能です。
// ロケール「ja」を継承して新規ロケール「my_ja」を定義
moment.defineLocale('my_ja', {
  parentLocale: 'ja',
});

// 定義を更新
moment.updateLocale('my_ja', {
  // 月(MMMM:1月、2月・・・)の定義を旧暦の月で更新
  months : ["睦月", "如月", "弥生", "卯月", "皐月", "水無月", "文月", "葉月", "長月", "神無月", "霜月", "師走"],
  // 週の最初を月曜日に更新
  week : { dow: 1 }
});

// 「my_ja」にロケールを変更
moment.locale("my_ja");

// 9月を旧暦で、周の最初を表示
console.log(moment('2019-09-04').startOf('week').format('YYYY年 MMMM DD日(ddd)'));  // 2019年 長月 02日(月)

// 2番目の引数としてnullを渡すと、定義したロケールを削除します
moment.updateLocale('my_ja', null);


日付時刻処理のライブラリは他に「dayjs」、「date-fns」、「luxon」などありますが、
「moment」は一番人気のライブラリなので、ぜひ使ってみてください。

,

2019年9月27日金曜日

ワード、エクセル、パワーポイントファイル内に貼り付けられている画像を保存する。

こんにちは、オフィス狛 デザイン部のSatoです。

「複数ある画像ファイルをエクセルに貼り付けたものが素材画像として送られてきて困った!」
「このパワーポイントに貼り付けられたロゴを保存できたらいいんだけどなあ……」
こんな風にエクセルやワードやパワーポイントに貼り付けられた画像を書き出したい、しかし方法がわからないという風に悩んだことありませんか?
今回はエクセル、ワード、パワーポイントに貼り付けられた画像の保存方法を解説します。

保存したい画像が少なめの場合は「図として保存」という機能を使うと簡単です。
保存したい貼り付けられてる画像の上で右クリックします。 出てきたメニューから「図として保存」を選択しましょう!
保存名、フォルダ、形式を選択し、保存ボタンを押せば保存完了です。


また、保存したい画像が数枚ある場合は以下の方法が便利です。
(なお、下記の手順はMacOSでの手順です)
まず、保存したい画像のあるファイルを別名コピーします。ファイルの名はどのようなものでも大丈夫です。
コピーしたファイルの名前を変更して拡張子をzipにします。(警告メッセージが出ますが「".zip"を使用」を押してください)
こうして出来上がったzipを解凍し、
解凍したファイル内に、元のファイルごとに作成されるディレクトリがあり(*1)、その中の『media』というディレクトリに画像ファイルがまとめられています。

*1)
「元ファイルがエクセルの場合は『xl』」、
「元ファイルがワードの場合は『word』」、
「元ファイルがパワーポイントの場合『ppt』」

しかし、稀にアーカイブユーティリティ(Macの場合ダブルクリックでzip解凍するとこのソフトで解凍してくれます)で解凍すると「.cpgz」という拡張子の謎のファイルが出来てしまいます。
cpgz形式のファイルをダブルクリックで解凍すると、zip形式のファイルが出来、それを解凍するとcpgz形式のファイルが……といった具合に無限ループを繰り返し、正しく解凍されません。

 調べたところ、cpgz形式のファイルが出来てしまうzipファイルはターミナルで「unzip」というコマンドを使って解凍するときちんと解凍できる、とのことだったので試してみました。
(UNIXコマンドと普段戯れていない私のような非エンジニアの方々は、デスクトップに解凍できないファイルを置いておくことを推奨します。【】の中のコマンドをC⌘でコピーして⌘Vでペーストすればなんとかなりますので……!)

デスクトップに解凍したいzipファイルを置いたので【cd Desktop/】とターミナルに入力し、エンターキーを押してデスクトップに遷移します。
(きちんと遷移したか不安な時は【ls】とターミナルに入力してみてください。 デスクトップに保存してあるファイル名がずらずらとターミナルに表示されるはずです!)
遷移後、【unzip (解凍できないファイル名).zip】(unzipとファイル名の間の半角スペースは消さないでください!)とターミナルに入力し、エンターキーを押すと処理が走るので少し待ちます。
少し待つと解凍されたファイルがデスクトップにできています! 手間はかかりましたが、どうにか保存できました!やったー!

zip解凍がうまくいかない場合にはターミナルでUNIXコマンドをぽちぽち打たなくてはいけないので、きちんとできてるのかが分かりにくいかったりと少しデザイナーにはハードルが高いですが、これら二つの方法でどうにか保存できます!
困った際は試してみてください!

, ,

2019年9月25日水曜日

ASP.NetとSqlServerでローカル環境を作ってみる。


オフィス狛 技術部のHammarです。

最近ASP.Netを主に触れているのですが、いつもテストサーバー(実際のWindowsServerのIIS上)で動作確認をしていました。が、いまさらながらローカル環境を作ってみようと思い、Dockerとwindows IISを利用して作ってみました。
基本的なプロジェクトの構成としてはローカルIISのwebサーバーとDockerの仮想DBとのデータのやり取りを実現するという内容になります。
ちなみに開発はweb画面からのアクセスではなくAPI開発で、下記のようにJSONでHTTPリクエストを行うという流れで今回やりました。

■環境

webサーバー:windows 10 IIS
DB:SqlServer(Docker)

■ローカル(winsows10)のIISを有効化する

まずはローカルのIISを有効化されているか確認する必要があります。
有効化されていない場合は下記手順で有効化します。
  1. ①コントロールパネルを開く
  2. ②プログラムを選択する
  3. ③「プログラムと機能」のWindowsの機能の有効化または無効化を選択
  4. ④「Windowsの機能」の一覧のインターネットインフォメーションサービスにチェックを入れてOKを選択
  5. ⑤デスクトップ左下のWindowsボタンを右クリック⇒コンピュータの管理を選択選択
  6. ⑥サービスとアプリケーションに「IISマネージャー」があることを確認する
  7. ⑦ブラウザにhttp://localhost/ とURLを入力し、Enterを押すと以下画面が見れる

■DockerでローカルDB環境を作る

※Dockerが既にインストールされていることが前提となります
まずはdockerを起動しておきます。
$ docker-machine start

次にdocker-compose.ymlファイルを作成し、使うDBの内容を記載します。
今回はSqlServerを使って開発したいので、下記のような記載になります。

・docker-compose.yml

version: '3'
services:
  db:
    environment:
      - MSSQL_SA_PASSWORD=password
      - ACCEPT_EULA=Y
      - MSSQL_PID=Developer
    image: microsoft/mssql-server-linux:2017-latest
    ports:
      - "1433:1433"
    volumes:
      - ./mssql/:/c/var/opt/mssql/

あとは、このdocker-compose.ymlファイルがあるディレクトリで
$ docker-compose up -d
で仮想ローカルDBを作成します。
あとはSSMS等のツールを利用し、テーブル作成等細かな設定を行います。

■IISのルートディレクトリにビルドしたファイルを設置する

visual studioでビルドしたファイルを下記IISのルートディレクトリに設置します。
C:\inetpub\wwwroot

■IISのサイトを作成する

デスクトップ左下のWindowsボタンを右クリック⇒コンピュータの管理を選択し
サービスとアプリケーションの「IISマネージャー」を選択します。

※サイトの作成方法についてはいろいろなサイトで説明があるのでここでは割愛します。

■IISサイトのサービスを開始する

サイトの「Default Web Site」で右クリック→「Webサイトの管理」→「開始」をクリックしてサイトを起動します。

あとは、作成したサイトにPOSTMAN等のツールを利用して、HTTPリクエストを投げて、正常にHTTPレスポンスが返ってくればローカル環境完成となります。

細かな部分は省いたのでかなりざっくりとした記載になってしまいましたが、ローカルIISのwebサーバーとDockerの仮想DBでローカル環境作る場合に参考になればと思います。


,

2019年9月4日水曜日

CSSで「要素が空の時の擬似セレクタ」を使う。

こんにちは、オフィス狛 デザイン部のSatoです。

先日webシステムのコーディングをする際に、「ここの要素の中身が空のときにCSSの内容を変えたいんだよなー」と考えることがありました。
jQueryを書けばいいのですがCSS3だけで出来たらいいなー、CSS3の擬似セレクタってなんでも出来そうだし……(雑なイメージ)と思ったので、できるか調べた所「要素が空の時の擬似セレクタ」が二つも見つかったので「要素が空の時の擬似セレクタ」のあれこれのメモ書き記事です。

※このブログ執筆時(2019/09/02)時点での情報です。



Mozilla Developer Centerなどで調べた所、要素が空の時の時のみ適用されるセレクタには「:empty」「:blank」の二種類があると分かりました。

:empty」は完全に要素の中が空(スペース、改行もない状態)な時のみ適用される(コメントアウトした文字は要素中に入っていても大丈夫なようです)擬似クラスで、
:blank」はスペースと改行以外の要素がない場合適用される擬似クラスであるという違いがあるそうです。

:empty」は改行やスペースがあると使えないのか……。ちょっと不便。
少しエンジニアさんに説明するの面倒だし「:blank」使おうかなと思ったのですが、まだ主要ブラウザで未実装なようです。悔しい……。
つまり現在時点では「:empty」を使わざるをえないわけですね。

See the Pen ZEzXbEN by sato (@officekoma_sato) on CodePen.


試しに「:empty」を使ってみました。(わかりにくいデモですが、最初の<div>のみ「:empty」を適用しています。
コメントアウトしている所に何か要素を入れると「:empty」を適用していない下の<div>で括った部分と背景色が同じになります。)


かなり扱いが難しいのでなかなか使いにくいですが、もしCSS3だけで要素の中身が空の時のみCSSの内容を変えたい時は擬似クラス「:empty」を思い出してください。