Получить NSDate сегодня, вчера, на этой неделе, в последнюю неделю, в этом месяце, в прошлом месяце... переменные
Я пытаюсь сделать, чтобы получить NSDate сегодня, вчера, эту неделю, последнюю неделю, этот месяц, последние месячные переменные готовы для сравнения для заголовков, которые будут добавлены в UITableView titleForHeaderInSection
То, что я хочу, выполняется вручную в коде ниже для даты 2009-12-11
NSDate *today = [NSDate dateWithString:@"2009-12-11 00:00:00 +0000"];
NSDate *yesterday = [NSDate dateWithString:@"2009-12-10 00:00:00 +0000"];
NSDate *thisWeek = [NSDate dateWithString:@"2009-12-06 00:00:00 +0000"];
NSDate *lastWeek = [NSDate dateWithString:@"2009-11-30 00:00:00 +0000"];
NSDate *thisMonth = [NSDate dateWithString:@"2009-12-01 00:00:00 +0000"];
NSDate *lastMonth = [NSDate dateWithString:@"2009-11-01 00:00:00 +0000"];
Ответы
Ответ 1
Возможно, это лучший способ написать это, но вот что я придумал для предложения Ben NSCalendar и работаю оттуда в NSDateComponents.
NSCalendar *cal = [NSCalendar currentCalendar];
NSDateComponents *components = [cal components:( NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit ) fromDate:[[NSDate alloc] init]];
[components setHour:-[components hour]];
[components setMinute:-[components minute]];
[components setSecond:-[components second]];
NSDate *today = [cal dateByAddingComponents:components toDate:[[NSDate alloc] init] options:0]; //This variable should now be pointing at a date object that is the start of today (midnight);
[components setHour:-24];
[components setMinute:0];
[components setSecond:0];
NSDate *yesterday = [cal dateByAddingComponents:components toDate: today options:0];
components = [cal components:NSWeekdayCalendarUnit | NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:[[NSDate alloc] init]];
[components setDay:([components day] - ([components weekday] - 1))];
NSDate *thisWeek = [cal dateFromComponents:components];
[components setDay:([components day] - 7)];
NSDate *lastWeek = [cal dateFromComponents:components];
[components setDay:([components day] - ([components day] -1))];
NSDate *thisMonth = [cal dateFromComponents:components];
[components setMonth:([components month] - 1)];
NSDate *lastMonth = [cal dateFromComponents:components];
NSLog(@"today=%@",today);
NSLog(@"yesterday=%@",yesterday);
NSLog(@"thisWeek=%@",thisWeek);
NSLog(@"lastWeek=%@",lastWeek);
NSLog(@"thisMonth=%@",thisMonth);
NSLog(@"lastMonth=%@",lastMonth);
Ответ 2
Адаптировано из Руководство по программированию даты и времени:
// Right now, you can remove the seconds into the day if you want
NSDate *today = [NSDate date];
// All intervals taken from Google
NSDate *yesterday = [today dateByAddingTimeInterval: -86400.0];
NSDate *thisWeek = [today dateByAddingTimeInterval: -604800.0];
NSDate *lastWeek = [today dateByAddingTimeInterval: -1209600.0];
// To get the correct number of seconds in each month use NSCalendar
NSDate *thisMonth = [today dateByAddingTimeInterval: -2629743.83];
NSDate *lastMonth = [today dateByAddingTimeInterval: -5259487.66];
Если вам нужно точное точное количество дней в зависимости от месяца, вы должны использовать NSCalendar
.
Ответ 3
NSDateComponents приятно сегодня:
NSCalendar *cal = [NSCalendar currentCalendar];
NSDate *date = [NSDate date];
NSDateComponents *comps = [cal components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit)
fromDate:date];
NSDate *today = [cal dateFromComponents:comps];
Это создает NSDate с только годом, месяцем и датой:
(gdb) po today
2010-06-22 00:00:00 +0200
Чтобы получить вчера и т.д., вы можете рассчитать его с помощью NSDateComponents:
NSDateComponents *components = [[NSDateComponents alloc] init];
[components setDay:-1];
NSDate *yesterday = [cal dateByAddingComponents:components toDate:today options:0];
Ответ 4
+ (NSDate*)dateFor:(enum DateType)dateType {
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *comps =
[calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit
fromDate:[NSDate date]];
if(dateType == DateYesterday) {
comps.day--;
}
else if(dateType == DateThisWeek) {
comps.weekday = 1;
}
else if(dateType == DateLastWeek) {
comps.weekday = 1;
comps.week--;
}
else if(dateType == DateThisMonth) {
comps.day = 1;
}
else if(dateType == DateLastMonth) {
comps.day = 1;
comps.month--;
}
else if(dateType != DateToday)
return nil;
return [calendar dateFromComponents:comps];
}
Ответ 5
Swift 2
let today = NSDate()
let yesterday = today.dateByAddingTimeInterval(-86400.0)
let thisWeek = today.dateByAddingTimeInterval(-604800.0)
let lastWeek = today.dateByAddingTimeInterval(-1209600.0)
let thisMonth = today.dateByAddingTimeInterval(-2629743.83)
let lastMonth = today.dateByAddingTimeInterval(-5259487.66)
// components of the date
let calendar = NSCalendar(identifier: NSCalendarIdentifierGregorian)
let components = calendar.components([.Year, .Month, .Day], fromDate: today)
let (year, month, day) = (components.year, components.month, components.day)
Swift 3
let today = Date()
let yesterday = today.addingTimeInterval(-86400.0)
let thisWeek = today.addingTimeInterval(-604800.0)
let lastWeek = today.addingTimeInterval(-1209600.0)
let thisMonth = today.addingTimeInterval(-2629743.83)
let lastMonth = today.addingTimeInterval(-5259487.66)
// components of the date
var calendar = Calendar(identifier: Calendar.Identifier.gregorian)
let components = calendar.dateComponents([.year, .month, .day], from: today)
let (year, month, day) = (components.year, components.month, components.day)
В Swift 3 обратите внимание, что компоненты даты не являются обязательными.
Ответ 6
Другие ответы просто не помогли мне (возможно, из-за моего часового пояса). Вот как я это делаю:
- (BOOL)isOnThisWeek:(NSDate *)dateToCompare
{
NSCalendar * calendar = [NSCalendar currentCalendar];
NSDate * today = [NSDate date];
int todaysWeek = [[calendar components: NSWeekCalendarUnit fromDate:today] week];
int dateToCompareWeek = [[calendar components: NSWeekCalendarUnit fromDate:dateToCompare] week];
int todaysYear = [[calendar components:NSYearCalendarUnit fromDate:today] year];
int dateToCompareYear = [[calendar components:NSYearCalendarUnit fromDate:dateToCompare] year];
if (todaysWeek == dateToCompareWeek && todaysYear == dateToCompareYear) {
return YES;
}
return NO;
}
Ответ 7
Если вы используете iOS 10+ или MacOS 10.12+, вы можете использовать эти два метода Calendar
, чтобы сделать это правильно.
-
func date(byAdding component: Calendar.Component, value: Int, to date: Date, wrappingComponents: Bool = default) -> Date?
(docs)
-
func dateInterval(of component: Calendar.Component, for date: Date) -> DateInterval?
(docs)
Вот пример того, как использовать эти методы в Swift 3 вместе с игровыми площадками, выводимыми в моем часовом поясе.
let calendar = Calendar.current
let now = Date()
// => "Apr 28, 2017, 3:33 PM"
let yesterday = calendar.date(byAdding: .day, value: -1, to: now)
// => "Apr 29, 2017, 3:33 PM"
let yesterdayStartOfDay = calendar.startOfDay(for: yesterday!)
// => ""Apr 29, 2017, 12:00 AM"
let thisWeekInterval = calendar.dateInterval(of: .weekOfYear, for: now)
// => 2017-04-23 04:00:00 +0000 to 2017-04-30 04:00:00 +0000
let thisMonthInterval = calendar.dateInterval(of: .month, for: now)
// => 2017-04-01 04:00:00 +0000 to 2017-05-01 04:00:00 +0000
let aDateInLastWeek = calendar.date(byAdding: .weekOfYear, value: -1, to: now)
let lastWeekInterval = calendar.dateInterval(of: .weekOfYear, for: aDateInLastWeek!)
// => 2017-04-16 04:00:00 +0000 to 2017-04-23 04:00:00 +0000
let aDateInLastMonth = calendar.date(byAdding: .month, value: -1, to: now)
let lastMonthInterval = calendar.dateInterval(of: .weekOfYear, for: aDateInLastMonth!)
// => 2017-03-26 04:00:00 +0000 to 2017-04-02 04:00:00 +0000
Бонус: вы можете использовать DateInterval
для проверки того, попадает ли дата в этот диапазон. Продолжение сверху:
thisWeekInterval!.contains(now)
// => true
lastMonthInterval!.contains(now)
// => false
Ответ 8
NSDate *today = [NSDate date]; // Today date
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *weekdayComponents =[gregorian componentsNSDayCalendarUnit | NSWeekdayCalendarUnit) fromDate:today];
NSInteger day = [weekdayComponents day];
Ответ 9
Мне очень нравится объект THCalendarInfo, содержащийся в этом проекте:
http://github.com/jaredholdcroft/kcalendar
Я не могу найти оригинал. Используя этот объект, вы можете перейти к предыдущему дню, началу недели, началу месяца, получить день недели, день месяца... и т.д. И т.д.
Ответ 10
NSDate *today = [[NSDate alloc] initWithTimeIntervalSinceNow:0];
Ответ 11
Это для проверки даты в этом месяце или нет
func isOnThisMonth(dateToCompare: NSDate) -> Bool {
let calendar: NSCalendar = NSCalendar.currentCalendar()
let today: NSDate = NSDate()
let todaysWeek: Int = calendar.components(NSCalendarUnit.Month, fromDate: today).month
let dateToCompareWeek: Int = calendar.components(.Month, fromDate: dateToCompare).month
let todaysYear: Int = calendar.components(NSCalendarUnit.Year, fromDate: today).year
let dateToCompareYear: Int = calendar.components(NSCalendarUnit.Year, fromDate: dateToCompare).year
if todaysWeek == dateToCompareWeek && todaysYear == dateToCompareYear {
return true
}
return false
}
И во-вторых, только изменение типа calendarUnit для слабых, таких как
func isOnThisWeek(dateToCompare: NSDate) -> Bool {
let calendar: NSCalendar = NSCalendar.currentCalendar()
let today: NSDate = NSDate()
let todaysWeek: Int = calendar.components(NSCalendarUnit.Weekday, fromDate: today).weekday
let dateToCompareWeek: Int = calendar.components(.Weekday, fromDate: dateToCompare).weekday
let todaysYear: Int = calendar.components(NSCalendarUnit.Year, fromDate: today).year
let dateToCompareYear: Int = calendar.components(NSCalendarUnit.Year, fromDate: dateToCompare).year
if todaysWeek == dateToCompareWeek && todaysYear == dateToCompareYear {
return true
}
return false
}
Надеюсь, это поможет кому-то.
Ответ 12
Я ответил на аналогичный вопрос уже, и вот почему мой ответ лучше:
- Swift 3!
- Использует DateFormatter "Вчера" и "Сегодня". Это уже переведено Apple, что экономит вашу работу!
- Использует DateComponentsFormatter уже переведенную строку "1 week". (Снова меньше работы для вас, любезно предоставлено Apple.) Все, что вам нужно сделать, это перевести строку "% @назад". 🙂
- Другие ответы неверно вычисляют время, когда день переключается с "сегодня" на "вчера" на и т.д. Исправленные константы - это большие NO-NO, потому что причины. Кроме того, другие ответы используют текущую дату/время, когда они должны использовать дату даты текущего дня.
- Использует autoupdatingCurrent для Calendar и Locale, который гарантирует, что ваше приложение сразу обновляется с помощью пользовательского календаря и языковых настроек в Settings.app