hızlı bir şekilde belirli bir aralıkta olup olmadığını kontrol etme

Merhaba, geçerli zamanın 8: 00-16: 30 saatleri arasında olup olmadığını kontrol etmeye çalışıyorum. Aşağıdaki kod, geçerli saati bir dize olarak alabileceğimi gösteriyor, ancak yukarıda belirtilen zaman aralığında olup olmadığını kontrol etmek için bu değeri nasıl kullanabileceğimden emin değilim. Herhangi bir yardım çok takdir edilecektir!

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

9 cevap

Bunu yapmanın birçok yolu vardır. Şahsen, eğer kaçınabilsem, stringlerle çalışmaktan hoşlanmam. Tarih bileşenleriyle uğraşmayı tercih ederim.

Aşağıda, geçerli tarihin gün/ay/yılını almak için bir Takvim nesnesi kullanan ve istenen saat/dakika bileşenlerini ekleyen ve ardından bu bileşenler için bir tarih oluşturan bazı oyun alanı kodları verilmiştir.

Saat 8:00 ve 16:30 için tarihler oluşturur ve ardından geçerli tarih/saatin o aralıkta olup olmadığını görmek için tarihleri ​​karşılaştırır.

Diğer kişilerin kodlarından daha uzun, ancak bence Takvim kullanarak tarihlerle hesaplama yapma konusunda öğrenmeye değer:

# 3 DÜZENLE:

Bu cevap uzun zaman önceydi. Eski cevabı aşağıda bırakacağım, ancak şu andaki çözüm

@CodenameDuchess' answer uses a system function, date(bySettingHour:minute:second:of:matchingPolicy:repeatedTimePolicy:direction:)

Bu işlevi kullanarak, kod basitleştirilebilir:

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")
}

Eski (Swift 2) cevabı, tarihsel bir bütünlük için şöyledir:

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")
}

DÜZENLE:

Bu cevaptaki kod Swift 3 için bir LOT değiştirdi.

NSDate kullanmak yerine, bize yerel Date nesnesini ve Date nesnelerini Equatable ve Karşılaştırılabilir "kutunun dışında".

Thus we can get rid of the Equatable and Comparable extensions and the definitions for the <, > and = operators.

O zaman Swift 3 sözdizimini takip etmek için dateAt işlevinde sözdiziminin çok az bir miktarını yapmamız gerekir. Swift 3’teki yeni uzantı şöyle görünüyor:

Swift 3 versiyonu:

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")
}
21
katma
NSDates herhangi bir zaman dilimi kullanmaz. Her zaman dahili olarak GMT/UTC'de depolanırlar. Sadece onları belirli bir zaman diliminde gördüğünüzü gösterdiğiniz zaman. Bir tarihi belirli bir saat diliminde görüntülemenin en kolay yolu, bir tarih biçimlendirici kullanmaktır. (Her ne kadar println ("\ (someDate)") sözdizimine benzese de, cihazın varsayılan yerel ayarında görüntülenir.
katma yazar Duncan C, kaynak
Hayır. NSDates, gezegenin herhangi bir yerinde zamanın bir anını tanımlar. UTC'yi dahili olarak kullanırlar. Eğer 2 NSDate aynıysa, zaman diliminden bağımsız olarak, zaman içinde aynı anı tanımlar.
katma yazar Duncan C, kaynak
@ PSUSabes, sorun değil, yardımcı olmaktan memnuniyet duyarız. Şimdi kim aşağı oy kullandı? Çıldırtan adam. Cevabımın eksik olduğunu veya bir şekilde kötü bilgi verdiğini düşünüyorsanız, lütfen aşağı oyla ve bana neyin yanlış olduğunu söyleyin, ancak açıklama yapmadan oy kullanma
katma yazar Duncan C, kaynak
Bu gerçekten istisnai bir cevaptı @DuncanC çok teşekkürler
katma yazar GarySabo, kaynak
hala mükemmel bir çözüm. bana çok yardımcı oldu ..
katma yazar nyxee, kaynak
Aydınlattığın için teşekkürler Duncan, test ettim ve söylediğin gibi işe yarıyor. Şerefe.
katma yazar redman, kaynak
Evet, ancak kıyaslama gibi bir hesaplama yaparsanız, dengeleme hesabım olmadığından sonuçlarım yanlış olmaz mı? Alternatif olarak, sadece 8: 00-16: 30'umu GMT'ye dönüştürebileceğimi düşünüyorum ve bu işe yaramalı.
katma yazar redman, kaynak
Yukarıdaki kod çalışıyor gibi görünüyor, ancak şimdiki saat GMT olarak alındı. Telefondaki yerel saat dilimini kullanan veya UTC/GMT + 10 olan Avustralya Doğu Saati gibi belirtilen bir NSDate nesnesi oluşturmanın bir yolu var mı?
katma yazar redman, kaynak
Harika bir cevap, özellikle Swift 3 için 2 numaralı güncelleme.
katma yazar brian_schick, kaynak

