大学生からの Web 開発

廃れない技術よ 我が身に

NSDate を相対時刻にするライブラリ

時刻を相対表記にする。相対時刻とは、現在時刻から見たその時間である。たとえば 現在が 23時50分だとして何かの時刻が23時10分であれば「40分」という風に表示したい。1分以内のできごとなら「たった今」とか。

Twitter が代表例。

f:id:karur4n:20150623232305p:plain

NSDate-TimeAgo

そんなもん分かっとるわ! という感じなので、早速ライブラリを紹介する。

github.com

日本語にも対応している。date.timeAgo() とすれば取れる。

現在は MatthewYork/DateTools というライブラリに統合されていて、コントリビュートする場合はそちらにどうぞと書いてある。使いたい機能は kevinlawler/NSDate-TimeAgo に揃っているので今回はこちらを使う。

NSDate-TimeAgo を導入する

CocoaPods を用いて導入する。CocoaPods.org に公開されているバージョンは 2014年1月18日にリリースされた古いものなので GitHubリポジトリから取ってくる。

$ pod init
$ vi Podfile

Podfile

# 今回はテストを書かないので、こちらだけ
target 'ExampleTimeAgo' do
  pod 'NSDate+TimeAgo', git: 'https://github.com/kevinlawler/NSDate-TimeAgo.git'
end

target 'ExampleTimeAgoTests' do

end
$ pod install

Bridging-Header を作成する

NSDate-TimeAgo は Objective-C で書かれているので Bridging-Header を作成して Swift 上で利用できるようにする。Bridging-Header の仕組みについては理解していないので後日エントリーを書く。

以下のエントリを参考に作成していく。

tech.admax.ninja

File > New > File.... から Header File を選択する。

f:id:karur4n:20150623234128p:plain

ファイル名は ${ProductModuleName}-Bridging-Header.h とする。例えばプロジェクト名が ExampleTimeAgo なら、ExampleTimeAgo-Bridging-Header.h となる。

次に Build Settings に Bridging-Header を設定する。

f:id:karur4n:20150623234915p:plain

Objective-C Bridging Header に先ほど作成した Bridging Header のパスを入力する。Objective-C Bridging Header の場所は右上の検索バーに Swift を入力すると見つけやすい。

そして、最後に Bridging Header で使いたいライブラリを import しよう。

Bridging Header

//
//  Use this file to import your target's public headers that you would like to expose to Swift.
//

#import <Foundation/Foundation.h>
#import "NSDate+TimeAgo.h"

使う

さあ使っていく。といっても簡単。

let now = NSDate()
println(now.timeAgo()) // => Just Now

基本的なメソッドは以下。

  • timeAgo
  • dateTimeAgo
  • dateTimeUntilNow

timeAgo

基本。

let now = NSDate()
println(now.timeAgo()) // => Just now
        
let a = NSDate(timeIntervalSinceNow: -24)
println(a.timeAgo()) // => 24 seconds ago
        
let aa = NSDate(timeIntervalSinceNow: -24*60*60)
println(aa.timeAgo()) // => Yesterday
        
let aaa = NSDate(timeIntervalSinceNow: -7*60*60*24)
println(aaa.timeAgo()) // => Last week

dateTimeAgo

Yesterday や Last week ではなく、1 day ago, 1 week ago というように数字で表記される。

 let now = NSDate()
 println(now.dateTimeAgo()) // => Just now
        
 let a = NSDate(timeIntervalSinceNow: -24)
 println(a.dateTimeAgo()) // => 24 seconds ago

 let aa = NSDate(timeIntervalSinceNow: -24*60*60)
 println(aa.dateTimeAgo()) // => 1 day ago
        
 let aaa = NSDate(timeIntervalSinceNow: -7*60*60*24)
 println(aaa.dateTimeAgo()) // => 1 week ago

dateTimeUntilNow

コードは割愛するが、Today や This month というようにより具体的で自然な書式で出力される。

ローカライズする

先に述べたとおり日本語にも対応している。

Info > Custom iOS Target Properties > Localization native development region を変更する。

f:id:karur4n:20150624003318p:plain

US から

f:id:karur4n:20150624003405p:plain

JP に変更する。

f:id:karur4n:20150624003412p:plain

これで日本語化ができた。

let now = NSDate()
println(now.timeAgo()) // => たった今

let a = NSDate(timeIntervalSinceNow: -24)
println(a.timeAgo()) // => 24秒前
        
let aa = NSDate(timeIntervalSinceNow: -24*60*60)
println(aa.timeAgo()) // => 昨日

        
let aaa = NSDate(timeIntervalSinceNow: -7*60*60*24)
println(aaa.timeAgo()) // => 先週

まとめ

自分で実装するとなると条件分岐の数が多くてひたすらめんどくさいので、相対時刻を必要とするなら必須のライブラリといえる。

github.com