【问题标题】:Swift - Get last 7 days starting from today in arraySwift - 从数组中获取从今天开始的最后 7 天
【发布时间】:2014-11-18 14:10:08
【问题描述】:

如何获取该月的前 7 天如果今天是 18,我知道如何获取,但是如果今天是 11 月 3 日呢?如何在 Int 中获取上个月(10 月)的最后 4 天?

【问题讨论】:

  • Int 是什么意思? Unix时间戳还是……?
  • [27,28,29,30,1,2,3] 或 [28,29,30,31,1,2,3] 取决于月份

标签: ios arrays swift days


【解决方案1】:

使用NSCalendarNSDateComponents

let cal = NSCalendar.currentCalendar()
// start with today
var date = cal.startOfDayForDate(NSDate())

var days = [Int]()

for i in 1 ... 7 {
    // get day component:
    let day = cal.component(.DayCalendarUnit, fromDate: date)
    days.append(day)

    // move back in time by one day:
    date = cal.dateByAddingUnit(.DayCalendarUnit, value: -1, toDate: date, options: nil)!
}

println(days)

Swift 2.2 (Xcode 7.3.1) 更新:

let cal = NSCalendar.currentCalendar()
var date = cal.startOfDayForDate(NSDate())
var days = [Int]()
for i in 1 ... 7 {
    let day = cal.component(.Day, fromDate: date)
    days.append(day)
    date = cal.dateByAddingUnit(.Day, value: -1, toDate: date, options: [])!
}
print(days)

Swift 3(Xcode 8 beta 2)更新:

let cal = Calendar.current
var date = cal.startOfDay(for: Date())
var days = [Int]()
for i in 1 ... 7 {
    let day = cal.component(.day, from: date)
    days.append(day)
    date = cal.date(byAdding: .day, value: -1, to: date)!
}
print(days)

【讨论】:

  • 闰秒我们需要.startOfDayForDate()吗?
  • @rintaro:在处理日期时,我更喜欢定义明确的时间组件。但这并不是真正需要的。 Unix 时间不考虑闰秒,因此没有任何作用。
  • @MartinR 将不胜感激如果你回答我的问题stackoverflow.com/questions/45238994/…
  • @MartinR:像[Dec 26, Dec 27]这种格式的日子有什么办法实现?
  • @iPeter:使用 DateFormatter 将日期转换为字符串。您将在下面的其他答案中找到示例,例如stackoverflow.com/a/47375155/1187415.
【解决方案2】:

灵感来自this 答案,

以字符串数组的形式获取前 N 天的列表。

extension Date {
    static func getDates(forLastNDays nDays: Int) -> [String] {
        let cal = NSCalendar.current
        // start with today
        var date = cal.startOfDay(for: Date())

        var arrDates = [String]()

        for _ in 1 ... nDays {
            // move back in time by one day:
            date = cal.date(byAdding: Calendar.Component.day, value: -1, to: date)!

            let dateFormatter = DateFormatter()
            dateFormatter.dateFormat = "yyyy-MM-dd"
            let dateString = dateFormatter.string(from: date)
            arrDates.append(dateString)
        }
        print(arrDates)
        return arrDates
    }
}

用法:

let last7Days = Date.getDates(forLastNDays: 7)
debugPrint(last7Days)

//Today(2017-11-19) it prints: ["2017-11-18", "2017-11-17", "2017-11-16", "2017-11-15", "2017-11-14", "2017-11-13", "2017-11-12"]

