web-dev-qa-db-fra.com

comment vérifier si le temps est dans une plage spécifique dans swift

Bonjour, je suis en train de vérifier si l’heure actuelle est dans un intervalle de temps, disons 8h00 - 16h30. Mon code ci-dessous montre que je peux obtenir l'heure actuelle sous forme de chaîne, mais je ne sais pas comment utiliser cette valeur pour vérifier si elle se situe dans la plage de temps spécifiée ci-dessus. Toute aide serait grandement appréciée!

var todaysDate:NSDate = NSDate()
var dateFormatter:NSDateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "HH:mm"
var dateInFormat:String = dateFormatter.stringFromDate(todaysDate)
println(dateInFormat) // 23:54
10
redman

Il y a plusieurs manières de faire ça. Personnellement, je n'aime pas travailler avec des chaînes si je peux l'éviter. Je préfère traiter avec les composants de date.

Vous trouverez ci-dessous un code de terrain de jeu qui utilise un objet Calendrier pour obtenir le jour/mois/année de la date actuelle, ajoute les composants heure/minute souhaités, puis génère une date pour ces composants.

Il crée des dates pour 8h00 et 16h30, puis compare les dates pour voir si la date/heure actuelle se situe dans cette plage.

C'est plus long que le code des autres, mais je pense que ça vaut la peine d'apprendre à faire des calculs avec des dates en utilisant un calendrier:

EDIT # 3:

Cette réponse date d'il y a longtemps. Je vais laisser l'ancienne réponse ci-dessous, mais voici la solution actuelle:

La réponse de @CodenameDuchess utilise une fonction système, date(bySettingHour:minute:second:of:matchingPolicy:repeatedTimePolicy:direction:)

En utilisant cette fonction, le code peut être simplifié à ceci:

import UIKit

let calendar = Calendar.current
let now = Date()
let eight_today = calendar.date(
  bySettingHour: 8,
  minute: 0,
  second: 0,
  of: now)!

let four_thirty_today = calendar.date(
  bySettingHour: 16,
  minute: 30,
  second: 0,
  of: now)!

if now >= eight_today &&
  now <= four_thirty_today
{
  print("The time is between 8:00 and 16:30")
}

L'ancienne réponse (Swift 2) suit, par souci de complétude historique:

import UIKit
//-------------------------------------------------------------
//NSDate extensions.
extension NSDate
{
  /**
  This adds a new method dateAt to NSDate.

  It returns a new date at the specified hours and minutes of the receiver

  :param: hours: The hours value
  :param: minutes: The new minutes

  :returns: a new NSDate with the same year/month/day as the receiver, but with the specified hours/minutes values
  */
  func dateAt(#hours: Int, minutes: Int) -> NSDate
  {
    let calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!

    //get the month/day/year componentsfor today's date.

    println("Now = \(self)")

    let date_components = calendar.components(
      NSCalendarUnit.CalendarUnitYear |
        NSCalendarUnit.CalendarUnitMonth |
        NSCalendarUnit.CalendarUnitDay,
      fromDate: self)

    //Create an NSDate for 8:00 AM today.
    date_components.hour = hours
    date_components.minute = minutes
    date_components.second = 0

    let newDate = calendar.dateFromComponents(date_components)!
        return newDate
  }
}
//-------------------------------------------------------------
//Tell the system that NSDates can be compared with ==, >, >=, <, and <= operators
extension NSDate: Equatable {}
extension NSDate: Comparable {}

//-------------------------------------------------------------
//Define the global operators for the 
//Equatable and Comparable protocols for comparing NSDates

public func ==(lhs: NSDate, rhs: NSDate) -> Bool
{
  return lhs.timeIntervalSince1970 == rhs.timeIntervalSince1970
}

public func <(lhs: NSDate, rhs: NSDate) -> Bool
{
  return lhs.timeIntervalSince1970 < rhs.timeIntervalSince1970
}
public func >(lhs: NSDate, rhs: NSDate) -> Bool
{
  return lhs.timeIntervalSince1970 > rhs.timeIntervalSince1970
}
public func <=(lhs: NSDate, rhs: NSDate) -> Bool
{
  return lhs.timeIntervalSince1970 <= rhs.timeIntervalSince1970
}
public func >=(lhs: NSDate, rhs: NSDate) -> Bool
{
  return lhs.timeIntervalSince1970 >= rhs.timeIntervalSince1970
}
//-------------------------------------------------------------

let now = NSDate()
let eight_today = now.dateAt(hours: 8, minutes: 0)
let four_thirty_today = now.dateAt(hours:16, minutes: 30)

if now >= eight_today &&
  now <= four_thirty_today
{
  println("The time is between 8:00 and 16:30")
}

MODIFIER:

Le code dans cette réponse a changé BEAUCOUP pour Swift 3. 

Au lieu d'utiliser NSDate, il est plus logique que nous utilisions l'objet Date natif, et les objets Date sont Equatable et Comparable "prêts à l'emploi".

Ainsi, nous pouvons nous débarrasser des extensions Equatable et Comparable ainsi que des définitions pour les opérateurs <, > et =.

Ensuite, nous devons peaufiner la syntaxe dans la fonction dateAt pour suivre la syntaxe Swift 3. La nouvelle extension ressemble à ceci dans Swift 3:

Swift 3 version:

import Foundation

extension Date
{

