Як додати 1 день до NSDate?


320

В основному, як говорить назва. Мені цікаво, як я міг би додати 1 день до NSDate.

Так якби це було:

21st February 2011

Це стане:

22nd February 2011

Або якби це:

31st December 2011

Це стане:

1st January 2012.

4
Зауважте, що NSDate не представляє дату, він представляє момент часу. Тож він включає час і дату.
Рог

4
Погоджено - ви повинні використовувати відповідь Зака ​​Немця нижче. Дивіться Посібник з програмування дати та часу Apple .
Еш Борозен

Прокрутіть униз до нових (і коротших) рішень!
катанора

Відповіді:


711

Швидкий 5.0:

var dayComponent    = DateComponents()
dayComponent.day    = 1 // For removing one day (yesterday): -1
let theCalendar     = Calendar.current
let nextDate        = theCalendar.date(byAdding: dayComponent, to: Date())
print("nextDate : \(nextDate)")

Мета C:

NSDateComponents *dayComponent = [[NSDateComponents alloc] init];
dayComponent.day = 1;

NSCalendar *theCalendar = [NSCalendar currentCalendar];
NSDate *nextDate = [theCalendar dateByAddingComponents:dayComponent toDate:[NSDate date] options:0];

NSLog(@"nextDate: %@ ...", nextDate);

Це має бути зрозумілим.


19
Ви також можете використовувати негативні компоненти для віднімання дати.
DataGraham

58
Набагато краще рішення, ніж обрана відповідь
Джастін Майнерс

19
+1 для використання компонентів дати, а не додавання дня, що становить секунди.
Abizern

Так, добре працює для економії денного світла. Порада для перевірки DST: Скиньте дату та час на вашому mac, а потім перезапустіть ваш тренажер, і він буде слідувати вашому системному часу.
Роб ван ден Берг

2
У Swift вам потрібно змінити останній параметр dateByAddingComponents виклику наNSCalendarOptions(rawValue: 0)
gfpacheco

270

Оскільки iOS 8 ви можете використовувати NSCalendar.dateByAddingUnit

Приклад у Swift 1.x:

let today = NSDate()
let tomorrow = NSCalendar.currentCalendar()
    .dateByAddingUnit(
         .CalendarUnitDay, 
         value: 1, 
         toDate: today, 
         options: NSCalendarOptions(0)
    )

Swift 2.0:

let today = NSDate()
let tomorrow = NSCalendar.currentCalendar()
    .dateByAddingUnit(
        .Day, 
        value: 1, 
        toDate: today, 
        options: []
    )

Swift 3.0:

let today = Date()
let tomorrow = Calendar.current.date(byAdding: .day, value: 1, to: today)

5
Це тільки я, чи не було б у Swift набагато простіше мати щось вбудоване date.add(.days, 1)? * іде і будує прибудова
quemeful

2
@quemeful extension Date { func adding(_ component: Calendar.Component, _ value: Int) -> Date? { return Calendar.current.date(byAdding: component, value: value, to: self) } }використанняDate().adding(.day, 1) // "Jun 6, 2019 at 5:35 PM"
Лев Дабус

82

Оновлено для Swift 5

let today = Date()
let nextDate = Calendar.current.date(byAdding: .day, value: 1, to: today)

Мета C

 NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
 // now build a NSDate object for the next day
 NSDateComponents *offsetComponents = [[NSDateComponents alloc] init];
 [offsetComponents setDay:1];
 NSDate *nextDate = [gregorian dateByAddingComponents:offsetComponents toDate: [NSDate date] options:0];

34

iOS 8+, OSX 10.9+, Objective-C

NSCalendar *cal = [NSCalendar currentCalendar];    
NSDate *tomorrow = [cal dateByAddingUnit:NSCalendarUnitDay 
                                   value:1 
                                  toDate:[NSDate date] 
                                 options:0];

Зауважте, що тут не можна маскувати пристрій (використовуйте лише один).
катанора

31

Працюючий реалізація Swift 3+ на основі highmaintenance в відповідь і vikingosegundo в коментарі. Це розширення дати також має додаткові параметри зміни року, місяця та часу:

extension Date {

    /// Returns a Date with the specified amount of components added to the one it is called with
    func add(years: Int = 0, months: Int = 0, days: Int = 0, hours: Int = 0, minutes: Int = 0, seconds: Int = 0) -> Date? {
        let components = DateComponents(year: years, month: months, day: days, hour: hours, minute: minutes, second: seconds)
        return Calendar.current.date(byAdding: components, to: self)
    }

