Как добавить 1 день к NSDate?

320

Как говорится в названии. Мне интересно, как я мог бы добавить 1 день к NSDate.

Так что, если бы это было:

21st February 2011

Это станет:

22nd February 2011

Или если бы это было:

31st December 2011

Это станет:

1st January 2012.
Андрей
источник
4
Обратите внимание, что NSDate не представляет дату, она представляет момент времени. Таким образом, это включает в себя время, а также дату.
Рог
4
Договорились - вы должны использовать ответ Zack German ниже. См. Руководство по программированию даты и времени Apple .
Эш Борроу
Прокрутите вниз для новых (и более коротких) решений!
catanore

Ответы:

711

Swift 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 за использование компонентов Date вместо добавления дня в секундах.
Abizern
Да, хорошо работает для перехода на летнее время. Совет для проверки на летнее время: сбросьте дату и время на вашем 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
@ прекрасное 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)

Цель С

 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];
IHS
источник
34

iOS 8+, OSX 10.9+, Objective-C

NSCalendar *cal = [NSCalendar currentCalendar];    
NSDate *tomorrow = [cal dateByAddingUnit:NSCalendarUnitDay 
                                   value:1 
                                  toDate:[NSDate date] 
                                 options:0];
vikingosegundo
источник
Обратите внимание, что вы не можете замаскировать блок здесь (используйте только один).
catanore
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)
    }

}

Использование только для добавления дня в соответствии с запросом OP будет:

let today = Date() // date is then today for this example
let tomorrow = today.add(days: 1)
Бенно Кресс
источник
2
Вы можете значительно сократить код, используя компоненты даты.
Викингосегундо
Вы правы, хотя, на мой взгляд, у него есть недостатки: - код, использующий расширение, выглядит не так чисто - он открывает некоторые ненужные опции с компонентами, которые не имеют особого смысла, как будто let foo = Date().add([.calendar: 1, .yearForWeekOfYear: 3] я добавляю альтернативное решение в свой ответ, хотя , Спасибо за ваше предложение, @vikingosegundo!
Бенно Кресс
3
ну, на самом деле я имел в виду что-то другое: gist.github.com/vikingosegundo/31ddb14920415ef444a9ab550411d4ff
vikingosegundo
22

Swift 4.0 (так же, как Swift 3.0 в этом замечательном ответе, просто давая понять новичкам, как я)

let today = Date()
let yesterday = Calendar.current.date(byAdding: .day, value: -1, to: today)
Джошуа Дэнс
источник
3
Вы забыли изменить имя переменной?
Ракеша Шастри
13

Используйте приведенную ниже функцию и используйте параметр days, чтобы получить дату 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;
}
Bhupendra
источник
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];
DenZhukov
источник
Ну, видимо, этот вопрос - это свалка небес. Так что нет причин выделять вас.
Дрю
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)!
}
AmJa
источник
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 «Swift Optionals».

quemeful
источник
3

Вы можете использовать метод NSDate - (id)dateByAddingTimeInterval:(NSTimeInterval)secondsгде secondsбы60 * 60 * 24 = 86400

Tiago
источник
3
AddByTimeInterval от NSDate устарел в iOS 4 ( bit.ly/vtOzvU ). Вместо этого используйте dateByAddingTimeInterval ( bit.ly/vRkFrN ).
billmaya
4
дни могут иметь 23, 24 или 25 часов из-за перехода на летнее время.
Викингосегундо
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)
Dharmesh
источник
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
n.by.n
источник
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]);
Shrikant Tanwade
источник
2

В Swift вы можете сделать расширение, чтобы добавить метод в 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

Swift 4, если все, что вам действительно нужно, это 24-часовая смена (60 * 60 * 24 секунд), а не «1 календарный день»

Будущее: let dayAhead = Date(timeIntervalSinceNow: TimeInterval(86400.0))

Прошлое: let dayAgo = Date(timeIntervalSinceNow: TimeInterval(-86400.0))

Джон Роби
источник
1

обновление для Swift 5

let nextDate = fromDate.addingTimeInterval(60*60*24)
Manish
источник
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);
Vũ Ngọc Giang
источник
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];
}
slashlos
источник
0

Swift 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

Расширение строки: Convert String_Date> 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

сейчас устарела.

Hemang
источник
3
дни могут иметь 23, 24 или 25 часов из-за перехода на летнее время
vikingosegundo