NSDate returning wrong date in Swift - ios

Today is Feb 1 of 2016 and I just opened up my working app to continue my work and this shocks me.
It is a collection view of date, I didn't notice anything wrong during January because it hasn't been a month.
Here's the code,
func dF(someDate:NSDate) -> (String){
let monthFormat = NSDateFormatter()
let dayFormat = NSDateFormatter()
monthFormat.dateFormat = "MMM"
dayFormat.dateFormat = "D"
let aMonth = monthFormat.stringFromDate(someDate)
let aDay = dayFormat.stringFromDate(someDate)
//concatenate strings
let conString = aMonth + " " + aDay
return (conString)
}
//from today to 7th day, to be used in ScrollView
let day1 = NSCalendar.currentCalendar().dateByAddingUnit(.Day, value: 0, toDate: NSDate(), options: [])
let day2 = NSCalendar.currentCalendar().dateByAddingUnit(.Day, value: -1, toDate: NSDate(), options: [])
let day3 = NSCalendar.currentCalendar().dateByAddingUnit(.Day, value: -2, toDate: NSDate(), options: [])
let day4 = NSCalendar.currentCalendar().dateByAddingUnit(.Day, value: -3, toDate: NSDate(), options: [])
let day5 = NSCalendar.currentCalendar().dateByAddingUnit(.Day, value: -4, toDate: NSDate(), options: [])
let day6 = NSCalendar.currentCalendar().dateByAddingUnit(.Day, value: -5, toDate: NSDate(), options: [])
let day7 = NSCalendar.currentCalendar().dateByAddingUnit(.Day, value: -6, toDate: NSDate(), options: [])
let titles = [dF(day1!), dF(day2!), dF(day3!), dF(day4!), dF(day5!), dF(day6!), dF(day7!)]
I'm expecting day1 to pass the current date to function dF and format it.
So I ran some checks to make sure I've got the correct date
Current time: Feb 1, 2016, 1:08am in my time zone
print(day1)
print(day2)
print(ddd)
Here's the result from console:
Optional(2016-01-31 17:08:47 +0000)
Optional(2016-01-30 17:08:47 +0000)
Feb 32
I'm suspecting my NSDateComponent isn't setup correctly/on par with local time zone. Any ideas?

You are using the wrong specifier for the day of the month.
You are creating your date string the hardest way possible.
Try this:
Swift 3/4:
func dF(_ someDate: Date) -> String {
let format = DateFormatter()
format.dateFormat = "MMM d"
// For a more localized format, use the following instead:
// format.setLocalizedDateFormatFromTemplate("MMMd")
let conString = format.string(from: someDate)
return conString
}
Old Swift 2 answer:
func dF(someDate:NSDate) -> (String){
let format = NSDateFormatter()
format.dateFormat = "MMM d"
let conString = format.stringFromDate(someDate)
return (conString)
}

More Swifty way to solve your problem. Works with Swift 3 and above.
let date = Date()
let formatter = DateFormatter()
formatter.dateFormat = "MMM d"
let result = formatter.string(from: date)
Output
"May 12"

Related

How to set weekdays date in CollectionView starting from Monday to Saturday in swift

