中年プログラマーの息抜き

ブログをはじめました。気の向くままにプログラム関連ネタをメモしていきます。

swift4 DateFormatter->string 日時と文字列の相互変換で9時間ずれる ので ずれないようにする

はじめに

今回はswiftを使った日付操作で気がついたことのメモ。swiftではDate、Locale、TimeZone、DateFormatter、など考慮したその一例です、ある日時に対して、DateFormatterを利用した「Date<-->String」の相互変換をswiftで書いてみます。

TimeZoneを意識せず実装してみる

DateとStringが異る日時

実行日時:2019-01-1 09:00:00
-> 日時:Date()
-> 日時:2019-01-1 00:00:00 (9時間ずれる)
-> Date -->String:e0.string(from: e1)
-> Date -->String:2019-01-1 09:00:00 (正しい日時)
-> String -->Date:e0.date(from: e2)
-> String -->Date:2019-01-1 00:00:00 (9時間ずれる)
let e0 = DateFormatter()
e0.dateFormat = "yyyy-MM-dd HH:mm:ss"
let e1 = Date()
let e2 = e0.string(from: e1)
let e3 = e0.date(from: e2)

TimeZoneを日本時間に固定してみる

実行日時:2019-01-1 09:00:00

DateとStringが同じ日時

-> 日時:Date.current
-> 日時:2019-01-1 09:00:00 (正しい日時)
-> Date -->String:DateFormatter.current("yyyy-MM-dd HH:mm:ss").string(from: d1)
-> Date -->String:2019-01-1 09:00:00 (正しい日時)
-> String -->Date:DateFormatter.current("yyyy-MM-dd HH:mm:ss").date(from: d2)
-> String -->Date:2019-01-1 09:00:00 (正しい日時)
let d1 = Date.current
let d2 = DateFormatter.current("yyyy-MM-dd HH:mm:ss").string(from: d1)
let d3 = DateFormatter.current("yyyy-MM-dd HH:mm:ss").date(from: d2)

extension TimeZone {
    static let gmt = TimeZone(secondsFromGMT: 0)!
    static let jst = TimeZone(identifier: "Asia/Tokyo")!
}

extension Locale {
    static let japan = Locale(identifier: "ja_JP")
}

extension DateFormatter {
    static func current(_ dateFormat: String) -> DateFormatter {
        let df = DateFormatter()
        df.timeZone = TimeZone.gmt
        df.locale = Locale.japan
        df.dateFormat = dateFormat
        return df
    }
}

extension Date {
    static var current: Date = Date(timeIntervalSinceNow: TimeInterval(TimeZone.jst.secondsFromGMT()))
}

まとめ

以前に書いたカレンダーの記事では・・・

ということで??、例えば、0:0:0 や 23:59:59 正しい日時を扱えるように。

【Android】日当-ヒナタ-

週末で審査に出そうと思います・・

ab39

コンピュータ:負数と補数:2の補数を理解する

はじめに

多くのコンピュータでは一般的に負数は2の補数で表現されているようで、その理由の一つには減算を加算として扱えるようになることがあるみたいです。その方が良いみたいです。こういうの・・演算装置(CPU的な)の話かな・・ 今回はこの2の補数表現に注目して整理します。

-> 1の補数:ビット反転
-> 2の補数:1の補数+1

表現できる範囲

先頭ビットで、その値が、正(0)なのか or 負(1)なのかを表現する。(その値の大きさには影響しない)

nビットであれば:-2n-1 ~ 2n-1-1

int型(32ビット)であれば:-231 ~ 231-1:-2,147,483,648 ~ 2,147,483,647

実用例を用いた検証

前の記事で扱った内容を用いて確認してみます

Java実装:カラーコードの定義

    "ピーコック", 0xFF46D6DB
    "ミカン", 0xFFFFB878
    "バナナ", 0xFFFBD75B
    "バジル", 0xFF51B749
    "セージ", 0xFF7AE7BF
    "ブルーベリー", 0xFF5484ED
    "ラベンダー", 0xFFA4BDFC
    "ブドウ", 0xFFDBADFF
    "フラミンゴ", 0xFFFF887C
    "グラファイト", 0xFFE1E1E1

Swift実装:カラーコードの定義

    "ピーコック": -12134693
    "ミカン": -18312
    "バナナ": -272549
    "バジル": -11421879
    "セージ": -8722497
    "ブルーベリー": -11238163
    "ラベンダー": -5980676
    "ブドウ": -2380289
    "フラミンゴ": -30596
    "グラファイト": -1973791
16進数->2進数->1の補数->2の補数->絶対値->10進数
"ピーコック":10進数
16進数:FF46D6DB
2進数:11111111010001101101011011011011
-> 1の補数:00000000101110010010100100100100
-> 2の補数:00000000101110010010100100100101
-> 絶対値:12134693
-> 10進数:-12134693

 