    /// Returns a Date with the specified amount of components subtracted from the one it is called with
    func subtract(years: Int = 0, months: Int = 0, days: Int = 0, hours: Int = 0, minutes: Int = 0, seconds: Int = 0) -> Date? {
        return add(years: -years, months: -months, days: -days, hours: -hours, minutes: -minutes, seconds: -seconds)
    }

}

Використання лише додавання дня, як просив ОП, було б:

let today = Date() // date is then today for this example
let tomorrow = today.add(days: 1)

2
Ви можете скоротити код масово, використовуючи компоненти дат.
vikingosegundo

Ви маєте рацію, хоча, на мою думку, є і недоліки: - код, що використовує розширення, виглядає не таким чистим - він відкриває деякі непотрібні параметри з компонентами, які мають мало сенсу, як let foo = Date().add([.calendar: 1, .yearForWeekOfYear: 3] і я додаю альтернативне рішення до своєї відповіді, хоча . Дякуємо за вашу пропозицію, @vikingosegundo!
Бенно Кресс

3
ну, я фактично мав на увазі щось інше: gist.github.com/vikingosegundo/31ddb14920415ef444a9ab550411d4ff
vikingosegundo


13

Використовуйте наведену нижче функцію та використовуйте параметр дня, щоб отримати дату daysAhead / daysBehind просто передайте параметр як позитивний для майбутньої дати або як мінус для попередніх дат:

+ (NSDate *) getDate:(NSDate *)fromDate daysAhead:(NSUInteger)days
{
    NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
    dateComponents.day = days;
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSDate *previousDate = [calendar dateByAddingComponents:dateComponents
                                                     toDate:fromDate
                                                    options:0];
    [dateComponents release];
    return previousDate;
}

10

Швидко

var dayComponenet = NSDateComponents()
dayComponenet.day = 1

var theCalendar = NSCalendar.currentCalendar()
var nextDate = theCalendar.dateByAddingComponents(dayComponenet, toDate: NSDate(), options: nil)

8

Це робота!

    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSCalendarUnit unit = NSCalendarUnitDay;
    NSInteger value = 1;
    NSDate *today = [NSDate date];
    NSDate *tomorrow = [calendar dateByAddingUnit:unit value:value toDate:today options:NSCalendarMatchStrictly];

Ну, мабуть, це питання - код скидання неба. Тож немає причин виділяти вас.
Дрю

2
моя відповідь правильніша, тому що якщо ви використовуєте параметр NSCalendarWrapComponents (0), ви можете створювати дату лише в діапазоні поточного місяця. Це означає, що якщо ви додасте 1 день з NSCalendarWrapComponents до 31 січня 2016 року, ви отримаєте 1 січня 2016 року. За допомогою параметра NSCalendarMatchStrictly ви отримаєте наступну дату календаря.
ДенЖуков

8

Swift 3.0 дуже простою реалізацією буде:

func dateByAddingDays(inDays: Int) -> Date {
    let today = Date()
    return Calendar.current.date(byAdding: .day, value: inDays, to: today)!
}

5
NSDate *today=[NSDate date];
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar];
NSDateComponents *components=[[NSDateComponents alloc] init];
components.day=1;
NSDate *targetDate =[calendar dateByAddingComponents:components toDate:today options: 0];

5

Swift 4.0

extension Date {
    func add(_ unit: Calendar.Component, value: Int) -> Date? {
        return Calendar.current.date(byAdding: unit, value: value, to: self)
    }
}

Використання

date.add(.day, 3)!   // adds 3 days
date.add(.day, -14)!   // subtracts 14 days

Примітка. Якщо ви не знаєте, чому рядки коду закінчуються знаком оклику, знайдіть "Швидкий вибір" в Google.


3

Ви можете використовувати метод NSDate там, - (id)dateByAddingTimeInterval:(NSTimeInterval)secondsде secondsбув би60 * 60 * 24 = 86400


3
Додаток NSDate addByTimeInterval був застарілий у iOS 4 ( bit.ly/vtOzvU ). Використовуйте замість dateByAddingTimeInterval ( bit.ly/vRkFrN ).
billmaya

4
через літній час може тривати 23, 24 або 25 годин.
vikingosegundo

3

У Swift 2.1.1 та xcode 7.1 OSX 10.10.5 ви можете додавати будь-яку кількість днів уперед та назад за допомогою функції

