Date를 UTC 와 KST로 출력하기 - swift

|

UTC 와 KST로 출력하기 - swift

중요한 사실

NSDate 또는 Date 객체는 타임존 정보를 포함하지 않고 모두 UTC기준입니다. 따라서 해당 지역의 시각으로 표현하기 위해서는 DateFormatter를 사용해야 합니다.

Apple 개발자 사이트에서 명확한 내용을 아직 찾지 못해 SO에 있는 내용을 잠시나마 발췌합니다.

ref: https://stackoverflow.com/questions/1268509/ios-convert-utc-nsdate-to-local-timezone

I disagree. NSDate does NOT have a timezone. To specify the timezone for the NSDate, you use an NSCalendar object or an NSDateFormatter object. If you create an NSDate from a string that has no timezone specified, then the NSDate will assume that the string is in GMT time. – Rickster Dec 3 ‘13 at

다음은 Date객체를 현재 timeZone에 맞게 출력하기 위해 String으로 변환하는 extension 함수입니다.

6336862B-6460-44C2-ADCA-12FEBF43C687

코드:

extension Date {
    
    func toString( dateFormat format: String ) -> String {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = format
        dateFormatter.timeZone = TimeZone.autoupdatingCurrent
        dateFormatter.locale = Locale.current
        return dateFormatter.string(from: self)
    }
    
    func toStringKST( dateFormat format: String ) -> String {
        return self.toString(dateFormat: format)
    }
    
    func toStringUTC( dateFormat format: String ) -> String {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = format
        dateFormatter.timeZone = TimeZone(abbreviation: "UTC") 
        return dateFormatter.string(from: self)
    }
}
 

추가로 lldb를 통해 아래 정보도 확인이 가능합니다.

(lldb) po dateFormatter.locale
 Optional<Locale>
   some : en_KR (current)
    - identifier : "en_KR"
    - kind : "current"

UserDefaults에 Array를 저장하는 방법, 어제오늘 구하기.

|

UserDefaults에 Array를 저장하는 방법, 어제 오늘 구하기

Save Date Array

let array = [Date(), Date(), Date(), Date()]

let defaults = UserDefaults.standard
defaults.set(array, forKey: "SavedDateArray")

Retrieve array

let defaults = UserDefaults.standard
let array = defaults.array(forKey: "SavedDateArray")  as? [Date] ?? [Date]()

어제 오늘 그제 구하기

let today = Calendar.current.startOfDay(for: Date())
let yesterday =  Calendar.current.date(byAdding: .day, value: -1, to: today)!
let thedbyesterday = Calendar.current.date(byAdding: .day, value: -2, to: today)!

모델 필터링하기 - 어제 오늘 그제중 하나라면 모델 데이터에서 제거하기

가정 uploadModel에 startTime, endTime 이라는 Date? 속성이 있다고 가정.

let today = Calendar.current.startOfDay(for: Date())
let yesterday =  Calendar.current.date(byAdding: .day, value: -1, to: today)!
let thedbyesterday = Calendar.current.date(byAdding: .day, value: -2, to: today)!
let datesAsCandiates = [today, yesterday, thedbyesterday ]// read from userDefaults.

uploadViewModel.readings = uploadViewModel.readings?.filter({ ( uploadModel) -> Bool in

    if let startDate = uploadModel.startTime, let endTime = uploadModel.endTime {

        var result: Bool = true
        verifyingDateLabel: for aTime in datesAsCandiates {
            if aTime.isInclusiveBetween(from: startDate, until: endTime) {
                result = false
                break verifyingDateLabel
            }
        }     // 사이의 날짜가 맞으면 false 를 리턴하게 끔 함.
      		  // true가 되면 필터링에서 걸러지지 않으므로 
        return result  
	}

	return true
})

왜 Alpha속성만 Animatable 인가?

|

Why

왜 Alpha속성만 Animatable 인가? Constraint는 왜 애니메이션이 자동으로 안되고 꼭 애니메이션 클로져(블럭)속에 layoutIfNeeded 를 추가해야 하는가?

먼저 UIView 클래스의 Animatable properties를 봅시다:

  • frame
  • bounds
  • center
  • transform
  • alpha
  • backgroundColor
  • contentStretch

결론부터 말하자면, Constraint의 경우에는 Auto Layout의 Constraint의 변경된 값이 실제로 View에 반영되려면 일련의 거치게 되는데, 이 때문에 layoutIfNeeded와 같은 처리가 필요하다고 합니다.

우선 발췌한 내용만 먼저 보자면 다음과 같습니다.

1 변경될 값에 맞추어 시스템이 해당 Constraint를 포함하여 이와 연관되어 있는 Constrainte들의 모든 값을 재계산합니다. 2 layout 엔진이 재계산된 Constraint에 맞추어 연관되어 있는 모든 View들의 frame들의 값을 재계산하고 배치합니다. 3 재계산되고 재배치된 frame을 실제 화면에 그립니다.

좀 더 상세히 보기 위해서 예시를…

다음 시간에 update하겠습니다.ㅜㅜ.

ref: http://baked-corn.tistory.com/107 http://tech.gc.com/demystifying-ios-layout/

go2Shell 환경설정

|

go2Shell 환경설정

iTerm 과 go2Shell을 함께 사용하고 있는데 go2Shell 환경설정을 다시하고 싶다면 다음처럼 합니다

open -a Go2Shell --args config

Pretty print JSON issue

|

Problem:

let myPrerryJson = prettyPrintResponse(from: httpResp.allHeaderFields)
print(myPrerryJson)

I wanted to pretty print json response as follows.

======================== Header ========================
{
  "Connection" : "keep-alive",
  "Access-Control-Allow-Origin" : "*",
  "Date" : "Mon, 12 Nov 2018 07:36:25 GMT",
  "Access-Control-Allow-Credentials" : "true",
  "Content-Type" : "application\/json; charset=utf-8",
  "Acc

However for some reason the result printed so ugly as below:

======================== Header ========================
Optional("{\n  \"Date\" : \"Mon, 12 Nov 2018 08:09:58 GMT\",\n  \"Access-Control-Allow-Origin\" : \"*\",\n  \"Content-Type\" : \"application\\/json; charset=utf-8\",\n  \"Access-Control-Allow-Methods\" : \"GET, POST\",\n  \"Server\" : \"openresty\",\n  \"Access-Control-Allow-Credentials\" : \"true\",\n  \"Content-Length\" : \"40\",\n  \"Connection\" : \"keep-alive\",\n  \"X-Cache-Key\" : \"\\/data\\/2.5\\/weather?APPID=2a6e5a8a3e3d92e541d0323dc3459961&q=seo%20ul\"\n}")

As you can see. The result is composed of just one line of long string.

Solution:

My Bad!!!

carriage return character aka ` \n ` is ignored because printing Optional means just printing optional value itself, so you need unwrap optional value like this:

if let myPrerryJson = prettyPrintResponse(from: httpResp.allHeaderFields){
    print(myPrerryJson)
}

Finally I can see pretty printed result:

======================== Header ========================
{
  "Connection" : "keep-alive",
  "Access-Control-Allow-Origin" : "*",
  "Date" : "Mon, 12 Nov 2018 07:36:25 GMT",
  "Access-Control-Allow-Credentials" : "true",
  "Content-Type" : "application\/json; charset=utf-8",
  "Access-Control-Allow-Methods" : "GET, POST",
  "X-Cache-Key" : "\/data\/2.5\/weather?APPID=sxdd9961&q=sxt%20l",
  "Server" : "openresty",
  "Content-Length" : "40"
}