6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

swiftのUnitTestで海外への渡航、サマータイムなどタイムゾーンが変わる時のテストを書く

Last updated at Posted at 2017-01-10

サマータイムや渡航によって、保存されている時間データと、現在時刻のタイムゾーンにズレが生じる。それによって、所定の時間に通知がこない。コンテンツが更新されない。などはよくある話です。
今回、そのよくある話に見事はまったので、そのテストを書きました。

サマータイムは同じ場所に居ながら、時差が変更される

サマータイムとは、夏は早く明るくなるんだから、一日をちょっと早く開始すればみんな活動時間伸びていいじゃん。っていうアレです。
システム的には、サマータイム中とサマータイム外だと、同じ場所にいるのに時差が変わります

# シドニーの場合
2016/11/19 00:00:00 UTC+11
2017/06/20 00:00:00 UTC+10

# シドニーの場合(UTCで保存)
2016/11/18 13:00:00 UTC+0
2017/06/20 14:00:00 UTC+0

"Australia/Sydney"のサマータイム中に登録したデータのサマータイム外での挙動をXCTestで書く

NSDateFormatterのtimeZoneを設定することで、サマータイムを発生させます。


class TimezoneTests: XCTestCase {
    override func setUp() {
        super.setUp()
    }

    override func tearDown() {
        super.tearDown()
    }
    
    func testTimezoneChange {
        let formatter = NSDateFormatter()
        formatter.timeZone = NSTimeZone.init(name: "Australia/Sydney")
        formatter.calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)
        formatter.dateFormat = "yyyy/MM/dd"
        
        let registerDate = formatter.dateFromString("2016/11/19")
        
        /*
         *   ここにregisterDateをDBに保存するコードを記載
         */ 
         
        let targetDate = formatter.dateFromString("2017/06/20")
        timeTravel(to: targetDate) {
            print(registerDate) //=> 2016-11-18 13:00:00 +0000
            print(targetDate)   //=> 2017-06-19 14:00:00 +0000
            
            /* 
             *   ここにタイムゾーンが変わったとき、どうあるべきかを記載
             */
             
        }
    }
    
    private func timeTravel(to date: NSDate, block: () -> Void) {
        let customDateBlock: @convention(block) (AnyObject) -> NSDate = { _ in date }
        let implementation = imp_implementationWithBlock(unsafeBitCast(customDateBlock, AnyObject.self))
        let method = class_getInstanceMethod(NSClassFromString("__NSPlaceholderDate"), #selector(NSObject.init))
        let oldImplementation = method_getImplementation(method)
        method_setImplementation(method, implementation)
        block()
        method_setImplementation(method, oldImplementation)
    }
}
6
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?