func addDaystoGivenDate(baseDate:NSDate,NumberOfDaysToAdd:Int)->NSDate
{
    let dateComponents = NSDateComponents()
    let CurrentCalendar = NSCalendar.currentCalendar()
    let CalendarOption = NSCalendarOptions()

    dateComponents.day = NumberOfDaysToAdd

    let newDate = CurrentCalendar.dateByAddingComponents(dateComponents, toDate: baseDate, options: CalendarOption)
    return newDate!
}

виклик функції для збільшення поточної дати на 9 днів

var newDate = addDaystoGivenDate(NSDate(), NumberOfDaysToAdd: 9)
print(newDate)

виклик функції для поточної дати зменшення на 80 днів

newDate = addDaystoGivenDate(NSDate(), NumberOfDaysToAdd: -80)
 print(newDate)

3

Ось метод загального призначення, який дозволяє додавати / віднімати будь-який тип одиниці (рік / місяць / день / година / другий тощо) у вказану дату.

Використання Swift 2.2

func addUnitToDate(unitType: NSCalendarUnit, number: Int, date:NSDate) -> NSDate {

    return NSCalendar.currentCalendar().dateByAddingUnit(
        unitType,
        value: number,
        toDate: date,
        options: NSCalendarOptions(rawValue: 0))!

}

print( addUnitToDate(.Day, number: 1, date: NSDate()) ) // Adds 1 Day To Current Date
print( addUnitToDate(.Hour, number: 1, date: NSDate()) ) // Adds 1 Hour To Current Date
print( addUnitToDate(.Minute, number: 1, date: NSDate()) ) // Adds 1 Minute To Current Date

// NOTE: You can use negative values to get backward values too

3
NSDateComponents *dayComponent = [[[NSDateComponents alloc] init] autorelease];
dayComponent.day = 1;

NSCalendar *theCalendar = [NSCalendar currentCalendar];
dateToBeIncremented = [theCalendar dateByAddingComponents:dayComponent toDate:dateToBeIncremented options:0];

Гаразд - я думав, що це буде працювати для мене. Однак якщо ви використовуєте його для додавання дня до 31 березня 2013 року, він поверне дату, до якої додано лише 23 години. Насправді це може бути 24, але до використання в обчисленнях додано лише 23:00 години.

Аналогічно, якщо ви рухаєтесь вперед до 28 жовтня 2013 року, код додає 25 годин, що призводить до часу побачення 2013-10-28 01:00:00.

Для того, щоб додати день, я робив річ у верхній частині, додаючи:

NSDate *newDate1 = [now dateByAddingTimeInterval:60*60*24*daysToAdd];

Складний, головним чином, через літній час.


раз на рік має всього 23 години. раз 25. і кожні кілька років він має тривалість 60*60*24 + 1через високосні секунди. дати повинні охоплювати все це, і саме тому обробка какао датами насправді чудова!
вікіосегундо

2
NSDate *now = [NSDate date];
int daysToAdd = 1;
NSDate *tomorrowDate = [now dateByAddingTimeInterval:60*60*24*daysToAdd];

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"EEEE, dd MMM yyyy"];
NSLog(@"%@", [dateFormatter stringFromDate:tomorrowDate]);

2

Швидко ви можете зробити розширення, щоб додати метод у NSDate

extension NSDate {
    func addNoOfDays(noOfDays:Int) -> NSDate! {
        let cal:NSCalendar = NSCalendar.currentCalendar()
        cal.timeZone = NSTimeZone(abbreviation: "UTC")!
        let comps:NSDateComponents = NSDateComponents()
        comps.day = noOfDays
        return cal.dateByAddingComponents(comps, toDate: self, options: nil)
    }
}

Ви можете використовувати це як

NSDate().addNoOfDays(3)

2

Оновлення для Swift 4:

let now = Date() // the current date/time
let oneDayFromNow = Calendar.current.date(byAdding: .day, value: 1, to: now) // Tomorrow with same time of day as now

1

для швидкого 2.2:

let today = NSDate()
let tomorrow = NSCalendar.currentCalendar().dateByAddingUnit(
        .Day,
        value: 1,
        toDate: today,
        options: NSCalendarOptions.MatchStrictly)

Сподіваюся, це комусь допоможе!


1

Швидкий 4, якщо все, що вам дійсно потрібно, - це 24-годинна зміна (60 * 60 * 24 секунди), а не «1 календарний день»

