How to print name of the day of the week? - ios

Im trying to print out the name of the day of the week i.e Monday, Tuesday, Wednesday. I currently have this bit of code that does just that. I was wondering if there is a way to get rid of my switch statement and make this better. Thanks!
func getDayOfWeek(_ today: String) -> String? {
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)
switch weekDay {
case 1:
return "Sunday"
case 2:
return "Monday"
case 3:
return "Tuesday"
case 4:
return "Wednesday"
case 5:
return "Thursday"
case 6:
return "Friday"
case 7:
return "Saturday"
default:
return ""
}
}
getDayOfWeek("2018-3-5")
This prints out "Monday"

You are using the wrong date format. The correct format is "yyyy-M-d". Besides that you can use Calendar property weekdaySymbols which returns the weekday localized.
func getDayOfWeek(_ date: String) -> String? {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-M-d"
formatter.locale = Locale(identifier: "en_US_POSIX")
guard let todayDate = formatter.date(from: date) else { return nil }
let weekday = Calendar(identifier: .gregorian).component(.weekday, from: todayDate)
return Calendar.current.weekdaySymbols[weekday-1] // "Monday"
}
Another option is to use DateFormatter and set your dateFormat to "cccc" as you can see in this answer:
extension Formatter {
static let weekdayName: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "cccc"
return formatter
}()
static let customDate: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-M-d"
formatter.locale = Locale(identifier: "en_US_POSIX")
return formatter
}()
}
extension Date {
var weekdayName: String { Formatter.weekdayName.string(from: self) }
}
Using the extension above your function would look like this:
func getDayOfWeek(_ date: String) -> String? { Formatter.customDate.date(from: date)?.weekdayName }
Playground testing:
getDayOfWeek("2018-3-5") // Monday
Date().weekdayName // Thursday

Use this function:
func DayOfWeek(date: String) -> String?
{
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-M-d"
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
guard let _date = dateFormatter.date(from: date) else { return nil }
let weekday = Calendar(identifier: .gregorian).component(.weekday, from: _date)
return Calendar.current.weekdaySymbols[weekday-1]
}

Related

NSDate Extension not working

This is a piece of code that was working in earlier version of swift. It is now giving an error (Cannot convert value of type 'NSDate' to type 'NSDate.Date' in coercion)
extension NSDate {
struct Date {
static let formatterISO8601: DateFormatter = {
let formatter = DateFormatter()
formatter.calendar = NSCalendar(calendarIdentifier: NSCalendar.Identifier.ISO8601)! as Calendar
formatter.locale = NSLocale.current
formatter.timeZone = NSTimeZone(forSecondsFromGMT: 0) as TimeZone!
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssXXX"
return formatter
}()
}
var formattedISO8601: String { return Date.formatterISO8601.string(from: self as Date) }
}
Issue is that in Swift 3 there is already a structure define with named Date.
So what you can do is change your struct name to MyDate or something else and you all set to go.
Also it is better if you use new Date, Calendar and TimeZone instead of NSDate, NSCalendar and NSTimeZone.
Or make extension of Date like this way.
extension Date {
static let formatterISO8601: DateFormatter = {
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .iso8601)
formatter.locale = Locale.current
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssXXX"
return formatter
}()
var formattedISO8601: String { return Date.formatterISO8601.string(from: self) }
}
Extensions for both NSDate and Date.
extension Date {
static let formatterISO8601: DateFormatter = {
let formatter = DateFormatter()
formatter.calendar = NSCalendar(calendarIdentifier: NSCalendar.Identifier.ISO8601)! as Calendar
formatter.locale = NSLocale.current
formatter.timeZone = NSTimeZone(forSecondsFromGMT: 0) as TimeZone!
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssXXX"
return formatter
}()
func formattedISO8601() -> String {
return Date.formatterISO8601.string(from: self)
}
}
extension NSDate {
func formattedISO8601() -> String {
return Date.formatterISO8601.string(from: self as Date)
}
}
And use it like this ...
// NSDate
let nsdate = NSDate.init()
let formattedDate = nsdate.formattedISO8601()
// Date
let date = Date.init()
let formattedNsDate = date.formattedISO8601()
try this
extension Date {
static let formatterISO8601: DateFormatter = {
let formatter = DateFormatter()
formatter.calendar = NSCalendar(calendarIdentifier: NSCalendar.Identifier.ISO8601)! as Calendar
formatter.locale = NSLocale.current
formatter.timeZone = NSTimeZone(forSecondsFromGMT: 0) as TimeZone!
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssXXX"
return formatter
}()
var formattedISO8601: String { return Date.formatterISO8601.string(from: self)
}
}