  func dateAt(hours: Int, minutes: Int) -> Date
  {
    let calendar = NSCalendar(calendarIdentifier: NSCalendar.Identifier.gregorian)!

    //get the month/day/year componentsfor today's date.


    var date_components = calendar.components(
      [NSCalendar.Unit.year,
       NSCalendar.Unit.month,
       NSCalendar.Unit.day],
      from: self)

    //Create an NSDate for the specified time today.
    date_components.hour = hours
    date_components.minute = minutes
    date_components.second = 0

    let newDate = calendar.date(from: date_components)!
    return newDate
  }
}


let now = Date()
let eight_today = now.dateAt(hours: 8, minutes: 0)
let four_thirty_today = now.dateAt(hours: 16, minutes: 30)

if now >= eight_today &&
  now <= four_thirty_today
{
  print("The time is between 8:00 and 16:30")
}
24
Duncan C

Dans Swift 3.0, vous pouvez utiliser le nouveau type de valeur Date et comparer directement avec ==,>, <etc.

    let now = NSDate()
    let nowDateValue = now as Date
    let todayAtSevenAM = calendar.date(bySettingHour: 7, minute: 0, second: 0, of: nowDateValue, options: [])
    let todayAtTenPM = calendar.date(bySettingHour: 22, minute: 0, second: 0, of: nowDateValue, options: [])

