ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • DateFormatter가 쓰기싫어서 DateFormatStyle을 알아본다
    iOS/Swift 2022. 6. 28. 00:17

    yyyy-MM-dd hh:mm:ss

    DateFormatter가 쓰기싫었다.

    더 쉬운 방법이 없을까? 싶어서 찾아봤습니다....

    일단 어떻게 나오는지 궁금한 샐옴?

    print문은 아래의 순서입니다.

    어떤 날짜style로 표기했는지

    날짜 style + timeStyle: .standard

    날짜 style + timeStyle: .omiited

    날짜 style + timeStyle: .shortened

    날짜 style + timeStyle: .complete

     

    더보기

    omitted 

    오후 9:34:42

    6/27/2022 오후 9:34

    오후 9:34

    오후 9:34:42 GMT+9

     

    comple

    2022년 6월 27일 월요일 오후 9:34:42

    2022년 6월 27일 월요일

    2022년 6월 27일 월요일 오후 9:34

    2022년 6월 27일 월요일 오후 9:34:42 GMT+9

     

    nume

    6/27/2022 오후 9:34:42

    6/27/2022

    6/27/2022 오후 9:34

    6/27/2022 오후 9:34:42 GMT+9

     

    long

    2022년 6월 27일 오후 9:34:42

    2022년 6월 27일

    2022년 6월 27일 오후 9:34

    2022년 6월 27일 오후 9:34:42 GMT+9

     

    abbre

    2022년 6월 27일 오후 9:34:42

    2022년 6월 27일

    2022년 6월 27일 오후 9:34

    2022년 6월 27일 오후 9:34:42 GMT+9

    그럼 규칙도 궁금한 샐옴?

    DateStyle omitted complete numeric long abbreviated
      (생략) yyyy년 mm월 dd일 + 요일 MM/dd/yyyy yyyy년 mm월 dd일 yyyy년 mm월 dd일

    ...long과 abbreviated의 내용이 같아보이죠?

    네맞아요

    원인은 저희가 한국어 사용자임에 있습니다.

    영문으로는 long 일때 January, abbreviated일때 Jan. 으로 표기됩니다.

    complete일 때는, long + 요일입니다.

    numeric은... 찡긋 >_ㅇ

     

    TimeStyle standard omitted shortened complete
      오후 9:34:42 (생략) 오후 9:34 오후 9:34:42 GMT+9

    시간은 표만 봐도 알겠네요! 

     

    근데,, 프리셋은 이제 알겠는데, 커스텀은 안되나요? 저는 시간이 24시간으로 나오면 좋겠는데?

    커스텀이 있긴합니다!

            let localeArr = ["en_GB", "ko_KR"]
            
            for locale in localeArr {
                
                let str = Date.now.formatted(
                    Date.FormatStyle()
                        .year(.defaultDigits)
                        .month(.twoDigits)
                        .day(.defaultDigits)
                        .hour(.twoDigits(amPM: .abbreviated))
                        .minute(.twoDigits)
                        .second(.twoDigits)
                        .locale(Locale(identifier: locale))
                
                )
                
                print(str)
            }
            
            
    //28/06/2022, 00:13:31
    //2022. 06. 28. 오전 12:13:31

    근데,,, 저 오전을 없애고 싶었거든요 ^^,,, 이게 되긴 하는데, 안됩니다.

    왜냐하면 저 녀석은 locale에 따라서 나와요....... locale에 따라서 정해지는 녀석이라 어쩔수가 없어요,,,,

    2022. 06. 28. 00:13:31 을 꿈꿨건만................... DateFormatter로 돌아가십시오.

    아래부터는 공식문서의 번역입니다~

    원본 링크

    주의, 의역이 매우 많습니다. 왜냐하면 혼자 공부하면서 해석한 것이기 때문입니당,,,,,,

    Date.FormatStyle

    date 객체를 locale에 적합하게 String으로 만들거나, dates와 times의 문자열들을 date객체로 바꿔주는 구조체
     

    요구되는 OS version

    • iOS 15.0+ 
    • macOS 12.0+ 
    • Mac Catalyst 15.0+ 
    • tvOS 15.0+ 
    • watchOS 8.0+ 
    • Xcode 13.0+ 

    Technology

    • Foundation
     

    Declaration

    struct FormatStyle

    Overview

    date format style은 날짜와 시간 format을 가져요, format은 사용자의 locale에 영향을 받습니다.

    당신이 특별한 format style을 어떤 Date 객체에 적용하길 원할 때, Date.ForamtStyle을 쓰세요! 아래에 예제가 있슴다

    Formatting String Representations of Dates and Times

    Date.FormatStyle은 다양한 localized된 프리셋을 제공합니다.  또한, Date 객체의 날짜들과 시간의 표기를 유저가 원하는 대로 만들기 위한 설정 옵션들도요!

    날짜를 user에게 보여줄 때, use the formatted(date:time:) instance method를 사용해보세요! 당신의 툭별한 의도에 따라, 날짜와 시간 format style을 개별적으로 설정해보세요!

     

    예를 들어, 날짜를 상세히 표기하고, 시간정보가 필요없다고요? Date.FormatStyle.DateStyle을 .complete, Date.FormatStyle.TimeStyle을 .omitted로 설정하세요!

    반대로 현재 timezone과 locale에서  날짜가 불필요하고, 시간만 얻고 싶다고요?

     date style을 .omitted 그리고, time style을 .complete로 설정하세요!

    print(Date.now.formatted(date: .omitted, time: .complete))
    //오후 9:34:42 GMT+9
    print(Date.now.formatted(date: .complete, time: .omitted))
    //2022년 6월 27일 월요일

    보여지는 결과는 한국에 맞춰져 있습니당

     

    당신은 간결한 날짜와 시간 preset을 사용하여 다양한 수준의 Date 객체의 문자열 표기를 만들 수 있습니다!

    번역체가 어렵죠? date, time에 적당한 style을 선택하여 편리하게 String을 만들 수 있다고요!

     

    아래의 예시는 여러 스타일의 예시를 보여줍니다.

    print(Date.now.formatted(date: .long, time: .shortened))
    //2022년 6월 27일 오후 9:34
    print(Date.now.formatted(date: .abbreviated, time: .standard))
    //2022년 6월 27일 오후 9:34:42
    print(Date.now.formatted(date: .numeric, time: .complete))
    //6/27/2022 오후 9:34:42 GMT+9
    print(Date.now.formatted())
    //2022년 6월 27일 오후 9:34

    날짜 default는 abbreviated, 시간 default는 shortened 에요!

     

    전체 커스터마이징을 위해서, Date.formatted(_:) Instance method를 사용하고, DateFormatStyle 객체를 제공하세요!

     

    당신은 더 많은 날짜와 시간요소들, 그리고 그들의 표현에 대해서 여러 편리한 modifier들을 당신의 formatStyle에 적용함으로써, 더 많은 커스터마이징을 적용 할 수 있어요

    아래의 예시는 여러 modifier를 format style에 적용하여, 정밀하게 년 월 일 시 분 timezone을 정의하여 결과 문자열에 보여줘요!

    date, time modifier의 순서는 결과와 무관해요!

    // Call the .formatted method on an instance of Date passing in an instance of Date.FormatStyle.
    let birthday = Date()
    birthday.formatted(Date.FormatStyle()
                    		.year(.defaultDigits)
                                .month(.abbreviated)
                                .day(.twoDigits)
                                .hour(.defaultDigits(amPM: .abbreviated))
                                .minute(.twoDigits)
                                .timeZone(.identifier(.long))
                                .era(.wide)
                                .dayOfYear(.defaultDigits)
                                .weekday(.abbreviated)
                                .week(.defaultDigits)) 
                                
    // Sun, Jan 17, 2021 Anno Domini (week: 4), 11:18 AM America/Chicago

     

    진행중, 사실 원하는게 안된다는 걸 알고 의욕이 떨어졌슴미다..

    Date.FormatStyle provides a convenient factory variable, dateTime, used to shorten the syntax when applying date and time modifiers to customize the format, as in the following example:

    let localeArray = ["en_US", "sv_SE", "en_GB", "th_TH", "fr_BE"]
    for localeID in localeArray {    
    print(meetingDate.formatted(.dateTime
    	.day(.twoDigits)
        .month(.wide)
        .weekday(.short)
        .hour(.conversationalTwoDigits(amPM: .wide))
        .locale(Locale(identifier: localeID))))}
    // Th, November 12, 7 PM
    // to 12 november 19
    // Th 12 November, 19
    // พฤ. 12 พฤศจิกายน 19
    // je 12 novembre, 19 h

    Parsing Dates and Times

    To parse a Date instance from an input string, use a date parse strategy. For example:

    let inputString = "Archive for month 8, archived on day 23 - complete."let strategy = Date.ParseStrategy(format: "Archive for month \(month: .defaultDigits), archived on day \(day: .twoDigits) - complete.", locale: Locale(identifier: "en_US"), timeZone: TimeZone(abbreviation: "CDT")!)if let date = try? Date(inputString, strategy: strategy) {   print(date.formatted()) // "Aug 23, 2000 at 12:00 AM"}

    The time defaults to midnight local time unless explicitly defined.

    The parse instance method attempts to parse a provided string into an instance of date using the source date format style. The function throws an error if it can’t parse the input string into a date instance.

    You can use Date.FormatStyle for round-trip formatting and parsing in a locale-aware manner. This date format style guides parsing the date instance from an input string, as the following code demonstrates:

    let birthdayFormatStyle = Date.FormatStyle()    .year(.defaultDigits)    .month(.abbreviated)    .day(.twoDigits)    .hour(.defaultDigits(amPM: .abbreviated))    .minute(.twoDigits)    .timeZone(.identifier(.long))    .era(.abbreviated)    .weekday(.abbreviated)
    let yourBirthdayString = "Mon, Feb 17, 1997 AD, 1:27 AM America/Chicago"
    // Create a date instance from a string representation of a date.let yourBirthday = try? birthdayFormatStyle.parse(yourBirthdayString)// Feb 17, 1997 at 1:27 AM
    

    The following round-trip date formatting example uses a date format style to create a locale-aware string representation of a date instance. Then, the date format style guides parsing the newly created string into a new date instance.

    let myFormat = Date.FormatStyle()    .year()    .day()    .month()    .locale(Locale(identifier: "en_US"))    let dateString = Date().formatted(myFormat)// "Feb 17, 2021" for the "en_US" locale
    print(dateString) // Feb 17, 2021
    if let anniversary = try? Date(dateString, strategy: myFormat) {    print(anniversary.formatted(myFormat)) // Feb 17, 2021    print(anniversary.formatted()) // 2/17/2021, 12:00 AM} else {    print("Can't parse string into date with this format.")}

    After this code executes, anniversary contains a Date instance parsed from dateString.

    Applying Format Styles Repeatedly

    Once you create a date format style, you can use it to format dates multiple times.

    You can use a format style to parse a set of date instances from a set of string representations of dates. Then, use another format style, applied repeatedly, to produce more detailed string representations of those dates for a different locale. For example:

    func formatIntroDates() {   let inputFormat = Date.FormatStyle()      .locale(Locale(identifier: "en_GB"))      .year()      .month()      .day()    // Parse string inputs into date instances.    guard let productIntroDate = try? Date("9 Jan 2007", strategy: inputFormat) else { return }    guard let anotherIntroDate = try? Date("27 Jan 2010", strategy: inputFormat) else { return }    guard let conferenceDate = try? Date("7 Jun 2021", strategy: inputFormat) else { return }
        let outputFormat = Date.FormatStyle() // Define format style for string output.        .locale(Locale(identifier: "en_US"))        .year()        .month(.wide)        .day(.twoDigits)        .weekday(.abbreviated)
        // Apply the output format on the three dates below.    print(outputFormat.format(conferenceDate)) // Mon, June 07, 2021    print(outputFormat.format(anotherIntroDate)) // Wed, January 27, 2010    print(outputFormat.format(productIntroDate)) // Tue, January 09, 2007}

     

Designed by Tistory.