How can I get The 3rd month names from Current month to Nov. Ex:-if the current month is Nov then I want the month names from Feb. Current month should be the running month.
Question: How to get 3rd month name from the current month?
Can someone please explain to me how to get month name. Any help would be greatly appreciated.
Thanks in advance.
You need to use the Calendar class, e.g.
var now = Date()
var calendar = Calendar.current
if let then = calendar.date(byAdding: .month, value: 3, to: now) {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "LLLL"
let monthName = dateFormatter.string(from: then)
print ("\(monthName)")
}
Just keep in mind how calenar arithmetics is handled: if you add "3 months" to let's say Nov 30th, 2019, then you'll get Feb-29th, 2020, although someone might expect March-01, 2020.
//set start & end date in correct format
let startDate = "September"
let strEndDate = "December"
//create date formatter
let formatter = DateFormatter()
formatter.dateFormat = "MMMM"
//convert string into date object
guard let startDate = formatter.date(from: startDate) else {
print("invalid start date")
return
}
//convert string into date object
guard let endDate = formatter.date(from: strEndDate) else {
print("invalid end date time")
return
}
//calculate the month from end date and that should not exceed the start date
for month in 1...6 {
if let dt = Calendar.current.date(byAdding: .month, value: -month, to: endDate) {
if dt.compare(startDate) == .orderedAscending {
break
}
print(formatter.string(from: dt!))
}
}
I have these two dates in string format:
let startDate = "2018-06-14"
let endDate = "2018-06-17"
I would like to format them together as such:
June 14-17, 2018
However, if the start and end date fall on different months it should be formatted like this:
June 29 - July 1, 2018
And if the start and end date fall on different years it should be formatted like this:
December 29, 2018 - January 1, 2019
Is there an easy way of doing this using Swift's native DateFormatter?
Is there a popular pod that can help with this?
What's the best practice to accomplish this formatting?
Here's my answer:
if let startDate = startDateString.toDate(withFormat: "yyyy-MM-dd"),
let endDate = endDateString.toDate(withFormat: "yyyy-MM-dd") {
let formatter = DateIntervalFormatter()
formatter.dateStyle = .long
formatter.timeStyle = .none
dateLabel.text = formatter.string(from: startDate, to: endDate)
}
And this extension:
extension String {
func toDate(withFormat format: String) -> Date? {
let formatter = DateFormatter()
formatter.dateFormat = format
formatter.locale = Locale(identifier: "en_US_POSIX")
return formatter.date(from: self)
}
}
I am getting two time stamps from server response. Like following
value = 1507824000; //2017-10-12 16:00:00 +0000
value2 = 1507939200; //2017-10-14 00:00:00 +0000
let startTimeStamp = dateTimeStampValues["value"] as! String
let endTimeStamp = dateTimeStampValues["value2"] as! String
let convertedDate = Double(startTimeStamp)
let convertedEndDate = Double(endTimeStamp)
var startdate = Date(timeIntervalSince1970: convertedDate!)
let enddate = Date(timeIntervalSince1970: convertedEndDate!)
self.showRange(between: startdate, and: enddate)
func showRange(between startDate: Date, and endDate: Date) {
guard startDate < endDate else { return }
let calendar = Calendar.current
let calendarEndDate = calendar.startOfDay(for: endDate)
var currentDate = calendar.startOfDay(for: startDate)
while(currentDate <= calendarEndDate) {
print(currentDate)
currentDate = Calendar.current.date(byAdding: .day, value: 1, to: currentDate)!
let dateString = currentDate.convertDateToString(withFormat: "MMM-dd-yyyy h:mm a")
self.totalDaysFromServerArray.append(dateString)
print("\(self.totalDaysFromServerArray)")
}
}
But, the out put is
self.totalDaysFromServerArray is ["Oct-13-2017 12:00 AM", "Oct-14-2017 12:00 AM", "Oct-15-2017 12:00 AM"]
but, it should print from
Oct-12-2017 to Oct-14-17
Can anyone suggest me, where its going wrong in my code, thanks.
If you will print your startdate and enddate directly(without converting in string) it will be print 2017-10-12 16:00:00 +0000 and 2017-10-14 00:00:00 +0000 respectively because it will be in UTC format. When you will convert that date to string then it will be in your local timezone! For example, If you are in india then your timezone will be GMT + 05:30 or UTC + 05:30, so it will add 05 : 30 hours in your date while converting to string.
So, there is nothing wrong in your code. Your result dates are in gmt + 05 : 30 time zone as you has converted them to string.
Now, If someone in UK do this then he/she will find it in their local timezone! I mean they will get output what you expect in your question because UK's timezone is UTC + 00 : 00 or GMT + 00 : 00
Now if you want to show your string value also in utc or any specific timezone OR if you want to prevent above scenario when you convert date to string then you can set specific timezone! then it will convert date to string in that timezone(see below example for that). But it is not proper way unless you hardly required it because normal behavior is that you shows date in local timezone to users.
For example,
let value = "1507824000" //2017-10-12 16:00:00 +0000
let value2 = "1507939200" //2017-10-14 00:00:00 +0000
let convertedDate = Double(value)
let convertedEndDate = Double(value2)
let startdate = Date(timeIntervalSince1970: convertedDate!)
let enddate = Date(timeIntervalSince1970: convertedEndDate!)
self.showRange(between: startdate, and: enddate)
and your function will be,
func showRange(between startDate: Date, and endDate: Date) {
guard startDate < endDate else { return }
let calendar = Calendar.current
let calendarEndDate = calendar.startOfDay(for: endDate)
var currentDate = calendar.startOfDay(for: startDate)
while(currentDate <= calendarEndDate) {
print(currentDate)
currentDate = Calendar.current.date(byAdding: .day, value: 1, to: currentDate)!
let df = DateFormatter.init()
df.dateFormat = "MMM-dd-yyyy h:mm a"
df.timeZone = TimeZone.init(abbreviation: "BST")
let dateString = df.string(from: currentDate)
totalDaysFromServerArray.append(dateString)
}
print("\(totalDaysFromServerArray)")
}
And your result will be,
Oct-12-2017 7:30 PM Oct-13-2017 7:30 PM Oct-14-2017 7:30 PM
Hope this will help!
I have an app in which I want to show some data when it's Saturday or Sunday.
Actually I have a segmented control and if I press one of my option (which will be the weekend) I want to check If it is Saturday or Sunday but only the first weekend.
This is what I've done for my first option in segmented control to take the current date
dateevent is a variable that I take to check if is the currentDate
currentDate is declared to be the currentDate
if dateevent.earlierDate(self.currentDate).isEqualToDate(self.currentDate){
if NSCalendar.currentCalendar().isDate(dateevent, equalToDate: self.currentDate, toUnitGranularity: .Day){
//Do something
}
}
First find the number of days to add to NSDateComponents weekday property and then You can use dateByAddingComponents(_:toDate:options:).
let today = NSDate()
let calendar = NSCalendar.currentCalendar()
let todayWeekday = calendar.component(.Weekday, fromDate: today)
let addWeekdays = 7 - todayWeekday // 7: Saturday number
var components = NSDateComponents()
components.weekday = addWeekdays
let nextSaturday = calendar.dateByAddingComponents(components, toDate: today, options: .MatchFirst)
From the Apple docs:
If the date does fall within a weekend, you can use the
rangeOfWeekendStartDate:interval:containingDate: method to determine
the start date of that weekend period. Otherwise, you can use the
nextWeekendStartDate:interval:options:afterDate: method to determine
the start date of the next or previous weekend.
extension for getting day of the week
func dayOfTheWeek() -> String? {
let dateFormatter = NSDateFormatter()
dateFormatter.locale = NSLocale(localeIdentifier: "en_US")
dateFormatter.dateFormat = "EEEE"
return dateFormatter.stringFromDate(self)
}
then you can just count how many days do yo need to weekend and add it to NSDate
NSDate().dateByAddingTimeInterval(60 * 60 * 24 * daysFromTodayToWeekend)
Swift 4 Solution
I have figured out according to my requirement, where I have find out dates for following.
1. Today
2. Tomorrow
3. This Week
4. This Weekend
5. Next Week
6. Next Weekend
So, I have created Date Extension to get Dates of Current Week and Next Week.
CODE
extension Date {
func getWeekDates() -> (thisWeek:[Date],nextWeek:[Date]) {
var tuple: (thisWeek:[Date],nextWeek:[Date])
var arrThisWeek: [Date] = []
for i in 0..<7 {
arrThisWeek.append(Calendar.current.date(byAdding: .day, value: i, to: startOfWeek)!)
}
var arrNextWeek: [Date] = []
for i in 1...7 {
arrNextWeek.append(Calendar.current.date(byAdding: .day, value: i, to: arrThisWeek.last!)!)
}
tuple = (thisWeek: arrThisWeek,nextWeek: arrNextWeek)
return tuple
}
var tomorrow: 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 startOfWeek: Date {
let gregorian = Calendar(identifier: .gregorian)
let sunday = gregorian.date(from: gregorian.dateComponents([.yearForWeekOfYear, .weekOfYear], from: self))
return gregorian.date(byAdding: .day, value: 1, to: sunday!)!
}
func toDate(format: String) -> String {
let formatter = DateFormatter()
formatter.dateFormat = format
return formatter.string(from: self)
}
}
USAGE:
let arrWeekDates = Date().getWeekDates() // Get dates of Current and Next week.
let dateFormat = "MMM dd" // Date format
let thisMon = arrWeekDates.thisWeek.first!.toDate(format: dateFormat)
let thisSat = arrWeekDates.thisWeek[arrWeekDates.thisWeek.count - 2].toDate(format: dateFormat)
let thisSun = arrWeekDates.thisWeek[arrWeekDates.thisWeek.count - 1].toDate(format: dateFormat)
let nextMon = arrWeekDates.nextWeek.first!.toDate(format: dateFormat)
let nextSat = arrWeekDates.nextWeek[arrWeekDates.nextWeek.count - 2].toDate(format: dateFormat)
let nextSun = arrWeekDates.nextWeek[arrWeekDates.nextWeek.count - 1].toDate(format: dateFormat)
print("Today: \(Date().toDate(format: dateFormat))") // Sep 26
print("Tomorrow: \(Date().tomorrow.toDate(format: dateFormat))") // Sep 27
print("This Week: \(thisMon) - \(thisSun)") // Sep 24 - Sep 30
print("This Weekend: \(thisSat) - \(thisSun)") // Sep 29 - Sep 30
print("Next Week: \(nextMon) - \(nextSun)") // Oct 01 - Oct 07
print("Next Weekend: \(nextSat) - \(nextSun)") // Oct 06 - Oct 07
You can modify Extension according to your need.
Thanks!
I use this implementation to get the next Saturday at specific time:
CODE (Swift 5):
func nextSaturday(atHour hour: Int, min: Int) -> Date {
let today = Date()
let daysToAdd = 7 - (Calendar.current.dateComponents([.weekday], from: today).weekday ?? 0 )
let nextSaturday = Calendar.current.date(byAdding: .day, value: daysToAdd, to: today)!
return Calendar.current.date(bySettingHour: hour, minute: min, second: 0, of: nextSaturday)!
}
How to use it:
nextSaturday(atHour: 10, min: 0)
I'm trying to get Monday's date of the current week. This is treated as the first day of the week in my table view.
I also need to get Sunday's of the current week. This is treated as the last day of the week in my table view.
Current attempt:
let date = NSDate()
let calendar = NSCalendar.currentCalendar()
calendar.firstWeekday = 1
//attempt to changefirstday
let dateFormatter = NSDateFormatter()
let theDateFormat = NSDateFormatterStyle.ShortStyle
let theTimeFormat = NSDateFormatterStyle.ShortStyle
dateFormatter.dateStyle = theDateFormat
dateFormatter.timeStyle = theTimeFormat
let currentDateComponents = calendar.components([.YearForWeekOfYear, .WeekOfYear ], fromDate: date)
let startOfWeek = calendar.dateFromComponents(currentDateComponents)
print("startOfWeek is \(startOfWeek)")
let stringDate = dateFormatter.stringFromDate(startOfWeek!)
print("string date is \(stringDate)") //This is returning Sunday's date
I wrote Date extensions to get Date for certain weekday and here is how easy it is to use with Swift 5,
Date.today() // Oct 15, 2019 at 9:21 AM
Date.today().next(.monday) // Oct 21, 2019 at 9:21 AM
Date.today().next(.sunday) // Oct 20, 2019 at 9:21 AM
Date.today().previous(.sunday) // Oct 13, 2019 at 9:21 AM
Date.today().previous(.monday) // Oct 14, 2019 at 9:21 AM
Date.today().previous(.thursday) // Oct 10, 2019 at 9:21 AM
Date.today().next(.thursday) // Oct 17, 2019 at 9:21 AM
Date.today().previous(.thursday,
considerToday: true) // Oct 10, 2019 at 9:21 AM
Date.today().next(.monday)
.next(.sunday)
.next(.thursday) // Oct 31, 2019 at 9:21 AM
And here is Date extension for that,
extension Date {
static func today() -> Date {
return Date()
}
func next(_ weekday: Weekday, considerToday: Bool = false) -> Date {
return get(.next,
weekday,
considerToday: considerToday)
}
func previous(_ weekday: Weekday, considerToday: Bool = false) -> Date {
return get(.previous,
weekday,
considerToday: considerToday)
}
func get(_ direction: SearchDirection,
_ weekDay: Weekday,
considerToday consider: Bool = false) -> Date {
let dayName = weekDay.rawValue
let weekdaysName = getWeekDaysInEnglish().map { $0.lowercased() }
assert(weekdaysName.contains(dayName), "weekday symbol should be in form \(weekdaysName)")
let searchWeekdayIndex = weekdaysName.firstIndex(of: dayName)! + 1
let calendar = Calendar(identifier: .gregorian)
if consider && calendar.component(.weekday, from: self) == searchWeekdayIndex {
return self
}
var nextDateComponent = calendar.dateComponents([.hour, .minute, .second], from: self)
nextDateComponent.weekday = searchWeekdayIndex
let date = calendar.nextDate(after: self,
matching: nextDateComponent,
matchingPolicy: .nextTime,
direction: direction.calendarSearchDirection)
return date!
}
}
// MARK: Helper methods
extension Date {
func getWeekDaysInEnglish() -> [String] {
var calendar = Calendar(identifier: .gregorian)
calendar.locale = Locale(identifier: "en_US_POSIX")
return calendar.weekdaySymbols
}
enum Weekday: String {
case monday, tuesday, wednesday, thursday, friday, saturday, sunday
}
enum SearchDirection {
case next
case previous
var calendarSearchDirection: Calendar.SearchDirection {
switch self {
case .next:
return .forward
case .previous:
return .backward
}
}
}
}
You can use calendar ISO8601 where the first weekday is Monday:
Swift 5.2 or later
extension Calendar {
static let iso8601 = Calendar(identifier: .iso8601)
static let iso8601UTC: Calendar = {
var calendar = Calendar(identifier: .iso8601)
calendar.timeZone = TimeZone(identifier: "UTC")!
return calendar
}()
}
let monday =
Calendar.iso8601.dateComponents([.calendar, .yearForWeekOfYear, .weekOfYear], from: Date()).date! // "Nov 9, 2020 at 12:00 AM"
print(monday.description(with: .current)) // "Monday, November 9, 2020 at 12:00:00 AM Brasilia Standard Time\n"
let mondayUTC =
Calendar.iso8601UTC.dateComponents([.calendar, .yearForWeekOfYear, .weekOfYear], from: Date()).date! // "Nov 8, 2020 at 9:00 PM" TimeZone -03:00
print(mondayUTC) // "2020-11-09 00:00:00 +0000\n"
Implemented as a Date computer property extension:
extension Date {
var mondayOfTheSameWeek: Date {
Calendar.iso8601.dateComponents([.calendar, .yearForWeekOfYear, .weekOfYear], from: self).date!
}
var mondayOfTheSameWeekAtUTC: Date {
Calendar.iso8601UTC.dateComponents([.calendar, .yearForWeekOfYear, .weekOfYear], from: self).date!
}
}
let mondayOfTheSameWeek = Date().mondayOfTheSameWeek // "Nov 9, 2020 at 12:00 AM"
print(mondayOfTheSameWeek.description(with: .current)) // "Monday, November 9, 2020 at 12:00:00 AM Brasilia Standard Time\n"
let mondayOfTheSameWeekAtUTC = Date().mondayOfTheSameWeekAtUTC // "Nov 8, 2020 at 9:00 PM"
print(mondayOfTheSameWeekAtUTC) // "2020-11-09 00:00:00 +0000\n"
Here's a simplified version of Sandeep's answer.
Usage:
Date().next(.monday)
Date().next(.monday, considerToday: true)
Date().next(.monday, direction: .backward)
Extension:
public func next(_ weekday: Weekday,
direction: Calendar.SearchDirection = .forward,
considerToday: Bool = false) -> Date
{
let calendar = Calendar(identifier: .gregorian)
let components = DateComponents(weekday: weekday.rawValue)
if considerToday &&
calendar.component(.weekday, from: self) == weekday.rawValue
{
return self
}
return calendar.nextDate(after: self,
matching: components,
matchingPolicy: .nextTime,
direction: direction)!
}
public enum Weekday: Int {
case sunday = 1, monday, tuesday, wednesday, thursday, friday, saturday
}
Here is the extension I created, first it finds sunday and then it adds one day
extension Date {
var startOfWeek: Date? {
let gregorian = Calendar(identifier: .gregorian)
guard let sunday = gregorian.date(from: gregorian.dateComponents([.yearForWeekOfYear, .weekOfYear], from: self)) else { return nil }
return gregorian.date(byAdding: .day, value: 1, to: sunday)
}
}
Try to use:
calendar.firstWeekday = 2
Edit
To be more specific: NSCalendar.currentCalendar() returns user calendar. According to docs:
The returned calendar is formed from the settings for the current user’s chosen system locale overlaid with any custom settings the user has specified in System Preferences.
If you want always Monday as first day, I think you should use:
let calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
calendar!.firstWeekday = 2
Swift 4 Solution
I have figured out according to my requirement, where I have find out dates for following.
1. Today
2. Tomorrow
3. This Week
4. This Weekend
5. Next Week
6. Next Weekend
So, I have created Date Extension to get Dates of Current Week and Next Week.
CODE
extension Date {
func getWeekDates() -> (thisWeek:[Date],nextWeek:[Date]) {
var tuple: (thisWeek:[Date],nextWeek:[Date])
var arrThisWeek: [Date] = []
for i in 0..<7 {
arrThisWeek.append(Calendar.current.date(byAdding: .day, value: i, to: startOfWeek)!)
}
var arrNextWeek: [Date] = []
for i in 1...7 {
arrNextWeek.append(Calendar.current.date(byAdding: .day, value: i, to: arrThisWeek.last!)!)
}
tuple = (thisWeek: arrThisWeek,nextWeek: arrNextWeek)
return tuple
}
var tomorrow: 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 startOfWeek: Date {
let gregorian = Calendar(identifier: .gregorian)
let sunday = gregorian.date(from: gregorian.dateComponents([.yearForWeekOfYear, .weekOfYear], from: self))
return gregorian.date(byAdding: .day, value: 1, to: sunday!)!
}
func toDate(format: String) -> String {
let formatter = DateFormatter()
formatter.dateFormat = format
return formatter.string(from: self)
}
}
USAGE:
let arrWeekDates = Date().getWeekDates() // Get dates of Current and Next week.
let dateFormat = "MMM dd" // Date format
let thisMon = arrWeekDates.thisWeek.first!.toDate(format: dateFormat)
let thisSat = arrWeekDates.thisWeek[arrWeekDates.thisWeek.count - 2].toDate(format: dateFormat)
let thisSun = arrWeekDates.thisWeek[arrWeekDates.thisWeek.count - 1].toDate(format: dateFormat)
let nextMon = arrWeekDates.nextWeek.first!.toDate(format: dateFormat)
let nextSat = arrWeekDates.nextWeek[arrWeekDates.nextWeek.count - 2].toDate(format: dateFormat)
let nextSun = arrWeekDates.nextWeek[arrWeekDates.nextWeek.count - 1].toDate(format: dateFormat)
print("Today: \(Date().toDate(format: dateFormat))") // Sep 26
print("Tomorrow: \(Date().tomorrow.toDate(format: dateFormat))") // Sep 27
print("This Week: \(thisMon) - \(thisSun)") // Sep 24 - Sep 30
print("This Weekend: \(thisSat) - \(thisSun)") // Sep 29 - Sep 30
print("Next Week: \(nextMon) - \(nextSun)") // Oct 01 - Oct 07
print("Next Weekend: \(nextSat) - \(nextSun)") // Oct 06 - Oct 07
You can modify Extension according to your need.
Thanks!
Addition to #Saneep answer
If you would like to get exact dateTime as per given/current date (lets say you wanted to convert Monday's dateTime -> 23-05-2016 12:00:00 to 23-05-2016 05:35:17) then try this:
func convertDate(date: NSDate, toGivendate: NSDate) -> NSDate {
let calendar = NSCalendar.currentCalendar()
let comp = calendar.components([.Year, .Month, .Day, .Hour, .Minute, .Second], fromDate: toGivendate)
let hour = comp.hour
let minute = comp.minute
let second = comp.second
let dateComp = calendar.components([.Year, .Month, .Day], fromDate: date)
let year = dateComp.year
let month = dateComp.month
let day = dateComp.day
let components = NSDateComponents()
components.year = year
components.month = month
components.day = day
components.hour = hour
components.minute = minute
components.second = second
let newConvertedDate = calendar.dateFromComponents(components)
return newConvertedDate!
}
simple code (remember to take better care of the optionals):
let now = Date()
var calendar = Calendar(identifier: .gregorian)
let timeZone = TimeZone(identifier: "UTC")!
let desiredWeekDay = 2
let weekDay = calendar.component(.weekday, from: now)
var weekDayDate = calendar.date(bySetting: .weekday, value: desiredWeekDay, of: now)!
/// Swift will give back the closest day matching the value above so we need to manipulate it to be always included at cuurent week.
if weekDayDate > now, weekDay > desiredWeekDay {
weekDayDate = weekDayDate - 7*24*60*60
}
print(weekDayDate)