I have to show weekdays date in CollectionView start from Monday to Saturday. Until the end of the week, I have to show that weekdays date only. My task image Image. Please help/advise me how to do this task.
I am getting weekdays but its start from current day, But i need start date from monday,
func arrayOfDates() -> NSArray {
let numberOfDays: Int = 6
let formatter: DateFormatter = DateFormatter()
formatter.dateFormat = "dd"
let startDate = Date()
let calendar = Calendar.current
var offset = DateComponents()
var dates: [Any] = [formatter.string(from: startDate)]
for i in 1..<numberOfDays {
offset.day = i
let nextDay: Date? = calendar.date(byAdding: offset, to: startDate)
let nextDayString = formatter.string(from: nextDay!)
dates.append(nextDayString)
}
return dates as NSArray
}
Try this
func formattedDaysInThisWeekNet() -> [String]
{
// create calendar
let calendar = NSCalendar(identifier: NSCalendar.Identifier.gregorian)!
// today's date
let today = NSDate()
let weekday = calendar.component(.weekday, from: today as Date)
let beginningOfWeek : NSDate
if weekday != 2 { // if today is not Monday, get back
beginningOfWeek = calendar.nextDate(after: today as Date, matching: .weekday, value: 1, options: [.matchNextTime, .searchBackwards])! as NSDate
} else { // today is Monday
beginningOfWeek = calendar.startOfDay(for: today as Date) as NSDate
}
var formattedDays = [String]()
for i in 0..<7 {
let date = calendar.date(byAdding: .day, value: i, to: beginningOfWeek as Date, options: [])!
formattedDays.append(formatDate(date: date as NSDate))
let firstDate = calendar.date(byAdding: .day, value: 0, to: beginningOfWeek as Date, options: [])!
let lastDate = calendar.date(byAdding: .day, value: 6, to: beginningOfWeek as Date, options: [])!
let fullString = "\(formatDateFull(date: firstDate as NSDate)) - \(formatDateFull(date: lastDate as NSDate))" as String
fulldateLbl.text = "< \(fullString) >"
print(fullString)
}
return formattedDays
}
enum Days: Int {
case Sat = 0, Sun, Mon, Tue, Wed, Thu, Fri
static var all = [Mon, Tue, Wed, Thu, Fri, Sat]
}
func getWeekDays(date: Date) -> [Date] {
var weekDates = [Date]()
let cal = Calendar.current
var comps = cal.dateComponents([.weekOfYear, .yearForWeekOfYear], from: date)
let days = Days.all
for day in days {
comps.weekday = day.rawValue
weekDates.append(cal.date(from: comps)!)
}
return weekDates
}
print(getWeekDays(date: Date())) // print all dates from Monday to Saturday
Hi guys thank you for your response. I completed This task.
func arrayOfDates() -> NSArray {
var calendar = Calendar(identifier: Calendar.Identifier.gregorian)
let today = calendar.startOfDay(for: Date())
let dayOfWeek = calendar.component(.weekday, from: today) - calendar.firstWeekday
let weekdays = calendar.range(of: .weekday, in: .weekOfYear, for: today)!
let dayss = (weekdays.lowerBound ..< weekdays.upperBound)
.compactMap { calendar.date(byAdding: .day, value: $0 - dayOfWeek, to: today) }
//.filter { !calendar.isDateInWeekend($0) }
let formatter = DateFormatter()
formatter.dateFormat = "dd"
let strings = dayss.map { formatter.string(from: $0) }
self.dates = strings as NSArray
return dates as NSArray
}
But here I have one question, How to disable the previous dates. I need to select only current date and next dates.

How to fetch all dates between from Date to Date in Swift 3 [duplicate]

