Come posso calcolare la differenza tra due date?


Risposte:


237
NSDate *date1 = [NSDate dateWithString:@"2010-01-01 00:00:00 +0000"];
NSDate *date2 = [NSDate dateWithString:@"2010-02-03 00:00:00 +0000"];

NSTimeInterval secondsBetween = [date2 timeIntervalSinceDate:date1];

int numberOfDays = secondsBetween / 86400;

NSLog(@"There are %d days in between the two dates.", numberOfDays);

MODIFICARE:

Ricorda, gli NSDateoggetti rappresentano momenti esatti di tempo, non hanno alcuna informazione sul fuso orario associato. Quando si converte una stringa in una data utilizzando, ad esempio NSDateFormatter, un , viene NSDateFormatterconvertita l'ora dal fuso orario configurato. Pertanto, il numero di secondi tra due NSDateoggetti sarà sempre fuso orario.

Inoltre, questa documentazione specifica che l'implementazione del tempo di Cocoa non tiene conto dei secondi intercalari, quindi se hai bisogno di una tale precisione, dovrai eseguire la tua implementazione.


5
@RalucaGurau: 86400 è il numero di secondi in un giorno (cioè 60 secondi, volte 60 minuti, volte 24 ore). Non ha niente a che fare con il mese.
dreamlax

18
Non tutti i giorni hanno 86400 secondi. Per un esempio banale va bene, ma non è una buona idea nel mondo reale. Le modifiche all'ora legale, i secondi intercalari, ecc. Possono tutti rovinarlo. NSCalendar può dirti quanti secondi sono in un dato giorno.
NeilInglis

2
@muthukumar: Non su iOS, il metodo è disponibile solo su Mac OS X. Questa domanda è contrassegnata cocoae non cocoa-touchquindi questa risposta si applica solo a Mac OS X.
dreamlax

1
Il numero di giorni tra due momenti qualsiasi nel tempo sarà sempre 86400. Se gli esseri umani sono nella fase di ingannare se stessi per svegliarsi un'ora prima del normale o no, non fa differenza sul fatto che un giorno dura 86400 secondi (ignorando il salto secondi)
dreamlax

1
Voglio solo aggiungere che se non hai quel +0000 alla fine, otterrai date nulle e un valore di 0 sempre sul diff, non importa quale. Quindi, non cadere in quella trappola.
Volomike

84

Potresti voler usare qualcosa del genere:

NSDateComponents *components;
NSInteger days;

components = [[NSCalendar currentCalendar] components: NSDayCalendarUnit 
        fromDate: startDate toDate: endDate options: 0];
days = [components day];

Credo che questo metodo tenga conto di situazioni come le date che riguardano un cambiamento dell'ora legale.


2
c'è un modo semplice per ignorare anche l'ora per le date indicate?
Mihai Timar

può essere modificato di conseguenza per altre unità di calendario :) utilizzato per l'unità Anno.
esperto di tecnologia

NSDategli oggetti sono già indipendenti dal fuso orario. Le informazioni sul fuso orario vengono rimosse quando si analizzano le date, ad esempio NSDateFormatter, in modo che gli NSDateoggetti rappresentino momenti esatti nel tempo. Pertanto, se hai già startDatee endDate, questi due oggetti saranno distanti x un numero di secondi. I fusi orari non avranno nulla a che fare con questo.
dreamlax

@ Benjamin: Perché dici questo?
dreamlax

dreamlax, la tua risposta è sbagliata. Chiaro e semplice. Calcola il numero di giorni tra le 12:00 dell'1 gennaio, ora solare e le 12:00 dell'1 aprile, e la tua formula non funziona. È una formula lenta e gli sviluppatori dovrebbero utilizzare l'oggetto NSDateComponents per calcolarlo.
Rickster

25
NSTimeInterval diff = [date2 timeIntervalSinceDate:date1]; // in seconds

dove date1e date2sono NSDate.

Inoltre, nota la definizione di NSTimeInterval:

typedef double NSTimeInterval;

Nota che NSTimeInterval è in realtà un doppio, quindi puoi usarlo come qualsiasi altro numero.
Kendall Helmstetter Gelner

19

Dai un'occhiata a questo. Si occupa dell'ora legale e dell'anno bisestile poiché utilizzava il calendario iOS per il calcolo. Puoi modificare la stringa e le condizioni per includere minuti con ore e giorni.