Майбутнє: let dayAhead = Date(timeIntervalSinceNow: TimeInterval(86400.0))

Минуле: let dayAgo = Date(timeIntervalSinceNow: TimeInterval(-86400.0))



0
NSDate *now = [NSDate date];
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:now];
NSDate *startDate = [calendar dateFromComponents:components];
NSLog(@"StartDate = %@", startDate);

components.day += 1;
NSDate *endDate = [calendar dateFromComponents:components];
NSLog(@"EndDate = %@", endDate);

0

У мене була така ж проблема; використовувати розширення для NSDate:

- (id)dateByAddingYears:(NSUInteger)years
                 months:(NSUInteger)months
                   days:(NSUInteger)days
                  hours:(NSUInteger)hours
                minutes:(NSUInteger)minutes
                seconds:(NSUInteger)seconds
{
    NSDateComponents * delta = [[[NSDateComponents alloc] init] autorelease];
    NSCalendar * gregorian = [[[NSCalendar alloc]
                               initWithCalendarIdentifier:NSCalendarIdentifierGregorian] autorelease];

    [delta setYear:years];
    [delta setMonth:months];
    [delta setDay:days];
    [delta setHour:hours];
    [delta setMinute:minutes];
    [delta setSecond:seconds];

    return [gregorian dateByAddingComponents:delta toDate:self options:0];
}

0

Швидкий 2.0

let today = NSDate()    
let calendar = NSCalendar.currentCalendar()
let tomorrow = calendar.dateByAddingUnit(.Day, value: 1, toDate: today, options: NSCalendarOptions.MatchFirst)

0

У swift 4 або swift 5 ви можете використовувати, як нижче:

    let date = Date()
    let yesterday = Calendar.current.date(byAdding: .day, value: -1, to: date)
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "yyyy-MM-dd"
    let yesterday_date = dateFormatter.string(from: yesterday!)
    print("yesterday->",yesterday_date)

вихід:

Current date: 2020-03-02
yesterday date: 2020-03-01

0

Розширення рядка: Перетворити String_Date> Дата

extension String{
  func DateConvert(oldFormat:String)->Date{ // format example: yyyy-MM-dd HH:mm:ss 
    let isoDate = self
    let dateFormatter = DateFormatter()
    dateFormatter.locale = Locale(identifier: "en_US_POSIX") // set locale to reliable US_POSIX
    dateFormatter.dateFormat = oldFormat
    return dateFormatter.date(from:isoDate)!
  }
}

Розширення дати: Перетворити дату> Рядок

extension Date{
 func DateConvert(_ newFormat:String)-> String{
    let formatter = DateFormatter()
    formatter.dateFormat = newFormat
    return formatter.string(from: self)
 }
}

Розширення дати: Отримайте +/- Дата

extension String{
  func next(day:Int)->Date{
    var dayComponent    = DateComponents()
    dayComponent.day    = day
    let theCalendar     = Calendar.current
    let nextDate        = theCalendar.date(byAdding: dayComponent, to: Date())
    return nextDate!
  }

 func past(day:Int)->Date{
    var pastCount = day
    if(pastCount>0){
        pastCount = day * -1
    }
    var dayComponent    = DateComponents()
    dayComponent.day    = pastCount
    let theCalendar     = Calendar.current
    let nextDate        = theCalendar.date(byAdding: dayComponent, to: Date())
    return nextDate!
 }
}

Використання:

let today = Date()
let todayString = "2020-02-02 23:00:00"
let newDate = today.DateConvert("yyyy-MM-dd HH:mm:ss") //2020-02-02 23:00:00
let newToday = todayString.DateConvert(oldFormat: "yyyy-MM-dd HH:mm:ss")//2020-02-02
let newDatePlus = today.next(day: 1)//2020-02-03 23:00:00
let newDateMinus = today.past(day: 1)//2020-02-01 23:00:00

довідка: з декількох запитань
Як додати 1 день до NSDate?
математична функція для перетворення позитивного int в негативний і негативного в позитивний?
Перетворення NSString в NSDate (і назад)


-1

Використовуйте наступний код:

NSDate *now = [NSDate date];
int daysToAdd = 1;
NSDate *newDate1 = [now dateByAddingTimeInterval:60*60*24*daysToAdd];

Як

addTimeInterval

зараз застаріло.


3
дні можуть мати 23, 24 або 25 годин через літній час
vikingosegundo
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.