Усекать NSDate (время обнуления) - PullRequest
30 голосов
/ 15 ноября 2010

Я хочу создать новое NSDate с 0 часами , 0 минутами и 0 секундами для времени Исходная дата может быть любой случайной NSDate.

Есть ли способ достичь этого? Документация мне не помогла.


Пример

Иметь: 2010-10-30 10:14:13 GMT

Хотите: 2010-10-30 00:00:00 GMT

Ответы [ 6 ]

63 голосов
/ 15 ноября 2010
unsigned int flags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay;
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDateComponents* components = [calendar components:flags fromDate:date];
NSDate* dateOnly = [calendar dateFromComponents:components];

date - это дата, с которой вы хотите удалить время.

Это разделяет дату и время и создает новую дату со временем по умолчанию (00:00:00).

РЕДАКТИРОВАТЬ

Для учета часового пояса:

NSDate* dateOnly = [[calendar dateFromComponents:components] dateByAddingTimeInterval:[[NSTimeZone localTimeZone]secondsFromGMT]];
17 голосов
/ 15 ноября 2010

Используйте NSCalendar's rangeOfUnit:startDate:interval:forDate:. Этот код выберет дневную границу на основе текущего часового пояса. Если вы хотите определенный часовой пояс, вам нужно создать NSCalendar и правильно установить его часовой пояс.

- (NSDate*)boundaryForCalendarUnit:(NSCalendarUnit)calendarUnit
{
    NSDate *boundary;
    [[NSCalendar currentCalendar] rangeOfUnit:calendarUnit startDate:&boundary interval:NULL forDate:self];
    return boundary;
}

- (NSDate*)dayBoundary
{
    return [self boundaryForCalendarUnit:NSDayCalendarUnit];
}
4 голосов
/ 30 марта 2017

С помощью Swift 3 вы можете выбрать один из четырех следующих шаблонов для решения вашей проблемы.


# 1. Использование Calendar startOfDay(for:)

startOfDay(for:) имеет следующую декларацию:

func startOfDay(for date: Date) -> Date

Возвращает первый момент данного Date как Date.

Приведенный ниже код игровой площадки показывает, как использовать этот метод:

import Foundation

let date = Date()

// Get new date
let calendar = Calendar.current
let newDate = calendar.startOfDay(for: date)

// Format dates
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_UK")
dateFormatter.dateStyle = .short
dateFormatter.timeStyle = .long

let formattedDate = dateFormatter.string(from: date)
let formattedNewDate = dateFormatter.string(from: newDate)

// Print formatted dates
print(formattedDate) // Prints: 30/03/2017, 15:14:41 CEST
print(formattedNewDate) // Prints: 30/03/2017, 00:00:00 CEST

# 2. Использование Calendar date(bySettingHour:minute:second:of:matchingPolicy:repeatedTimePolicy:direction:)

date(bySettingHour:minute:second:of:matchingPolicy:repeatedTimePolicy:direction:) имеет следующую декларацию:

func date(bySettingHour hour: Int, minute: Int, second: Int, of date: Date, matchingPolicy: Calendar.MatchingPolicy = default, repeatedTimePolicy: Calendar.RepeatedTimePolicy = default, direction: Calendar.SearchDirection = default) -> Date?

Возвращает новое Date, представляющее дату, вычисленную путем установки часов, минут и секунд для данного времени в указанное Date.

Код игровой площадки ниже показывает, как использовать этот метод:

import Foundation

let date = Date()

// Get new date
let calendar = Calendar.current
let newDate = calendar.date(bySettingHour: 0, minute: 0, second: 0, of: date)

// Format dates
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_UK")
dateFormatter.dateStyle = .short
dateFormatter.timeStyle = .long

let formattedDate = dateFormatter.string(from: date)
let formattedNewDate = dateFormatter.string(from: newDate!)

// Print formatted dates
print(formattedDate) // Prints: 30/03/2017, 15:14:41 CEST
print(formattedNewDate) // Prints: 30/03/2017, 00:00:00 CEST