+(NSString*)remaningTime:(NSDate*)startDate endDate:(NSDate*)endDate
{
    NSDateComponents *components;
    NSInteger days;
    NSInteger hour;
    NSInteger minutes;
    NSString *durationString;

    components = [[NSCalendar currentCalendar] components: NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute fromDate: startDate toDate: endDate options: 0];

    days = [components day];
    hour = [components hour];
    minutes = [components minute];

    if(days>0)
    {
        if(days>1)
            durationString=[NSString stringWithFormat:@"%d days",days];
        else
            durationString=[NSString stringWithFormat:@"%d day",days];
        return durationString;
    }
    if(hour>0)
    {        
        if(hour>1)
            durationString=[NSString stringWithFormat:@"%d hours",hour];
        else
            durationString=[NSString stringWithFormat:@"%d hour",hour];
        return durationString;
    }
    if(minutes>0)
    {
        if(minutes>1)
            durationString = [NSString stringWithFormat:@"%d minutes",minutes];
        else
            durationString = [NSString stringWithFormat:@"%d minute",minutes];

        return durationString;
    }
    return @""; 
}

questo metodo è il modo perfetto per calcolare la differenza di orario.
Moxarth

solo puoi tenere altro se con tutte quelle condizioni if. altrimenti verrà visualizzato un solo formato di ora.
Moxarth

3

Con Swift 5 e iOS 12, in base alle tue esigenze, puoi utilizzare uno dei due modi seguenti per trovare la differenza tra due date in giorni.


# 1. Utilizzando Calendaril dateComponents(_:from:to:)metodo di

import Foundation

let calendar = Calendar.current

let startDate = calendar.date(from: DateComponents(year: 2010, month: 11, day: 22))!
let endDate = calendar.date(from: DateComponents(year: 2015, month: 5, day: 1))!

let dateComponents = calendar.dateComponents([Calendar.Component.day], from: startDate, to: endDate)

print(dateComponents) // prints: day: 1621 isLeapMonth: false
print(String(describing: dateComponents.day)) // prints: Optional(1621)

# 2. Utilizzando DateComponentsFormatteril string(from:to:)metodo di

import Foundation

let calendar = Calendar.current

let startDate = calendar.date(from: DateComponents(year: 2010, month: 11, day: 22))!
let endDate = calendar.date(from: DateComponents(year: 2015, month: 5, day: 1))!

let formatter = DateComponentsFormatter()
formatter.unitsStyle = .full
formatter.allowedUnits = [NSCalendar.Unit.day]

let elapsedTime = formatter.string(from: startDate, to: endDate)
print(String(describing: elapsedTime)) // prints: Optional("1,621 days")

1

Swift 4
Prova questo e vedi (intervallo di date con stringa):

// Start & End date string
let startingAt = "01/01/2018"
let endingAt = "08/03/2018"

// Sample date formatter
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd/MM/yyyy"

// start and end date object from string dates
var startDate = dateFormatter.date(from: startingAt) ?? Date()
let endDate = dateFormatter.date(from: endingAt) ?? Date()


// Actual operational logic
var dateRange: [String] = []
while startDate <= endDate {
    let stringDate = dateFormatter.string(from: startDate)
    startDate = Calendar.current.date(byAdding: .day, value: 1, to: startDate) ?? Date()
    dateRange.append(stringDate)
}

print("Resulting Array - \(dateRange)")

Swift 3

var date1 = Date(string: "2010-01-01 00:00:00 +0000")
var date2 = Date(string: "2010-02-03 00:00:00 +0000")
var secondsBetween: TimeInterval = date2.timeIntervalSince(date1)
var numberOfDays: Int = secondsBetween / 86400
print(numberOfDays)

Non tutti i giorni hanno quella quantità di secondi.
Pavan

@Pavan - Sei il benvenuto a condividere i tuoi input aggiornando questa risposta e migliorandola.
Krunal

Per renderlo migliore richiederebbe la riscrittura dell'intera risposta, nel qual caso potrebbe anche essere cancellata perché sarà la stessa soluzione della risposta sopra che non utilizza valori hardcoded :)
Pavan

0

Puoi trovare la differenza convertendo la data in secondi e prendere l'intervallo di tempo dal 1970 per questo, quindi puoi trovare la differenza tra due date.


quando due date possono essere calcolate direttamente l'una con l'altra (assumendo lo stesso dominio temporale). C'è una ragione specifica per calcolare prima entrambe le date dal 1970 e poi trovare la differenza?
Adeel

0

Per trovare la differenza, è necessario ottenere la data corrente e la data futura. Nel caso seguente, ho usato 2 giorni per un esempio della data futura. Calcolato da:

2 days* 24 hours* 60 minutes* 60 seconds. Prevediamo che il numero di secondi in 2 giorni sia 172.800.

// Set the current and future date
let now = Date()
let nowPlus2Days = Date(timeInterval: 2*24*60*60, since: now)

// Get the number of seconds between these two dates
let secondsInterval = DateInterval(start: now, end: nowPlus2Days).duration

print(secondsInterval) // 172800.0

1
Per favore, non pubblicare solo il codice come risposta, ma fornisci anche una spiegazione su cosa fa il tuo codice e come risolve il problema della domanda. Le risposte con una spiegazione sono generalmente di qualità superiore e hanno maggiori probabilità di attirare voti positivi.
Mark Rotteveel il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.