I want to generate a new NSDate
with 0 hours, 0 minutes, and 0 seconds for time. The source date can be any random NSDate
.
Is there a way to achieve this? The documentation did not help me with this.
Example
Have: 2010-10-30 10:14:13 GMT
Want: 2010-10-30 00:00:00 GMT
unsigned int flags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay;
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDateComponents* components = [calendar components:flags fromDate:date];
NSDate* dateOnly = [calendar dateFromComponents:components];
date
is the date you want to remove the time from.
This separates the date and time and creates a new date with the default time (00:00:00).
EDIT
To take time zone into account:
NSDate* dateOnly = [[calendar dateFromComponents:components] dateByAddingTimeInterval:[[NSTimeZone localTimeZone]secondsFromGMT]];
Use NSCalendar's rangeOfUnit:startDate:interval:forDate:
. This code will choose the day boundary based on the current time zone. If you want a particular time zone, you need to create an NSCalendar and set its time zone appropriately.
- (NSDate*)boundaryForCalendarUnit:(NSCalendarUnit)calendarUnit
{
NSDate *boundary;
[[NSCalendar currentCalendar] rangeOfUnit:calendarUnit startDate:&boundary interval:NULL forDate:self];
return boundary;
}
- (NSDate*)dayBoundary
{
return [self boundaryForCalendarUnit:NSDayCalendarUnit];
}
With Swift 3, you can choose one of the four following patterns in order to solve your problem.
Calendar
startOfDay(for:)
startOfDay(for:)
has the following declaration:
func startOfDay(for date: Date) -> Date
Returns the first moment of a given
Date
, as aDate
.
The Playground code below shows how to use this method:
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
Calendar
date(bySettingHour:minute:second:of:matchingPolicy:repeatedTimePolicy:direction:)
date(bySettingHour:minute:second:of:matchingPolicy:repeatedTimePolicy:direction:)
has the following declaration:
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?
Returns a new
Date
representing the date calculated by setting hour, minute, and second to a given time on a specifiedDate
.
The Playground code below shows how to use this method:
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
Calendar
dateComponents(_:from:)
and date(from:)
methodsdateComponents(_:from:)
has the following declaration:
func dateComponents(_ components: Set<Calendar.Component>, from date: Date) -> DateComponents
Returns all the date components of a date, using the calendar time zone.
date(from:)
has the following declaration:
func date(from components: DateComponents) -> Date?
Returns a date created from the specified components.
The Playground code below shows how to use those methods:
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
NSCalendar
range(of:start:interval:for:)
range(of:start:interval:for:)
has the following declaration:
func range(of unit: NSCalendar.Unit, start datep: AutoreleasingUnsafeMutablePointer<NSDate?>?, interval tip: UnsafeMutablePointer<TimeInterval>?, for date: Date) -> Bool
Returns by reference the starting time and duration of a given calendar unit that contains a given date.
The Playground code below shows how to use this method:
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With