NSDate: получение значений для завтра или вчера

У меня есть фрагмент кода, который в основном состоит из двух частей:

Часть 1: Пользователь устанавливает дату с помощью UIDatePicker. Например, пользователь выбирает на 1 день вперед от текущей даты. Таким образом, выбранная новая дата — 19.05.16 вместо 18.05.16.

Код части 1

let dateFormatter = NSDateFormatter()
dateFormatter.locale = NSLocale.currentLocale()
var  dateString = "May-19-2016"
dateFormatter.dateFormat = "MMMM-dd-yyyy"

var due_date = dateFormatter.dateFromString(dateString)!

Часть 2: Я создал код, который подсчитывает, сколько дней осталось от выбранной даты до текущей даты. В этом примере мой код каким-то образом говорит, что до завтра 0 дней. Вот код второй части:

Вторая часть:

func computeDates(dueDate:NSDate)-> Int {

let currentDate = NSDate()

// Adding days to currentDate
let daysToAdd = 1

// Adding on Unit to the current instance
let calculateDate = NSCalendar.currentCalendar().dateByAddingUnit(NSCalendarUnit.Day, value: daysToAdd, toDate: currentDate, options: NSCalendarOptions.init(rawValue: 0))

// Figure out many days from may 3rd
let cal = NSCalendar.currentCalendar()

let unit = NSCalendarUnit.Day

let components = cal.components(unit, fromDate: currentDate, toDate: dueDate, options: [])

let countLeft = components.day

return countLeft
}

print("Days left: \(computeDates(due_date)) ")


// Tests
let calc_date = computeDates(due_date)

if calc_date <= -1 {
    print("Yesterday")
} else if calc_date == 0 {
    print("Today")
} else if calc_date > 1 {          
    print("Tomorrow")
}

В примере первой части я использовал статическую дату, которую я использую для тестирования этого кода. В этой части я установил 19 мая 2016 года, на один день вперед. Во второй части ниже в выражении if он каким-то образом говорит, что у меня осталось 0 дней, и из того, что я пытаюсь сделать, предполагается, что до завтра, 19-го, остался 1 день.

Другой пример: если я изменю 19-е число на 20-е, я хочу, чтобы с этого момента было написано "Через 2 дня".

Теперь, если я верну день, скажем, 15 мая (в прошлом), то оператор if будет говорить что-то вроде «Просрочено» или «прошлое».

Как я могу это решить?


person Samarey    schedule 18.05.2016    source источник
comment
Будьте осторожны с выражениями типа «через 2 дня», потому что их очень сложно локализовать. В некоторых языках неясно, к какой дате это относится.   -  person Andriy    schedule 04.06.2016


Ответы (2)


Было бы полезно, если бы вы думали о NSDate как о структуре, которая работает с количеством секунд от 2001 года. Это означает, что если вы выберете дату, она будет содержать дату и время. Все, что вам нужно сделать, чтобы рассчитать правильное количество дней между определенными датами, — это обрезать компонент времени.

Но если вам нужно только проверить, является ли указанная дата вчера, сегодня или завтра, NSCalendar имеет методы для этой цели:

Цель-С:

- (BOOL)isDateInToday:(NSDate *)date NS_AVAILABLE(10_9, 8_0);
- (BOOL)isDateInYesterday:(NSDate *)date NS_AVAILABLE(10_9, 8_0);
- (BOOL)isDateInTomorrow:(NSDate *)date NS_AVAILABLE(10_9, 8_0);

И Свифт:

@available(OSX 10.9, *)
public func isDateInYesterday(date: NSDate) -> Bool

@available(OSX 10.9, *)
public func isDateInTomorrow(date: NSDate) -> Bool

@available(OSX 10.9, *)
public func isDateInWeekend(date: NSDate) -> Bool
person Andriy    schedule 18.05.2016
comment
Доступны ли эти методы в Swift 2? - person Samarey; 18.05.2016

Например, вы можете использовать оператор switch для обработки различных случаев.

func computeDates(dueDate:NSDate) -> Int
{
  let difference = NSCalendar.currentCalendar().components(.Day, fromDate: NSDate(), toDate:dueDate , options:[])
  return difference.day
}

let dueDate = NSDate().dateByAddingTimeInterval(200000)
let day = computeDates(dueDate)

switch day {
case 2..<1000: print("In \(day) days")
case 1:  print("1 day left before tomorrow")
case 0 : print("today")
case -1 : print("1 day left after yesterday")
default: print("\(abs(day)) days left")
}
person vadian    schedule 18.05.2016