I’m creating a date using NSDateComponents().
let startDate = NSDateComponents()
startDate.year = 2015
startDate.month = 9
startDate.day = 1
let calendar = NSCalendar.currentCalendar()
let startDateNSDate = calendar.dateFromComponents(startDate)!
... now I want to print all dates since the startDate until today, NSDate(). I’ve already tried playing with NSCalendarUnit, but it only outputs the whole difference, not the single dates between.
let unit: NSCalendarUnit = [.Year, .Month, .Day, .Hour, .Minute, .Second]
let diff = NSCalendar.currentCalendar().components(unit, fromDate: startDateNSDate, toDate: NSDate(), options: [])
How can I print all dates between two Dateobjects?
Edit 2019
In the meantime the naming of the classes had changed – NSDate is now just Date. NSDateComponents is now called DateComponents. NSCalendar.currentCalendar() is now just Calendar.current.
Just add one day unit to the date until it reaches
the current date (Swift 2 code):
var date = startDateNSDate // first date
let endDate = NSDate() // last date
// Formatter for printing the date, adjust it according to your needs:
let fmt = NSDateFormatter()
fmt.dateFormat = "dd/MM/yyyy"
// While date <= endDate ...
while date.compare(endDate) != .OrderedDescending {
print(fmt.stringFromDate(date))
// Advance by one day:
date = calendar.dateByAddingUnit(.Day, value: 1, toDate: date, options: [])!
}
Update for Swift 3:
var date = startDate // first date
let endDate = Date() // last date
// Formatter for printing the date, adjust it according to your needs:
let fmt = DateFormatter()
fmt.dateFormat = "dd/MM/yyyy"
while date <= endDate {
print(fmt.string(from: date))
date = Calendar.current.date(byAdding: .day, value: 1, to: date)!
}
Using extension:
extension Date {
static func dates(from fromDate: Date, to toDate: Date) -> [Date] {
var dates: [Date] = []
var date = fromDate
while date <= toDate {
dates.append(date)
guard let newDate = Calendar.current.date(byAdding: .day, value: 1, to: date) else { break }
date = newDate
}
return dates
}
}
Usage:
let datesBetweenArray = Date.dates(from: Date(), to: Date())
Same thing but prettier:
extension Date {
func allDates(till endDate: Date) -> [Date] {
var date = self
var array: [Date] = []
while date <= endDate {
array.append(date)
date = Calendar.current.date(byAdding: .day, value: 1, to: date)!
}
return array
}
}
How to get all dates for next 20 days:
if let date = Calendar.current.date(byAdding: .day, value: 20, to: Date()) {
print(Date().allDates(till: date))
}
Your desired code becomes like
let startDate = NSDateComponents()
startDate.year = 2015
startDate.month = 9
startDate.day = 1
let calendar = NSCalendar.currentCalendar()
let startDateNSDate = calendar.dateFromComponents(startDate)!
var offsetComponents:NSDateComponents = NSDateComponents();
offsetComponents.day = 1
var nd:NSDate = startDateNSDate;
println(nd)
while nd.timeIntervalSince1970 < NSDate().timeIntervalSince1970 {
nd = calendar.dateByAddingComponents(offsetComponents, toDate: nd, options: nil)!;
println(nd)
}
Here is Solution of Print all dates between two Dates (Swift 4 Code)
var mydates : [String] = []
var dateFrom = Date() // First date
var dateTo = Date() // Last date
// Formatter for printing the date, adjust it according to your needs:
let fmt = DateFormatter()
fmt.dateFormat = "yyy-MM-dd"
dateFrom = fmt.date(from: strstartDate)! // "2018-03-01"
dateTo = fmt.date(from: strendDate)! // "2018-03-05"
while dateFrom <= dateTo {
mydates.append(fmt.string(from: dateFrom))
dateFrom = Calendar.current.date(byAdding: .day, value: 1, to: dateFrom)!
}
print(mydates) // Your Result
Output is:
["2018-03-01", "2018-03-02", "2018-03-03", "2018-03-04", "2018-03-05"]
I am using this approach (Swift 3):
import Foundation
class Dates {
static func printDatesBetweenInterval(_ startDate: Date, _ endDate: Date) {
var startDate = startDate
let calendar = Calendar.current
let fmt = DateFormatter()
fmt.dateFormat = "yyyy-MM-dd"
while startDate <= endDate {
print(fmt.string(from: startDate))
startDate = calendar.date(byAdding: .day, value: 1, to: startDate)!
}
}
static func dateFromString(_ dateString: String) -> Date {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
return dateFormatter.date(from: dateString)!
}
}
and I am calling this like:
Dates.printDatesBetweenInterval(Dates.dateFromString("2017-01-02"), Dates.dateFromString("2017-01-9"))
The output is:
2017-01-02
2017-01-03
2017-01-04
2017-01-05
2017-01-06
2017-01-07
2017-01-08
2017-01-09
You can use the compactMap operator.
I like to put these functions in an extension so they are reusable.
It's hard to make a range of dates, so I made a range of ints and loop through that.
extension Calendar {
func getDates(_ startDate: Date, _ endDate: Date) -> [Date] {
// make sure parameters are valid
guard startDate < endDate else { print("invalid parameters"); return [] }
// how many days between dates?
let dayDiff = Int(self.dateComponents([.day], from: startDate, to: endDate).day ?? 0)
let rangeOfDaysFromStart: Range<Int> = 0..<dayDiff + 1
let dates = rangeOfDaysFromStart.compactMap{ self.date(byAdding: .day, value: $0, to: startDate) }
return dates
}
}
Your usage could be:
let startDate = Date(dateString: "1/2/2017", format: "M/d/yyyy")
let endDate = Date(dateString: "1/9/2017", format: "M/d/yyyy")
let dates = Calendar.current.getDates(startDate, endDate)
let f = DateFormatter(withFormat: "yyyy-MM-dd", locale: "us_en")
print(dates.compactMap{f.string(from: $0)}.joined(separator: ", "))
output:
"2017-01-02, 2017-01-03, 2017-01-04, 2017-01-05, 2017-01-06, 2017-01-07, 2017-01-08, 2017-01-09"

Date not getting correctly using NSDate In Swift