"ミカン":10進数
16進数:FFFFB878
2進数:11111111111111111011100001111000
-> 1の補数:00000000000000000100011110000111
-> 2の補数:00000000000000000100011110001000
-> 絶対値:18312
-> 10進数:-18312

 

"バナナ":10進数
16進数:FFFBD75B
2進数:11111111111110111101011101011011
-> 1の補数:00000000000001000010100010100100
-> 2の補数:00000000000001000010100010100101
-> 絶対値:272549
-> 10進数:-272549
マスク表現でRBGを確認
extension UIColor {
    static func create(hex: Int) -> UIColor {
        return UIColor(
            displayP3Red: CGFloat((hex & 0xFF0000) >> 16) / 255.0
            , green: CGFloat((hex & 0xFF00) >> 8) / 255.0
            , blue: CGFloat(hex & 0xFF) / 255.0
            , alpha: 1.0
        )
    }
}
"ピーコック":(FF46D6DB )ARGB値
R値(赤):hex & 0xFF0000
-> 16進数:FF46D6DB (hex)
-> マスク:00FF0000 (0xFF0000)
-> 演算値:00460000 (FF46D6DB & 00FF0000)
-> シフト:0x46 (00460000>>16)
-> 10進数:70
G値(緑):hex & 0xFF00
-> 16進数:FF46D6DB (hex)
-> マスク:0000FF00 (0xFF00)
-> 演算値:0000D600 (FF46D6DB & 0000FF00)
-> シフト:0xD6 (0000D600 >>8)
-> 10進数:214
G値(青):hex & 0xFF
-> 16進数:FF46D6DB (hex)
-> マスク:000000FF (0xFF)
-> 演算値:000000DB (FF46D6DB & 000000FF)
-> シフト:0xDB (000000DB >>0)
-> 10進数:219

まとめ

Java実装とSwift実装で同じ定義という検証をしました。上の定義も計算違いなどで軽微な間違いがあるかもしれません、もしそうでも、ここではそれは置いておくとして(-_-;)、個人見解「根拠説明できる実装」が大切、基本だし・・まあ理想かなと・・。

日当-ヒナタ- swift4 -7- UIColorをIntで扱う

はじめに

Androidアプリ日当-ヒナタ-のiOS版を作り始めたのでその経過を少しアップします。普段の仕事ではSWIFTを触らないのでとても新鮮な感じと少し不安なとこもあり。。。少し機能を削り、早めのストア公開を目指します。 picker系のコントロールが少し手こずります。Androidでは0xFFFFFFFFのような感じでARGBを指定しました。iOSというかSWIFTではエラーになるので、とりあえず負数を直接定義したのですが、他に方法がないのでしょうかね。。(符号あり(先頭ビット[1]でマイナス)+16進記述の整数リテラル

機材

Macbook air Xcode Version 10.1 Apple Swift version 4.2.1
・iphone5c テスト機

UIColorをIntで扱う。

保存する時は選択した色の数字をRealmへ保存してます。コンピュータ的には良いですが、コメントで16進書いとかないとわからなくなりますね ・・ あ、、それと、透明度が扱えないかも。。

    ---
    ---
    ---
    ---
    let list: DictionaryLiteral = [
        "ピーコック": -12134693,
        "ミカン": -18312,
        "バナナ": -272549,
        "バジル": -11421879,
        "セージ": -8722497,
        "ブルーベリー": -11238163,
        "ラベンダー": -5980676,
        "ブドウ": -2380289,
        "フラミンゴ": -30596,
        "グラファイト": -1973791
    ]
    //使い方
    UIColor.create(hex: -11421879)
    UIColor.create(hex: list[3].value)
    ---
    ---
    ---
    ---
    ---
extension UIColor {
    static func create(hex: Int) -> UIColor {
        return UIColor(
            displayP3Red: CGFloat((hex & 0xFF0000) >> 16) / 255.0
            , green: CGFloat((hex & 0xFF00) >> 8) / 255.0
            , blue: CGFloat(hex & 0xFF) / 255.0
            , alpha: 1.0
        )
    }
}
    ---
    ---
    ---
    ---

参考:Androidの定義。

    "ピーコック", 0xFF46D6DB
    "ミカン", 0xFFFFB878)
    "バナナ", 0xFFFBD75B
    "バジル", 0xFF51B749
    "セージ", 0xFF7AE7BF
    "ブルーベリー", 0xFF5484ED
    "ラベンダー", 0xFFA4BDFC
    "ブドウ", 0xFFDBADFF
    "フラミンゴ", 0xFFFF887C
    "グラファイト", 0xFFE1E1E1

動作イメージ

f:id:tm-b:20190204042539p:plain

【Android】日当-ヒナタ-

ほぼほぼ、完成。。

なんとかリリースまで・・がんばりたい

ab39