Swift Calendar class returning wrong date for weekday
Dates are always printed as if they are in the GMT timezone.
Suppose your time zone is UTC+1, then next Sunday will be 29-10-2017 00:00:00
in your time zone. However, this Date
instance is expressed as 28-10-2017 23:00:00
in GMT.
So nextDate
does return the correct date, it's just not formatted in your time zone. To fix this, just use a DateFormatter
:
let formatter = DateFormatter()
formatter.dateStyle = .short
print(formatter.string(from: next_sunday))
Most concise fix for .weekday returning wrong day
In iOS, the weekdaySymbols starts from Sunday to Saturday. It's an array so indexes range from 0 to 6
All you need to do is subtract the weekDay number by 1 to get the right day like below:
let weekDay = Calendar.current.component(.weekday, from: Date())
let currentDay = DateFormatter().weekdaySymbols[weekDay-1]
Also, note that when you try to fetch the weekDay number for Sunday from Calendar API it will return you 1
Please find the developer documentation snapshot for a reference
Wrong date from components
It's because the date components you are providing are contradictory. You have weekDay 1 (which will probably be a Sunday or Monday, depending on your locale) but the 1 jan 2022 is a Saturday.
(you also used Calendar.default
when I think you meant Calendar.current
?)
If you take out the weekDay
term you will get the correct answer:
Calendar.current.date(from: DateComponents(year: 2022, month: 1, hour: 16, minute: 1, second: 1, weekOfMonth: 1))
// "Jan 1, 2022 at 4:01 PM"
You could also remove the weekOfMonth
term as it is superfluous when you are specifying the actual date.
Date() shows wrong time
From Apple's documentation:
A Date is independent of a particular calendar or time zone. To
represent a Date to a user, you must interpret it in the context of a
Calendar.
You need the help of Calendar
:
let calendar = Calendar(identifier: .gregorian)
let currentDate = Date()
print(calendar.dateComponents(in: calendar.timeZone, from: currentDate))
the output will be:
calendar: gregorian (fixed) timeZone: Europe/Bratislava (current) era: 1 year: 2019
month: 11 day: 19 hour: 15 minute: 47 second: 14 nanosecond: 285109996 weekday: 3 weekdayOrdinal: 3 quarter: 0 weekOfMonth: 4 weekOfYear: 47 yearForWeekOfYear: 2019 isLeapMonth: false
So you could then access your calendar
's components like hour
, minute
etc.
UPDATE:
@Camile answered in comments to their question using DateFormatter
:
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss:Z"
dateFormatter.timeZone = calendar.timeZone
dateFormatter.string(from:currentDate)
will give you
2019-11-19 16:38:03:+0100
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
}
}
Get the next weekday of Date()
Change
let day = start.dayNumberOfWeek
To
let day = start.dayNumberOfWeek()
Or even better
if let day = start.dayNumberOfWeek() {
(There will still be compile errors, but that should be enough to get you moving again.)
why is Calendar.current.firstWeekday == 2?
which I interpret as
I believe your interpretation is wrong. I'm not sure how the framework assigns the days of the week, but from your question I believe that they go 1 through 7, where 1 is Sunday, 2 is Monday and so on. These are static and don't change with your settings.
The firstWeekday
property tells you what day of the week the week starts in your locale. In the US, which is the default locale, a week starts on Sunday.
You can't "fix this" because nothing is wrong, that property is there to provide you with information which is specially useful when drawing a calendar.
Swift - Get next date from a array of weekdays
Never use 86400
for date math, Calendar
and IndexSet
have powerful methods to do that:
// Put your weekday indexes in an `IndexSet`
let weekdaySet = IndexSet([1, 2, 4, 7]) // Sun, Mon, Wed and Sat
// Get the current calendar and the weekday from today
let calendar = Calendar.current
var weekday = calendar.component(.weekday, from: Date())
// Calculate the next index
if let nextWeekday = weekdaySet.integerGreaterThan(weekday) {
weekday = nextWeekday
} else {
weekday = weekdaySet.first!
}
// Get the next day matching this weekday
let components = DateComponents(weekday: weekday)
calendar.nextDate(after: Date(), matching: components, matchingPolicy: .nextTime)
Swift Calendar, Weekday starting on Monday instead Sunday
Create a custom Gregorian calendar and set the first weekday to Monday
var customCalendar = Calendar(identifier: .gregorian)
customCalendar.firstWeekday = 2
Related Topics
How to Bind My Array Controller to My Core Data Model
Decrypting Des with Commoncrypto in Swift 3
How to Get Alphabetic Tableview Sections from an Object
How to Get Section of UItableview from Inside a Child UIcollectionview
Place Multiple Scn Objects in Touchesbegan Method
It Is Posible to Load Customise HTML View into Webview in Swift
How Pass Data from Button in Tableviewcell to View Controller
Swift-Making an Sknode Simply "Move Forward" on an Angle
Skphysicscontact Not Detecting Categorybitmask Collision
How to Draw Something on a PDF in Swift
Sharing Screenshot of Swiftui View Causes Crash
Creating Decoration View as Custom Column in UIcollection View
Issue with Optional Core Data Relationship Using Nspersistentcloudkitcontainer
Struct Hash for Different Types
Swift Nsbundle Pathforresource() Returns Nil