【讨论】:

    【解决方案3】:

    您可以使用日历创建扩展程序来帮助您进行日历计算:

    Swift 3 或更高版本

    extension Date {
        var day: Int {
            return Calendar.current.component(.day, from: self)
        }
        func adding(days: Int) -> Date {
            return Calendar.current.date(byAdding: .day, value: days, to: self)!
        }
        var last7days: [Int] {
            return (1...7).map { 
                adding(days: -$0).day
            }
        }
        func near(days: Int) -> [Int] {
            return days == 0 ? [day] : (1...abs(days)).map {
                adding(days: $0 * (days < 0 ? -1 : 1) ).day
            }
        }
    }
    

    用法:

    let last7Days  = Date().last7days   // [29, 28, 27, 26, 25, 24, 23]
    let last7Days2 = Date().near(days: -7) // [29, 28, 27, 26, 25, 24, 23]
    let next7Days  = Date().near(days: 7) // [27, 28, 29, 30, 31, 1, 2]
    

    与@rintaro 答案相同的策略,尽可能短;)(增加了对负值的支持,并将其作为日期扩展,以便能够使用任何日期作为输入)

    extension Date {
        func closest(days: Int) -> [Int] {
            return days == 0 ? [] : (1...abs(days)).map { delta -> Int in Calendar.current.component(.day, from: Calendar.current.date(byAdding: .day, value: delta * (days >= 0 ? 1 : -1), to: self)!) }
        }
    }
    

    用法:

    let next7Days2 = Date().closest(days: 7) // [27, 28, 29, 30, 31, 1, 2]
    let last7Days3 = Date().closest(days: -7) // [25, 24, 23, 22, 21, 20, 19]
    let next2Days = Date().closest(days: 2) // [27, 28]
    let last2Days = Date().closest(days: -2) // [25, 24]
    

    【讨论】:

      【解决方案4】:

      与@MartinR 答案相同的策略,尽可能短:

      let cal = NSCalendar.currentCalendar()
      let date = NSDate()
      
      var result = map(-6...0) { delta -> Int in
          cal.component(.DayCalendarUnit, fromDate: cal.dateByAddingUnit(.DayCalendarUnit, value: delta, toDate: date, options: nil)!)
      }
      

      【讨论】:

      • 不错。我喜欢你使用 map() 的方式
      【解决方案5】:

      这可能不是最快的代码。但是你明白了:)

      import Foundation
      
      let lastSevenDay: [Int] = {
          var days = [Int]()
          let secondsInADay: NSTimeInterval = 24 * 60 * 60
          let now = NSDate()
          let calendar = NSCalendar(calendarIdentifier: NSGregorianCalendar)!
          for i in 1...7 {
              let theDate = now.dateByAddingTimeInterval(-secondsInADay * NSTimeInterval(7 - i))
              let dateComponent = calendar.components(NSCalendarUnit.CalendarUnitDay, fromDate: theDate)
              let dayOfMonth = dateComponent.day
              days.append(dayOfMonth)
          }
          return days
      }()
      

      【讨论】:

      • 不是每一天都有 86400 秒(想想夏令时的转换)。使用 60*60*24 作为一天的时长是错误的。
      • 是的。谢谢你指出这一点。我们这里没有夏令时,所以我没有考虑。我投票赞成您的解决方案,因为它正确且更简洁:)
      【解决方案6】:

      我稍微修改了 rintaro 的答案,以便在 NSDictionaries 的 NSArray 中获取过去的日期,以获取包括过去几天、几个月和几年在内的所有值。你只需要像这样调用这个sn-p

      println(getPastDates(2))
      

      获取包含过去日期的完整列表

      ( { 天 = 30; 月 = 11; 年 = 2014; }, { 天 = 29; 月 = 11; 年 = 2014; } )

      func getPastDates(days: Int) -> NSArray {
      
          var dates = NSMutableArray()
      
          let cal = NSCalendar.currentCalendar()
      
          var today = cal.startOfDayForDate(NSDate())
      
          for i in 1 ... days {
      
              let day = cal.component(.DayCalendarUnit, fromDate: today)
              let month = cal.component(.MonthCalendarUnit, fromDate: today)
              let year = cal.component(.YearCalendarUnit, fromDate: today)
      
              var date = NSMutableDictionary()
      
              date.setValue(day, forKey: "day")
              date.setValue(month, forKey: "month")
              date.setValue(year, forKey: "year")
      
              dates.addObject(date)
      
              // move back in time by one day:
              today = cal.dateByAddingUnit(.DayCalendarUnit, value: -1, toDate: today, options: nil)!
          }
      
          return dates
      
      }
      

      【讨论】:

        【解决方案7】:

        我更新了

        Alejandro Luengo 的代码。它适用于 Swift4

        func getPastDates(days: Int) -> NSMutableArray {
        
                let dates = NSMutableArray()
                let calendar = Calendar.current
        
                var today = calendar.startOfDay(for: Date())
        
                for _ in 1 ... days {
        
                    let day = calendar.component(.day, from: today)
                    let month = calendar.component(.month, from: today)
                    let year = calendar.component(.year, from: today)
        
                    let date = NSMutableDictionary()
        
                    date.setValue(day, forKey: "day")
                    date.setValue(month, forKey: "month")
                    date.setValue(year, forKey: "year")
        
                    dates.add(date)
                    today = calendar.date(byAdding: .day, value: -1, to: today)!
                }
        
                return dates
        
            }
        

        【讨论】:

        • 感谢您。 :D
        【解决方案8】:

        Swift4

        与@MartinR,@rintaro 回答相同的策略,尽可能短:

            let calendar = Calendar.current
            let date = Date()
        
            let result: [Int] = (-6...0).map { delta -> Int in
                calendar.component(.day, from: calendar.date(byAdding: .day, value: delta, to: date)!)
            }
        

        【讨论】:

          【解决方案9】:

          您想使用NSCalendar 获取最近 7 天。这是一个代码 sn-p,用于在 11 月 3 日演示它:

          let dateFormatter = NSDateFormatter()
          dateFormatter.dateStyle = .ShortStyle
          dateFormatter.timeStyle = .NoStyle
          dateFormatter.locale = NSLocale(localeIdentifier: "en_GB")
          let date = dateFormatter.dateFromString("03/11/14")!
          println("date = \(dateFormatter.stringFromDate(date))")
          
          let calendar = NSCalendar(calendarIdentifier: NSGregorianCalendar)!
          var previous7days: Array<Int> = []
          for i in 0...6 {
              let prevDate = calendar.dateByAddingUnit(.CalendarUnitDay, value: -i, toDate: date, options:  nil)
              previous7days.insert(calendar.component(.CalendarUnitDay, fromDate: prevDate!), atIndex: 0)
          }
          println("last 7 days: \(previous7days)")
          

          【讨论】:

          • 不是每一天都有 86400 秒(想想夏令时的转换)。使用 60*60*24 作为一天的时长是错误的。
          • 是的,这就是为什么你的答案更好;)
          猜你喜欢
          • 1970-01-01
          • 2022-12-03
          • 1970-01-01
          • 1970-01-01
          • 2021-10-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多