I want to print date [1,2,3.... current date] but not getting correct result.
Because when I set first day is "1" in my code, the output in [2,3,4]. And when I set day is "0". It result show correct but show an extra date [1,2,3,4,5]. And today is 4th October 2016, as my time zone.
let date = NSDate()
let components = NSCalendar.currentCalendar().components([.Day , .Month , .Year], fromDate: date)
let year = components.year
let month = components.month
let day = 1 // Output is [2,3,4]
// let day = 0 than o/p [1,2,3,4,5]
dateFormatatter.dateFormat = "MMMM yyyy"
monthNameLabel.text = dateFormatatter.stringFromDate(date)
startDate.year = year
startDate.month = month
startDate.day = day
let startDateNSDate = calendar.dateFromComponents(startDate)!
var dateStart = startDateNSDate // first date
let endDate = NSDate() // last date
dateFormatatter.dateFormat = "dd"
while dateStart.compare(endDate) != .OrderedDescending {
// print(fmt.stringFromDate(date))
// Advance by one day:
dateStart = calendar.dateByAddingUnit(.Day, value: 1, toDate: dateStart, options: [])!
let dateFormat1 = NSDateFormatter()
dateFormat1.dateFormat = "dd-MM-yyyy"
dateArrayCalendar.addObject(dateFormatatter.stringFromDate(dateStart))
dateArrayForCompare.addObject(dateFormat1.stringFromDate(dateStart))
}
And I want result like this [1,2,3,4]
And Same issue Here
let componentsForCompare = calendar.components([.Year, .Month], fromDate: date)
let startOfMonth = calendar.dateFromComponents(componentsForCompare)!
print(startOfMonth)//2016-09-30 18:30:00 +0000
print(dateFormatatter.stringFromDate(startOfMonth)) //01
Its give different Outputs
You need to increment your date at the end of the while loop, rather than at the start:
while dateStart.compare(endDate) != .OrderedDescending {
// print(fmt.stringFromDate(date))
// Advance by one day:
let dateFormat1 = NSDateFormatter()
dateFormat1.dateFormat = "dd-MM-yyyy"
dateArrayCalendar.addObject(dateFormatatter.stringFromDate(dateStart))
dateArrayForCompare.addObject(dateFormat1.stringFromDate(dateStart))
dateStart = calendar.dateByAddingUnit(.Day, value: 1, toDate: dateStart, options: [])!
}

Date that is one year from another date

I'm trying to calculate the date that is a year from the current date:
let calendar = NSCalendar.currentCalendar()
let currDate = NSDate()
let newDate = calendar.dateBySettingUnit(.Year, value: 2017, ofDate: currDate, options: NSCalendarOptions(rawValue: 0))!
But newDate is always January 1, 2017.
You got it almost
let calendar = NSCalendar.currentCalendar()
let currDate = NSDate()
let newDate = calendar.dateByAddingUnit(.Year, value: 1, toDate: currDate, options: [])

How to get next 10 days from current date in swift

I have dateformat string like this "2015-03-09".How do i get next 10 days date from current date?any help will be appreciated.thanks in advance
For a purely Swift 3 solution:
Calendar.current.date(byAdding: .day, value: 10, to: Date())
Here's how to get a date 10 days from now, using built-in date modification method .dateByAddingUnit
If all 10 days (dates) are required, can be looped by "value:10" part and added to array.
var tenDaysfromNow: NSDate {
return NSCalendar.currentCalendar().dateByAddingUnit(.Day, value: 10, toDate: NSDate(), options: [])!
}
print(tenDaysfromNow)
And for Swift3:
var tenDaysfromNow: Date {
return (Calendar.current as NSCalendar).date(byAdding: .day, value: 10, to: Date(), options: [])!
}
You can use the dateByAddingTimeInterval() method for this.
var dateStr = "2015-03-09"
var formatter = NSDateFormatter()
formatter.dateFormat = "YYYY-MM-dd"
var currDate = formatter.dateFromString(dateStr)
for i in 1...10
{
var interval = NSTimeInterval(60 * 60 * 24 * i)
var newDate = currDate?.dateByAddingTimeInterval(interval)
println(newDate)
}
EDIT:
As mentioned by #Martin R in the comments, it'll be better to use dateByAddingComponents() of NSCalendar class:
var calendar = NSCalendar(calendarIdentifier: NSGregorianCalendar)
var dateComponent = NSDateComponents()
for i in 1...10
{
dateComponent.day = i
var newDate = calendar?.dateByAddingComponents(dateComponent, toDate: currDate!, options:nil)
println(newDate)
}
There is a function 'dateByAddingTimeInterval()' for an NSDate object. With this, you can create a NSDate from your date string. Then add 10 days = 10*24*60*60 to get next 10 days NSDate value
let today : NSDate = ....
let next10days = today.dateByAddingTimeInterval(10*60*60*24); //interval = seconds
//then you convert back to your date string format if you want, by using NSDateFormatter
To avoid problem with Daylighttime saving (#MartinR):
let cal = NSCalendar(calendarIdentifier: NSGregorianCalendar)
let next10Days = cal.dateByAddingUnit(NSCalendarUnit.DayCalendarUnit, value: 10, toDate: today, options: nil)
Here is a swift 4/5 version of the answer by #MidhunMP
var dateStr = "2015-03-09"
var formatter = DateFormatter()
formatter.dateFormat = "YYYY-MM-dd"
var calendar = Calendar(identifier: .gregorian)
var dateComponent = DateComponents()
if let currDate = formatter.date(from: dateStr) {
for i in 1...10 {
let newDate = calendar.date(byAdding: .day, value: i, to: currDate)
print(newDate)
}
}
For Swift 3:
let now = NSDate()
let plusTen = now.dateByAddingDays(10)

Resources