    if nowDateValue >= todayAtSevenAM! &&
        nowDateValue <= todayAtTenPM!
    {
        // date is in range

    }

Très pratique en effet.

13
CodenameDuchess

Swift 3

Il s'agit d'une fonction qui renvoie une chaîne en comparant si l'heure actuelle est comprise dans une plage d'heures données. Exécutez-le dans un terrain de jeu et adaptez-le à vos propres besoins. 

func updateGreeting() -> String {

var greeting = String()

//date formatter
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "h:mm a"

// Get current time and format it to compare
var currentTime = Date()
let currentTimeStr = dateFormatter.string(from: currentTime)
currentTime = dateFormatter.date(from: currentTimeStr)!

//Times array
let startTimes = ["5:00 AM", //Morning
    "11:00 AM", //Aftenoon
    "5:00 PM", //Evening
    "9:00 PM" //Nigth
]

let morning = 0
let afternoon = 1
let evening = 2
let night = 3

var dateTimes = [Date]()

//create an array with the desired times
for i in 0..<startTimes.count{
    let dateTime = dateFormatter.date(from: startTimes[i])
    print(dateTime!)
    dateTimes.append(dateTime!)
}

if currentTime >= dateTimes[morning] && currentTime < dateTimes[afternoon]   {
    greeting = "Good Morning!"
}
if currentTime >= dateTimes[afternoon] && currentTime < dateTimes[evening]   {
    greeting = "Good Afternoon!"
}
if currentTime >= dateTimes[evening] && currentTime <= dateTimes[night]   {
    greeting = "Good Evening"
}
if currentTime >= dateTimes[night] && currentTime < dateTimes[morning]   {
    greeting = "Good Night"
}

return greeting

}

5
Juan Felipe Gallo

Vous pouvez rendre NSDate conforme au protocole Comparable pour pouvoir utiliser les opérateurs ==, !=, <=, >=, > et <. Par exemple:

extension NSDate : Comparable {}

//  To conform to Comparable, NSDate must also conform to Equatable.
//  Hence the == operator.
public func == (lhs: NSDate, rhs: NSDate) -> Bool {
    return lhs.compare(rhs) == .OrderedSame
}

public func > (lhs: NSDate, rhs: NSDate) -> Bool {
    return lhs.compare(rhs) == .OrderedDescending
}

public func < (lhs: NSDate, rhs: NSDate) -> Bool {
    return lhs.compare(rhs) == .OrderedAscending
}

public func <= (lhs: NSDate, rhs: NSDate) -> Bool {
    return  lhs == rhs || lhs < rhs
}

public func >= (lhs: NSDate, rhs: NSDate) -> Bool {
    return lhs == rhs || lhs > rhs
}

Vous pouvez utiliser ceci pour vérifier qu'une date était comprise entre deux dates:

let currentDate = NSDate()
let olderDate   = NSDate(timeIntervalSinceNow: -100)
let newerDate   = NSDate(timeIntervalSinceNow: 100)

olderDate < currentDate && currentDate < newerDate // Returns true

Voici quelques exemples supplémentaires d'utilisation des opérateurs avec NSDate:

olderDate < newerDate  // True
olderDate > newerDate  // False
olderDate != newerDate // True
olderDate == newerDate // False
2
ABakerSmith

Vous pouvez obtenir l'année, le mois et le jour à compter de la date d'aujourd'hui, les ajouter à ces chaînes de date et heure pour créer de nouveaux objets NSDate. Alors compare la todaysDate à ces deux objets NSDate résultants:

let todaysDate  = NSDate()
let startString = "8:00"
let endString   = "16:30"

// convert strings to `NSDate` objects

let formatter = NSDateFormatter()
formatter.dateFormat = "HH:mm"
let startTime = formatter.dateFromString(startString)
let endTime = formatter.dateFromString(endString)

// extract hour and minute from those `NSDate` objects

let calendar = NSCalendar.currentCalendar()

let startComponents = calendar.components([.Hour, .Minute], fromDate: startTime!)
let endComponents = calendar.components([.Hour, .Minute], fromDate: endTime!)

// extract day, month, and year from `todaysDate`

let nowComponents = calendar.components([.Month, .Day, .Year], fromDate: todaysDate)

// adjust the components to use the same date

startComponents.year  = nowComponents.year
startComponents.month = nowComponents.month
startComponents.day   = nowComponents.day

endComponents.year  = nowComponents.year
endComponents.month = nowComponents.month
endComponents.day   = nowComponents.day

// combine hour/min from date strings with day/month/year of `todaysDate`

let startDate = calendar.dateFromComponents(startComponents)
let endDate = calendar.dateFromComponents(endComponents)

// now we can see if today's date is inbetween these two resulting `NSDate` objects

let isInRange = todaysDate.compare(startDate!) != .OrderedAscending && todaysDate.compare(endDate!) != .OrderedDescending
2
Rob

Voici du code que j'utilise dans l'un de mes projets en cours. Il suffit de définir l’heure de début sur 8h00, l’heure de fin sur 16h30 et l’horodatage sur l’heure actuelle.

func isTimeStampCurrent(timeStamp:NSDate, startTime:NSDate, endTime:NSDate)->Bool{
    if timeStamp.earlierDate(endTime) == timeStamp && timeStamp.laterDate(startTime) == timeStamp{
        return true
    }
    return false
}
2
boidkan

Vous pouvez utiliser la méthode compare de NSDate: elle retournera une NSComparisonResult (OrderedSame, OrderedAscending ou OrderedDescending) que vous pourrez vérifier par rapport à vos dates de début et de fin:

let dateMaker = NSDateFormatter()
dateMaker.dateFormat = "yyyy/MM/dd HH:mm:ss"
let start = dateMaker.dateFromString("2015/04/15 08:00:00")!
let end = dateMaker.dateFromString("2015/04/15 16:30:00")!

func isBetweenMyTwoDates(date: NSDate) -> Bool {
    if start.compare(date) == .OrderedAscending && end.compare(date) == .OrderedDescending {
        return true
    }
    return false
}

println(isBetweenMyTwoDates(dateMaker.dateFromString("2015/04/15 12:42:00")!)) // prints true
println(isBetweenMyTwoDates(dateMaker.dateFromString("2015/04/15 17:00:00")!)) // prints false
1
ayaio

Vous pouvez comparer la date comme ça.

extension NSDate {

func isGreaterThanDate(dateToCompare: NSDate) -> Bool {
    //Declare Variables
    var isGreater = false

    //Compare Values
    if self.compare(dateToCompare) == NSComparisonResult.OrderedDescending {
        isGreater = true
    }

    //Return Result
    return isGreater
}

func isLessThanDate(dateToCompare: NSDate) -> Bool {
    //Declare Variables
    var isLess = false

    //Compare Values
    if self.compare(dateToCompare) == NSComparisonResult.OrderedAscending {
        isLess = true
    }

    //Return Result
    return isLess
}

func equalToDate(dateToCompare: NSDate) -> Bool {
    //Declare Variables
    var isEqualTo = false

    //Compare Values
    if self.compare(dateToCompare) == NSComparisonResult.OrderedSame {
        isEqualTo = true
    }

    //Return Result
    return isEqualTo
}

func addDays(daysToAdd: Int) -> NSDate {
    let secondsInDays: NSTimeInterval = Double(daysToAdd) * 60 * 60 * 24
    let dateWithDaysAdded: NSDate = self.dateByAddingTimeInterval(secondsInDays)

    //Return Result
    return dateWithDaysAdded
}

func addHours(hoursToAdd: Int) -> NSDate {
    let secondsInHours: NSTimeInterval = Double(hoursToAdd) * 60 * 60
    let dateWithHoursAdded: NSDate = self.dateByAddingTimeInterval(secondsInHours)

    //Return Result
    return dateWithHoursAdded
 }
}
0
pradeepchauhan_pc

aussi, la solution ci-dessous semble courte si je veux voir si le temps est dans une plage spécifique pendant la journée

var greeting = String()
let date     = Date()
let calendar = Calendar.current
let hour     = calendar.component(.hour, from: date)
//let minutes  = calendar.component(.minute, from: date)
let morning = 3; let afternoon=12; let evening=16; let night=22;

print("Hour: \(hour)")
if morning < hour, hour < afternoon {
    greeting = "Good Morning!"
}else if afternoon < hour, hour < evening{
    greeting = "Good Afternoon!"
}else if evening < hour, hour < night{
    greeting = "Good Evening!"
}else{
    greeting = "Good Night"
}
print(greeting)

je suppose que vous pourriez le modifier, pour vérifier par exemple, si les mois sont également dans certaines plages, par exemple:

sum = "Jan"
win = "March"
Spr = "May"
Aut = "Sept"

et continue à partir de là ...

0
nyxee