Swift - Get next date

I am trying to write a function that takes a string (in the format "dd MM yyyy") and returns the day after the one given as a parameter.
For example:
let nextDay = getNextDay("31 12 2016")
print(nextDay)
Would print:
01 01 2017
Can someone show me how to do this? Thanks
Here is the code snippet that may help you.
//Call method like this
convertNextDate(dateString: "31 12 2016")
// Method is here
func convertNextDate(dateString : String){
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd MM yyyy"
let myDate = dateFormatter.date(from: dateString)!
let tomorrow = Calendar.current.date(byAdding: .day, value: 1, to: myDate)
let somedateString = dateFormatter.string(from: tomorrow!)
print("your next Date is \(somedateString)")
}
Another way is to create extension and here it is.
extension String {
func convertToNextDate(dateFormat: String) -> String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = dateFormat
let myDate = dateFormatter.date(from: self)!
let tomorrow = Calendar.current.date(byAdding: .day, value: 1, to: myDate)
return dateFormatter.string(from: tomorrow!)
}
}
Usage
print("31 12 2016".convertToNextDate(dateFormat: "dd MM yyyy"))
Note: You can use use your desired date-format just make sure it is appropriate.
class DateHelper
{
lazy var formatter:DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "dd MM yyyy"
return formatter
}()
lazy var dateComponents:DateComponents = {
var dateComp = DateComponents()
dateComp.day = 1
return dateComp
}()
func getNext(dateString:String) -> String?
{
if let date = self.formatter.date(from: dateString),
let nextDate = Calendar.current.date(byAdding: self.dateComponents, to: date)
{
return self.formatter.string(from: nextDate)
}
return nil
}
}
DateHelper().getNext(dateString: "31 12 2016")

How to declare a global variable?

This is a very simple question, I am getting the day of a week using a snippet
if let weekday = getDayOfWeek("2017-05-01") {
print(weekday)
} else {
print("bad input")
}
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
}
I need to create "weekday" as global variable can any one help.
What I did is:
class ViewController: UIViewController{
var weekday = NSInteger()
}
I am getting some error in snippet while declaring as above.
Declare currentWeekDay type to Int.
var weekday = Int()
Now access this instance property with if let.
if let weekday = getDayOfWeek("2017-05-01") {
//weekday has block scope and available only with in this if block
self.weekday = weekday
} else {
print("bad input")
}
Edit: Set timezone to get correct weekday
func getDayOfWeek(_ today:String) -> Int? {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
formatter.timeZone = TimeZone(abbreviation: "UTC")!
guard let todayDate = formatter.date(from: today) else { return nil }
let myCalendar = Calendar(identifier: .gregorian)
let weekDay = myCalendar.component(.weekday, from: todayDate)
return weekDay
}

Date picker shows a different date (1 day behined) from when picked

