swift 3 how to get date for tomorrow and yesterday ( take care special case ) new month or new year]
You should use Calendar method date(byAdding component:)
to do your calendrical calculations using noon time. Doing so you don't need to worry about those special cases:
Swift 3 or Later
extension Date {
static var yesterday: Date { return Date().dayBefore }
static var tomorrow: Date { return Date().dayAfter }
var dayBefore: Date {
return Calendar.current.date(byAdding: .day, value: -1, to: noon)!
}
var dayAfter: Date {
return Calendar.current.date(byAdding: .day, value: 1, to: noon)!
}
var noon: Date {
return Calendar.current.date(bySettingHour: 12, minute: 0, second: 0, of: self)!
}
var month: Int {
return Calendar.current.component(.month, from: self)
}
var isLastDayOfMonth: Bool {
return dayAfter.month != month
}
}
Date.yesterday // "Oct 28, 2018 at 12:00 PM"
Date() // "Oct 29, 2018 at 11:01 AM"
Date.tomorrow // "Oct 30, 2018 at 12:00 PM"
Date.tomorrow.month // 10
Date().isLastDayOfMonth // false
In Swift, how to delete hours in a Date object?
First of all your method can be written without a date formatter
func dateSimplificator(with date: Date) -> Date {
return Calendar.current.startOfDay(for: date)
}
Second of all a date formatter considers the local time zone – which is clearly UTC+0100 in your case – but print
shows dates in UTC. 2020-09-03 00:00:00 +0100
and 2020-09-02 23:00:00 +0000
is the same moment in time.
Getting the difference between two Dates (months/days/hours/minutes/seconds) in Swift
Xcode 8.3 • Swift 3.1 or later
You can use Calendar to help you create an extension to do your date calculations as follow:
extension Date {
/// Returns the amount of years from another date
func years(from date: Date) -> Int {
return Calendar.current.dateComponents([.year], from: date, to: self).year ?? 0
}
/// Returns the amount of months from another date
func months(from date: Date) -> Int {
return Calendar.current.dateComponents([.month], from: date, to: self).month ?? 0
}
/// Returns the amount of weeks from another date
func weeks(from date: Date) -> Int {
return Calendar.current.dateComponents([.weekOfMonth], from: date, to: self).weekOfMonth ?? 0
}
/// Returns the amount of days from another date
func days(from date: Date) -> Int {
return Calendar.current.dateComponents([.day], from: date, to: self).day ?? 0
}
/// Returns the amount of hours from another date
func hours(from date: Date) -> Int {
return Calendar.current.dateComponents([.hour], from: date, to: self).hour ?? 0
}
/// Returns the amount of minutes from another date
func minutes(from date: Date) -> Int {
return Calendar.current.dateComponents([.minute], from: date, to: self).minute ?? 0
}
/// Returns the amount of seconds from another date
func seconds(from date: Date) -> Int {
return Calendar.current.dateComponents([.second], from: date, to: self).second ?? 0
}
/// Returns the a custom time interval description from another date
func offset(from date: Date) -> String {
if years(from: date) > 0 { return "\(years(from: date))y" }
if months(from: date) > 0 { return "\(months(from: date))M" }
if weeks(from: date) > 0 { return "\(weeks(from: date))w" }
if days(from: date) > 0 { return "\(days(from: date))d" }
if hours(from: date) > 0 { return "\(hours(from: date))h" }
if minutes(from: date) > 0 { return "\(minutes(from: date))m" }
if seconds(from: date) > 0 { return "\(seconds(from: date))s" }
return ""
}
}
Using Date Components Formatter
let dateComponentsFormatter = DateComponentsFormatter()
dateComponentsFormatter.allowedUnits = [.second, .minute, .hour, .day, .weekOfMonth, .month, .year]
dateComponentsFormatter.maximumUnitCount = 1
dateComponentsFormatter.unitsStyle = .full
dateComponentsFormatter.string(from: Date(), to: Date(timeIntervalSinceNow: 4000000)) // "1 month"
let date1 = DateComponents(calendar: .current, year: 2014, month: 11, day: 28, hour: 5, minute: 9).date!
let date2 = DateComponents(calendar: .current, year: 2015, month: 8, day: 28, hour: 5, minute: 9).date!
let years = date2.years(from: date1) // 0
let months = date2.months(from: date1) // 9
let weeks = date2.weeks(from: date1) // 39
let days = date2.days(from: date1) // 273
let hours = date2.hours(from: date1) // 6,553
let minutes = date2.minutes(from: date1) // 393,180
let seconds = date2.seconds(from: date1) // 23,590,800
let timeOffset = date2.offset(from: date1) // "9M"
let date3 = DateComponents(calendar: .current, year: 2014, month: 11, day: 28, hour: 5, minute: 9).date!
let date4 = DateComponents(calendar: .current, year: 2015, month: 11, day: 28, hour: 5, minute: 9).date!
let timeOffset2 = date4.offset(from: date3) // "1y"
let date5 = DateComponents(calendar: .current, year: 2017, month: 4, day: 28).date!
let now = Date()
let timeOffset3 = now.offset(from: date5) // "1w"
Swift - Create consecutive date arrays from array of dates
Let's assume your String
array is,
let arr = ["2020-09-07 00:00:00 +0000", "2020-09-14 00:00:00 +0000", "2020-09-15 00:00:00 +0000", "2020-09-16 00:00:00 +0000", "2020-09-23 00:00:00 +0000", "2020-10-12 00:00:00 +0000", "2020-10-13 00:00:00 +0000", "2020-10-14 00:00:00 +0000", "2020-10-15 00:00:00 +0000", "2020-10-16 00:00:00 +0000"]
1. Get dateArr
of type [Date]
using are
,
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss Z"
let dateArr = arr.compactMap { formatter.date(from: $0) }
2. Sort the dateArr
in ascending order,
let sortedDateArr = dateArr.sorted { $0.compare($1) == .orderedAscending }
3. You can now split up the sortedDateArr
like so,
var result = [[String]]()
var tempArr = [String]()
for (index, date) in sortedDateArr.enumerated() {
tempArr.append(formatter.string(from: date))
if index+1 < sortedDateArr.count {
if let days = Calendar.current.dateComponents([.day], from: date, to: sortedDateArr[index+1]).day, days > 1 {
result.append(tempArr)
tempArr = []
}
} else {
result.append(tempArr)
}
}
How can I set an NSDate object to midnight?
Your statement
The problem with the above method is that you can only set one unit of
time ...
is not correct. NSCalendarUnit
conforms to the RawOptionSetType
protocol which
inherits from BitwiseOperationsType
. This means that the options can be bitwise
combined with &
and |
.
In Swift 2 (Xcode 7) this was changed again to be
an OptionSetType
which offers a set-like interface, see
for example Error combining NSCalendarUnit with OR (pipe) in Swift 2.0.
Therefore the following compiles and works in iOS 7 and iOS 8:
let date = NSDate()
let cal = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
// Swift 1.2:
let components = cal.components(.CalendarUnitDay | .CalendarUnitMonth | .CalendarUnitYear, fromDate: date)
// Swift 2:
let components = cal.components([.Day , .Month, .Year ], fromDate: date)
let newDate = cal.dateFromComponents(components)
(Note that I have omitted the type annotations for the variables, the Swift compiler
infers the type automatically from the expression on the right hand side of
the assignments.)
Determining the start of the given day (midnight) can also done
with the rangeOfUnit()
method (iOS 7 and iOS 8):
let date = NSDate()
let cal = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
var newDate : NSDate?
// Swift 1.2:
cal.rangeOfUnit(.CalendarUnitDay, startDate: &newDate, interval: nil, forDate: date)
// Swift 2:
cal.rangeOfUnit(.Day, startDate: &newDate, interval: nil, forDate: date)
If your deployment target is iOS 8 then it is even simpler:
let date = NSDate()
let cal = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
let newDate = cal.startOfDayForDate(date)
Update for Swift 3 (Xcode 8):
let date = Date()
let cal = Calendar(identifier: .gregorian)
let newDate = cal.startOfDay(for: date)
Get day of week using NSDate
What you are looking for (if I understand the question correctly) is NSCalendarUnit.CalendarUnitWeekday
. The corresponding property of NSDateComponents
is weekday
.
Note also that your date format is wrong (the
full specification can be found here: http://unicode.org/reports/tr35/tr35-6.html).
The function can be simplified slightly, using automatic type inference, also you use variables a lot where constants are sufficient.
In addition, the function should return an optional which is nil
for an invalid input string.
Updated code for Swift 3 and later:
func getDayOfWeek(_ today:String) -> Int? {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
guard let todayDate = formatter.date(from: today) else { return nil }
let myCalendar = Calendar(identifier: .gregorian)
let weekDay = myCalendar.component(.weekday, from: todayDate)
return weekDay
}
Example:
if let weekday = getDayOfWeek("2014-08-27") {
print(weekday)
} else {
print("bad input")
}
Original answer for Swift 2:
func getDayOfWeek(today:String)->Int? {
let formatter = NSDateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
if let todayDate = formatter.dateFromString(today) {
let myCalendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
let myComponents = myCalendar.components(.Weekday, fromDate: todayDate)
let weekDay = myComponents.weekday
return weekDay
} else {
return nil
}
}
Swift How to convert Parse createdAt time to time ago?
You can use NSCalendar isDateInToday to check if createdAt date is in same day as today, and use isDateInYesterday to check if it was yesterday. Just add a conditional and return a custom string for those conditions, for all other conditions just let date components formatter take care of it for you.
extension Formatter {
static let time: DateFormatter = {
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .gregorian)
formatter.dateFormat = "h:mm a"
return formatter
}()
static let dateComponents: DateComponentsFormatter = {
let formatter = DateComponentsFormatter()
formatter.calendar = Calendar(identifier: .iso8601)
formatter.unitsStyle = .full
formatter.maximumUnitCount = 1
formatter.zeroFormattingBehavior = .default
formatter.allowsFractionalUnits = false
formatter.allowedUnits = [.year, .month, .weekOfMonth, .day, .hour, .minute, .second]
return formatter
}()
}
extension Date {
var time: String { return Formatter.time.string(from: self) }
var year: Int { return Calendar.autoupdatingCurrent.component(.year, from: self) }
var month: Int { return Calendar.autoupdatingCurrent.component(.month, from: self) }
var day: Int { return Calendar.autoupdatingCurrent.component(.day, from: self) }
var elapsedTime: String {
if timeIntervalSinceNow > -60.0 { return "Just Now" }
if isInToday { return "Today at \(time)" }
if isInYesterday { return "Yesterday at \(time)" }
return (Formatter.dateComponents.string(from: Date().timeIntervalSince(self)) ?? "") + " ago"
}
var isInToday: Bool {
return Calendar.autoupdatingCurrent.isDateInToday(self)
}
var isInYesterday: Bool {
return Calendar.autoupdatingCurrent.isDateInYesterday(self)
}
}
testing:
Calendar.autoupdatingCurrent.date(byAdding: .second, value: -59, to: Date())!
.elapsedTime // "Just Now"
Calendar.autoupdatingCurrent.date(byAdding: .minute, value: -1, to: Date())!
.elapsedTime // "Today at 5:03 PM"
Calendar.autoupdatingCurrent.date(byAdding: .hour, value: -1, to: Date())!
.elapsedTime // "Today at 4:04 PM"
Calendar.autoupdatingCurrent.date(byAdding: .day, value: -1, to: Date())!
.elapsedTime // "Yesterday at 5:02 PM"
Calendar.autoupdatingCurrent.date(byAdding: .weekOfYear, value: -1, to: Date())!
.elapsedTime // "1 week ago"
Calendar.autoupdatingCurrent.date(byAdding: .month, value: -2, to: Date())!
.elapsedTime // "2 months ago"
Calendar.autoupdatingCurrent.date(byAdding: .year, value: -1, to: Date())!
.elapsedTime // "1 year ago"
Related Topics
Accessing the Host App Code from the Xcode 7 UI Test Target
How to Implement "Drag Right to Dismiss" a View Controller That's in a Navigation Stack
Resignfirstresponder VS. Endediting for Keyboard Dismissal
Ios: Change the Height of Uisegmentedcontrol
How to Customize the Page Indicator in Uipageviewcontroller
How to Use Cocoapods with Playground
How to Add Live Camera Preview to Uiview
Uinavigationcontroller Without Navigation Bar
How to Solve "Error Running Pod Install" in Flutter on MAC
Google Analytics iOS Campaign Tracking and Url Builder
How to Add Headerview in Uicollectionview Like Uitableview's Tableheaderview
Change Order of Read Items with Voiceover
How to Get the Hour of the Day with Swift
Conflicting Return Type in Implementation of 'Supportedinterfaceorientations': - Warning
Variable Used Before Being Initialized in Function