# 3. Использование Calendar dateComponents(_:from:) и date(from:) методов

dateComponents(_:from:) имеет следующую декларацию:

func dateComponents(_ components: Set<Calendar.Component>, from date: Date) -> DateComponents

Возвращает все компоненты даты даты, используя часовой пояс календаря.

date(from:) имеет следующую декларацию:

func date(from components: DateComponents) -> Date?

Возвращает дату, созданную из указанных компонентов.

Код Playground ниже показывает, как использовать эти методы:

import Foundation

let date = Date()

// Get new date
let calendar = Calendar.current
let components = calendar.dateComponents([.day, .month, .year], from: date)
let newDate = calendar.date(from: components)

// Format dates
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_UK")
dateFormatter.dateStyle = .short
dateFormatter.timeStyle = .long

let formattedDate = dateFormatter.string(from: date)
let formattedNewDate = dateFormatter.string(from: newDate!)

// Print formatted dates
print(formattedDate) // Prints: 30/03/2017, 15:14:41 CEST
print(formattedNewDate) // Prints: 30/03/2017, 00:00:00 CEST

# 4. Использование NSCalendar range(of:start:interval:for:)

range(of:start:interval:for:) имеет следующую декларацию:

func range(of unit: NSCalendar.Unit, start datep: AutoreleasingUnsafeMutablePointer<NSDate?>?, interval tip: UnsafeMutablePointer<TimeInterval>?, for date: Date) -> Bool

Возвращает по ссылке начальное время и продолжительность определенной календарной единицы, содержащей данную дату.

Код Playground ниже показывает, как использовать этот метод:

import Foundation

let date = Date()

// Get new date
let calendar = Calendar.current as NSCalendar
var newDate: NSDate?
calendar.range(of: .day, start: &newDate, interval: nil, for: date)

// Format dates
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_UK")
dateFormatter.dateStyle = .short
dateFormatter.timeStyle = .long

let formattedDate = dateFormatter.string(from: date)
let formattedNewDate = dateFormatter.string(from: newDate as! Date)

// Print formatted dates
print(formattedDate) // Prints: 30/03/2017, 15:14:41 CEST
print(formattedNewDate) // Prints: 30/03/2017, 00:00:00 CEST
2 голосов
/ 10 ноября 2016

Я знаю, что уже поздно, но сейчас есть лучшие методы: почему вы просто не используете

Swift 2

NSCalendar.currentCalendar().dateBySettingHour(0, minute: 0, second: 0, ofDate: yourDateToZeroOutTime, options: [])

Swift 3 будет что-то без префикса NS;)

1 голос
/ 07 октября 2016

Swift 3

extension Date {
    func trimTime() -> Date {
        var boundary = Date()
        var interval: TimeInterval = 0
        _ = Calendar.current.dateInterval(of: .day, start: &boundary, interval: &interval, for: self)

        return Date(timeInterval: TimeInterval(NSTimeZone.system.secondsFromGMT()), since: boundary)
    }
}
0 голосов
/ 15 ноября 2010

Я бы использовал метод description, чтобы получить данную дату в виде строки, затем изменил бы строку и создал бы вашу новую дату с помощью initWithString.

initWithString: Возвращает объект NSDate, инициализированный значением даты и времени, заданным данной строкой в ​​формате представления международной строки.

  • (id) initWithString: (NSString *) описание параметры описание Строка, которая задает значение даты и времени в международном формате представления строки - ГГГГ-ММ-ДД ЧЧ: ММ: СС ± ЧЧММ, где ± ЧЧММ - смещение часового пояса в часах и минутах от GMT (например, «2001 03-24 10:45:32 +0600 ”). Вы должны указать все поля строки формата, включая смещение часового пояса, которое должно иметь префикс плюс или минус. Возвращаемое значение Объект NSDate, инициализированный со значением даты и времени, заданным aString.
...