I have a UIDatePicker that is connected to a UILabel. I want the user to pick a birthday that is more than 18 years ago (age restriction). So I have this line to set the maximumDate value:
datePicker.maximumDate = NSCalendar.currentCalendar().dateByAddingUnit(.Year, value: -18, toDate: NSDate(), options: [])
This line however causes the picker to show a 1 day behind the selected date. for example if I choose September 27, 1956 on the picker the label shows September 26, 1956 I believe it has to do with NSDate() using a different timezone one that is behind my local timezone.
switch dequeueFrom[indexPath.row] {
case .Birthday:
if let pickedBday = pickedBday,
let bday = NSDate.dateFromISOString(pickedBday) {
(cell as! RegisterTextFieldCell).content(bday.longFormattedString())
}
// dateFromISOSString is declared in an extension.swift
class func dateFromComponents(components: NSDateComponents) -> NSDate? {
let calendar = NSCalendar(identifier: NSCalendarIdentifierGregorian)
return calendar?.dateFromComponents(components)
}
class func dateFromString(string: String) -> NSDate? {
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss-SSS"
if let stringDate = dateFormatter.dateFromString(string) {
return stringDate
} else {
return nil
}
}
func ISOStringFromDate() -> String {
let dateFormatter = NSDateFormatter()
dateFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS"
return dateFormatter.stringFromDate(self).stringByAppendingString("Z")
}
class func dateFromISOString(string: String) -> NSDate? {
let dateFormatter = NSDateFormatter()
dateFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
if let stringDate = dateFormatter.dateFromString(string) {
return stringDate
} else {
return nil
}
}
Any help with how I can make NSDate() be my local timezone so this one day behind issue can go away? Any help is greatly appreciated :)
The problem is in your method ISOStringFromDate because you are getting the local time and manually adding the Z (Z means UTC) to the string. Try like this when creating your iso8601:
extension NSDate {
var iso8601: String {
let dateFormatter = NSDateFormatter()
dateFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
dateFormatter.timeZone = NSTimeZone(forSecondsFromGMT: 0)
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
return dateFormatter.stringFromDate(self)
}
}
and your code should be:
pickedDate.iso8601 // to get your date iso8601 string

Get the name of the weekday on iOS

I compute the name of the day like this:
func loadDayName(forDate date: NSDate) -> String{
let myComponents = calendar.components(.Weekday, fromDate: date)
let weekDay = myComponents.weekday
switch weekDay {
case 1:
return "Sunday"
case 2:
return "Monday"
case 3:
return "Tuesday"
case 4:
return "Wednesday"
case 5:
return "Thursday"
case 6:
return "Friday"
case 7:
return "Saturday"
default:
return "Nada"
}
}
It is working fine but I was wondering if Swift comes with some libraries to do that automatically.
Use DateFormatter
Swift 4
let date = Date()
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "EEEE"
let dayInWeek = dateFormatter.string(from: date)
Swift3
let date = NSDate()
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "EEEE" // "EE" to get short style
let dayInWeek = dateFormatter.stringFromDate(date) // "Sunday"
Screenshot
If you want to get the array of day names you could use: weekdaySymbols in Calendar()
example:
let calendar = Calendar(identifier: .gregorian)
let days = calendar.weekdaySymbols
There's a new api since iOS 15.
#available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *)
extension FormatStyle where Self == Date.FormatStyle {
public static var dateTime: Date.FormatStyle { get }
}
You can now use:
Date().formatted(.dateTime.month(.wide)) // October
Date().formatted(.dateTime.year(.defaultDigits)) // 2022
Date().formatted(.dateTime.weekday(.wide)) // Thursday
Date().formatted(.dateTime.weekday(.abbreviated)) // Thu
Date().formatted(.dateTime.weekday(.narrow)) // T
and so on and so on
You can check also this DateFormatter
let dayNameFormatter: DateFormatter = {
let dateFormatter = DateFormatter()
dateFormatter.locale = .current
dateFormatter.calendar = .current
dateFormatter.dateFormat = "cccc"
return dateFormatter
}()
print(dayNameFormatter.string(from: Date())) Prints today's day name 🤪
c - stands for day of the week, good answer, official source

Resources