2017-03-24 3 views
0

Je voudrais créer une liste de tuple de fois comme ça; toutes les heures allant de 0 à 23.Créer une liste d'intervalles de temps Swift 3

tuple = [(2017-03-24 00:00:00 +0000, 0.0), (2017-03-24 00:01:00 +0000, 0.0), (2017-03-24 00:02:00 +0000, 0.0), (2017-03-24 00:03:00 +0000, 0.0)] 

J'ai essayé d'utiliser ce code qui me donnera les heures et les minutes, mais je ne peux pas à comprendre comment soit ajouter le mois, le jour et l'année. Ou ajustez le format de date dans le Struct.

Nous vous remercions de votre aide. Voici la structure que j'utilise ...

import Foundation 

struct TimeDay { 

let start: TimeInterval 
let end: TimeInterval 
let interval: TimeInterval 

init(start: TimeInterval, interval: TimeInterval, end: TimeInterval) { 
    self.start = start 
    self.interval = interval 
    self.end = end 
} 

init(startHour: TimeInterval, intervalMinutes: TimeInterval, endHour: TimeInterval) { 
    self.start = startHour * 60 * 60 
    self.end = endHour * 60 * 60 
    self.interval = intervalMinutes * 60 
} 

var timeRepresentations: [String] { 
    let dateComponentFormatter = DateComponentsFormatter() 
    dateComponentFormatter.unitsStyle = .positional 
    dateComponentFormatter.allowedUnits = [.minute, .hour] 

    let dateComponent = NSDateComponents() 
    return timeIntervals.map { timeInterval in 
     dateComponent.second = Int(timeInterval) 
     return dateComponentFormatter.string(from: dateComponent as DateComponents)! 
    } 
} 

var timeIntervals: [TimeInterval]{ 
    return Array(stride(from: start, through: end, by: interval)) 
} 
} 

Répondre

1

Un mois peut durer de 28 à 31 jours. Vous ne pouvez pas le convertir en un nombre exact de secondes. Utilisez DateComponents pour stocker votre étape:

struct TimeDay { 
    var startDate: Date 
    var endDate: Date 
    var step: DateComponents 

    var calendar = Calendar.autoupdatingCurrent 
    var dateFormatter: DateFormatter = { 
     let formatter = DateFormatter() 
     formatter.dateFormat = "yyyy-MM-dd HH:mm:ss" 
     return formatter 
    }() 

    init(startDate: Date, endDate: Date, step: DateComponents) { 
     self.startDate = startDate 
     self.endDate = endDate 
     self.step  = step 
    } 

    var timeIntervals : [Date] { 
     guard self.startDate <= self.endDate else { 
      return [] 
     } 

     var result = [self.startDate] 
     var date = self.startDate 
     while date < self.endDate { 
      date = self.calendar.date(byAdding: step, to: date)! 
      result.append(date) 
     } 

     return result 
    } 

    var timeRepresentation : [String] { 
     return self.timeIntervals.map { self.dateFormatter.string(from: $0) } 
    } 
} 

Exemple 1: itérer par heure

let startDate1 = DateComponents(calendar: .current, year: 2017, month: 3, day: 24).date! 
let endDate1 = DateComponents(calendar: .current, year: 2017, month: 3, day: 25).date! 

let t1 = TimeDay(startDate: startDate1, endDate: endDate1, step: DateComponents(hour: 1)) 
print(t1.timeRepresentation) 

Exemple 2: itérer par mois

// Iterate by month 
let startDate2 = DateComponents(calendar: .current, year: 2017, month: 1, day: 1).date! 
let endDate2 = DateComponents(calendar: .current, year: 2017, month: 12, day: 31).date! 

let t2 = TimeDay(startDate: startDate2, endDate: endDate2, step: DateComponents(month: 1)) 
print(t2.timeRepresentation) 

Exa mple 3: vous pouvez également mélanger les unités de temps et itérer par 1 mois et 5 jours:

let t3 = TimeDay(startDate: startDate2, endDate: endDate2, step: DateComponents(month: 1, day: 5)) 
print(t3.timeRepresentation) 

Edit:

Si vous voulez trouver le plus proche heure: (1) avancer à l'heure suivante; (2) reculer jusqu'à la dernière heure; (3) sélectionnez celui qui est le plus proche de la date spécifiée

let date = Date()  
let closestHour = ([.backward, .forward] as [Calendar.SearchDirection]) 
    .flatMap { Calendar.current.nextDate(after: date, matching: DateComponents(minute: 0), matchingPolicy: .nextTime, repeatedTimePolicy: .first, direction: $0) } 
    .min { abs($0.timeIntervalSince(date)) < abs($1.timeIntervalSince(date)) } 
+0

Cela fonctionne parfaitement pour ce que je voulais, et j'ai compris comment utiliser la date actuelle, puis 24 heures en arrière. Maintenant, ce dont j'ai besoin, c'est de passer d'un tableau à un tuple comme [(date: String, amount: Double)] ... De plus, toutes les valeurs dans le tuple vont être 0.0 pour commencer. – Denis

0

Vous voulez dire quelque chose comme ça?

struct TimeDay { 
    let start: TimeInterval 
    let end: TimeInterval 
    let interval:TimeInterval 
    let fmt = DateFormatter() 

    init(start: TimeInterval, interval: TimeInterval, end: TimeInterval) { 
     self.start = start 
     self.interval = interval 
     self.end = end 
    } 

    init(startHour: TimeInterval, intervalMinutes: TimeInterval, endHour: TimeInterval) { 
     self.start = startHour * 60 * 60 
     self.end = endHour * 60 * 60 
     self.interval = intervalMinutes * 60 
    } 

    var timeRepresentations: [String] { 
     fmt.dateFormat = "yyyy-MM-dd HH:mm:ss z" 
     var dateComponent = DateComponents() 
     guard let calendar = NSCalendar(calendarIdentifier: NSCalendar.Identifier.gregorian) else { 
      return [] 
     } 
     dateComponent = calendar.components(in: TimeZone.current, from:Date()) 
     dateComponent.hour = 0 
     dateComponent.minute = 0 
     return timeIntervals.map { timeInterval in 
      dateComponent.second = Int(timeInterval) 
      let dt = calendar.date(from:dateComponent) 
      return fmt.string(from:dt!) 
     } 
    } 

    var timeIntervals: [TimeInterval]{ 
     return Array(stride(from: start, through: end, by: interval)) 
    } 
} 

Vous pourriez avoir besoin de modifier le dateFormat pour le DateFormatter pour obtenir la sortie exacte que vous voulez, mais cela ne devrait travailler surtout la façon dont vous vouliez.