【问题标题】:Using a NumberFormatter within a DateFormatter在 DateFormatter 中使用 NumberFormatter
【发布时间】:2020-10-07 17:25:37
【问题描述】:

我正在尝试将我的Date() 格式化为类似于Saturday, June 12th • 5PM - 12PM。我已经能够通过以下DateFormatter() 解决大部分问题:

var date_formatter: DateFormatter {
    let formatter = DateFormatter()
    formatter.dateFormat = "EEEE, MMMM d • HHa - HHa"
    return formatter
}

导致Saturday, June 12 • 5PM - 12PM

我面临的挑战是了解如何添加序数后缀(即 12 -> 12th)。我在NumberFormatter() 上看过一点,但不完全确定如何整合两者。

编辑:最终不得不为5PM - 12PM 逻辑创建两种格式。

这看起来像:

var start_time_formatter: DateFormatter {
        let formatter = DateFormatter()
        formatter.dateFormat = "EEEE, MMMM d • HHa -"
        return formatter
    }

    var end_time_formatter: DateFormatter {
        let formatter = DateFormatter()
        formatter.dateFormat = "HHa"
        return formatter
    }

使用以下内容将其显示在视图中:

Text("\(self.create_event_vm.start_time, formatter: self.start_time_formatter) \(self.create_event_vm.end_time, formatter: self.end_time_formatter)")

我知道这有点古怪,可以使用一些重构,但我希望得到想要的效果,测试,然后重构。

【问题讨论】:

  • 我怀疑您是否从 one 日期收到 ...5PM - 12PM。您必须从当天计算后缀并动态修改日期格式。
  • 对不起,我在输入这个之后才意识到。我编辑了我的帖子以显示我当前的显示方式5PM - 12PM
  • @Bonteq 您需要的是 DateIntervalFormatter。请注意,下午 12 点已经是另一天了,所以您的表述是错误的

标签: swift swiftui dateformatter


【解决方案1】:

您可以在下面的函数中创建第一个日期后缀

func getDaySuffix(from date: Date) -> String {  
    switch Calendar.current.component(.day, from: date) {
    case 1, 21, 31: return "st"
    case 2, 22: return "nd"
    case 3, 23: return "rd"
    default: return "th"
    }
}

并结合您的代码:

let startDate = Date()
let endDate = Calendar.current.date(byAdding: .hour, value: 5, to: startDate)!

var startTimeFormatter: DateFormatter {
    let formatter = DateFormatter()
    formatter.locale = Locale(identifier: "en_US_POSIX")
    formatter.dateFormat = "EEEE, MMMM d'\(getDaySuffix(from: startDate))' • ha - "
    return formatter
}

var endTimeFormatter: DateFormatter {
    let formatter = DateFormatter()
    formatter.locale = Locale(identifier: "en_US_POSIX")
    formatter.dateFormat = "ha"
    return formatter
}

let startDateResult = startTimeFormatter.string(from: startDate) // "Thursday, June 18th • 2AM - "
let endDateResult = endTimeFormatter.string(from: endDate) // "7AM"
let finalResult = startDateResult + endDateResult // "Thursday, June 18th • 2AM - 7AM"

【讨论】:

    【解决方案2】:

    你走错了路。您需要创建一个 DateInterval 并使用它的 DateIntervalFormatter 将其显示给用户。请注意,下午 12 点已经是另一天了,所以您的日期间隔表示是错误的:

    let dateA = DateComponents(calendar: .current, year: 2020, month: 6, day: 12, hour: 17, minute: 0).date!
    let dateB = DateComponents(calendar: .current, year: 2020, month: 6, day: 13, hour: 0, minute: 0).date!
    let di = DateInterval(start: dateA, end: dateB)
    let dif = DateIntervalFormatter()
    dif.dateTemplate = "EEEEMMMMdh"
    dif.string(from: di)   // "Friday, June 12, 5 PM – Saturday, June 13, 12 AM"
    

    【讨论】:

      【解决方案3】:

      首先是一个有用的扩展Int+Ordinal.swift

      extension Int {
      
          /// `Int` ordinal suffix
          enum Ordinal: String {
      
              /// Suffix for numbers ending in `1` except 11
              case st = "st"
      
              /// Suffix for numbers snding in `2` except 12
              case nd = "nd"
      
              /// Suffix for numbers ending in `3` except 13
              case rd = "rd"
      
              /// Suffix otherwise 
              case th = "th"
          }
      
          /// Get `Ordinal` from `Int` `self`
          var ordinal: Ordinal {
              var mod = self % 100
              if mod == 11 || mod == 12 || mod == 13 {
                  return .th
              } else {
                  mod = mod % 10
                  if mod == 1 {
                      return .st
                  } else if mod == 2 {
                      return .nd
                  } else if mod == 3 {
                      return .rd
                  } else {
                      return .th
                  }
              }
          }
      }
      

      然后使用这个扩展和DateFormatter:

      func string(from startDate: Date, to endDate: Date) -> String {
          let formatter = DateFormatter()
      
          // weekdayMonth
          formatter.dateFormat = "EEEE, MMMM"
          let weekdayMonth = formatter.string(from: startDate)
      
          // day
          formatter.dateFormat = "d"
          var day = formatter.string(from: startDate)
          if let dayValue = Int(day) {
              day += dayValue.ordinal.rawValue
          }
      
          // timeFrom
          formatter.dateFormat = "ha"
          let timeFrom = formatter.string(from: startDate)
      
          // timeTo
          let timeTo = formatter.string(from: endDate)
      
          return "\(weekdayMonth) \(day) • \(timeFrom) - \(timeTo)"
      }
      

      运行它:

      let dateString = string(from: Date(), to: Date().addingTimeInterval(3600 * 4))
      print(dateString) // "Wednesday, June 17th • 11PM - 3AM"
      

      虽然我猜在这个例子中你不希望它运行到第二天! :)

      【讨论】:

        猜你喜欢
        • 2013-02-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多