In Swift 3.0 you can use the new Date value type and compare directly with ==,>,< 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

    }

Gerçekten çok kullanışlı.

12
katma
Aslında, date (bySettingHour: minute: second: of: options :) , bir NSCalendar işlevi ve eşdeğer Swift 3 Takvim işlevi date (bySettingHour: minute: second: of: matchingPolicy: yinelenenT & zwnj; imePolicy: direction: & zwnj;)
katma yazar Duncan C, kaynak
Düşes, iyi cevap, tarihini kullanarak (bySettingHour: minute: second: of :) . Bu, daha yeni bir Takvim işlevini kaçırmış gibi görünüyor. Tarih uzantıma olan ihtiyacımı engelliyor.
katma yazar Duncan C, kaynak
Teşekkürler benim için hızlıca çalıştı 3 bu kodu kullanıyorum: let todayAtEightAM = calendar.date (bySettingHour: hourStart, minute: minStart, second: 00, of: nowDateValue) minEnd, saniye: 00, toplam: nowDateValue)
katma yazar Chandni, kaynak
amortismana tabi ...?
katma yazar dylan, kaynak
dylan, bu hala hızlı çalışıyor
katma yazar Kang Byul, kaynak

Swift 3

Bu, geçerli zamanın belirli bir zaman aralığında olup olmadığını karşılaştırarak bir Dize döndüren bir işlevdir. Bir Oyun Alanında çalıştırın ve kendi ihtiyaçlarınıza göre uyarlayın.

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..= 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
katma
ayrıca zaman dilimini de düşünmelisiniz.
katma yazar Rajender Kumar, kaynak
dateFormatter.timeZone = TimeZone (kısaltma: "UTC")
katma yazar Rajender Kumar, kaynak

Bugünün tarihinden itibaren yıl, ay ve günü alabilirsiniz, bunları yeni NSDate nesneleri oluşturmak için bu tarih saat dizgelerine ekleyin. Ardından todaysDate ile sonuçlanan iki NSDate nesnesini karşılaştırın:

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
katma

You could make NSDate conform to the Comparable protocol to be able to use the ==, !=, <=, >=, > and < operators. For example:

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
}

Bunu bir tarihi kontrol etmek için kullanmak iki tarih içinde idi:

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

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

İşleçlerin NSDate ile nasıl kullanılacağına ilişkin birkaç örnek:

olderDate < newerDate //True
olderDate > newerDate //False
olderDate != newerDate//True
olderDate == newerDate//False
2
katma
Cevabımda da vardı ama Swift 3, Date nesnelerini uyumlu ve eşitlenebilir hale getirdi, bu yüzden bu uzantıya gerek kalmadı.
katma yazar Duncan C, kaynak

NSDate adresinden compare yöntemini kullanabilirsiniz: bir NSComparisonResult ( OrderedSame , OrderedAscending veya OrderedDcending ) başlangıç ​​ve bitiş tarihlerinize göre kontrol edebilirsiniz:

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
katma

İşte mevcut projelerimden birinde kullandığım bazı kodlar. Sadece başlangıç ​​saatini 8:00, bitiş saatini 16:30 ve timeStamp'ı geçerli saat olarak ayarlayın.

func isTimeStampCurrent(timeStamp:NSDate, startTime:NSDate, endTime:NSDate)->Bool{
    if timeStamp.earlierDate(endTime) == timeStamp && timeStamp.laterDate(startTime) == timeStamp{
        return true
    }
    return false
}
1
katma
Geri bildiriminiz için herkese teşekkürler. Şimdi geçiyorum ve hangisinin uygulanması en kolay olduğunu görüyorum.
katma yazar redman, kaynak

Ayrıca, zamanın gün içinde belirli bir aralıkta olup olmadığını görmek istersem aşağıdaki çözüm kısa görünür

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)

Örneğin, ayların da belirli aralıklarda olup olmadığını kontrol etmek için değiştirebilirsin, örneğin:

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

ve oradan devam et ...

0
katma

Tarihi böyle karşılaştırabilirsiniz.

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
katma