I am new to swift, Am using Fscalender in swift it's working fine, But I want add the Events to Fscalender, I can get events from Json
I Want Display the events in calender, I can try some of the code but its not working getting some errors pls help how to display events in calender
var EventsData = [Event]()
all events are stored Into Event
fileprivate lazy var dateFormatter2: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
return formatter
}()
inside Json
if let event_list = jsonData["events"] as? NSArray {
for i in 0 ..< event_list.count {
if let event = event_list[i] as? NSDictionary {
let data = event["date"]as?String
let newString = data?.replacingOccurrences(of: "/", with: "-")
print("new string data ",newString as Any)
self.compareDate(date: newString!)
self.EventsData.append(Event(
eventId: event["eventId"] as? String,
eventName:event["details"] as? String,
//eventDate: event["date"] as? String
eventDate: newString ))
}
}
}
Display the Events
func compareDate(date : String){
let date = date
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
let dateFromString : NSDate = dateFormatter.date(from: date)! as NSDate
===>> After this line showing Fatal error
dateFormatter.dateFormat = "yyyy-MM-dd"
let datenew = dateFormatter.string(from: dateFromString as Date)
print("datee",datenew)
}
func calendar(_ calendar: FSCalendar, willDisplay cell: FSCalendarCell, for date: Date, at position: FSCalendarMonthPosition) {
let dateFormatter3 = DateFormatter()
dateFormatter3.dateFormat = "yyyy-MM"
let dateString3 = dateFormatter3.string(from: date)
//print("datenew1",dateString3)
strcond = dateString3 as NSString
print("datenew1",strcond!)
}
func calendar(_ calendar: FSCalendar, numberOfEventsFor date: Date) -> Int {
let dateString = self.dateFormatter2.string(from: date)
for d in EventsData{
let date = d.eventDate
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
let dateFromString : NSDate = dateFormatter.date(from: date!)! as NSDate
dateFormatter.dateFormat = "yyyy-MM-dd"
let datenew = dateFormatter.string(from: dateFromString as Date)
if datenew.contains(dateString) {
return 1
}
}
return 0
}
func calendar(_ calendar: FSCalendar, appearance: FSCalendarAppearance, eventColorFor date: Date) -> UIColor? {
let dateString = self.dateFormatter2.string(from: date)
for d in EventsData{
let date = d.eventDate
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
let dateFromString : NSDate = dateFormatter.date(from: date!)! as NSDate
dateFormatter.dateFormat = "yyyy-MM-dd"
let datenew = dateFormatter.string(from: dateFromString as Date)
print("new calendar",dateString)
if datenew.contains(dateString) {
return UIColor.purple
}
}
return nil
}
func calendar(_ calendar: FSCalendar, didSelect date: Date, at monthPosition: FSCalendarMonthPosition) {
if monthPosition == .previous || monthPosition == .next {
calendar.setCurrentPage(date, animated: true)
print("title date",date)
}
}
how to show events in calendar ?
After some changes in my code it's working fine showing events in FsCalender
inside Json
if let event_list = jsonData["events"] as? NSArray {
for i in 0 ..< event_list.count {
if let event = event_list[i] as? NSDictionary {
self.EventsData.append(Event(
eventId: event["eventId"] as? String,
eventName:event["details"] as? String,
eventDate: event["date"] as? String
)
)
}
}
self.do_refresh()
}
func do_refresh()
{
DispatchQueue.main.async(execute: {
self.calender.reloadData()
return
})
}
Fscalender Implementation
func calendar(_ calendar: FSCalendar, willDisplay cell: FSCalendarCell, for date: Date, at position: FSCalendarMonthPosition) {
let dateFormatter3 = DateFormatter()
dateFormatter3.dateFormat = "yyyy-MM-dd"
let dateString3 = dateFormatter3.string(from: date)
strcond = dateString3 as NSString
}
func calendar(_ calendar: FSCalendar, numberOfEventsFor date: Date) -> Int {
let dateString = self.dateFormatter2.string(from: date)
print("this count first ",self.EventsData.count)
for d in EventsData{
let date = d.eventDate
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM-dd-yyyy"
let dateFromString : NSDate = dateFormatter.date(from: date!)! as NSDate
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
let datenew = dateFormatter.string(from: dateFromString as Date)
if datenew.contains(dateString) {
return 3
}
}
return 0
}
func calendar(_ calendar: FSCalendar, appearance: FSCalendarAppearance, eventColorFor date: Date) -> UIColor? {
let dateString = self.dateFormatter2.string(from: date)
for d in EventsData{
let date = d.eventDate
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM-dd-yyyy"
let dateFromString : NSDate = dateFormatter.date(from: date!)! as NSDate
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
let datenew = dateFormatter.string(from: dateFromString as Date)
if datenew.contains(dateString) {
return UIColor.init(red: 10, green: 200, blue: 399, alpha: 300)
}
}
return nil
}
Related
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]
}
How to display events on Fscalender?
This is my code to fetch events from api call.
func SetUpUIDashBoardCalenderdata()
{
APIManager.sharedInstance.FetchParentDashboardCalenderDataFromURL(){(dashBoardCalenderJson)-> Void in
let calenderVar = JSON(dashBoardCalenderJson)
print("calenderVar----",calenderVar)
let info = calenderVar["dates"].rawString()
let jsonData = info?.data(using: .utf8)!
let dictionary = try? JSONSerialization.jsonObject(with: jsonData!, options: []) as! Array<Any>
print("dictionary",dictionary)
}
}
You should implement FSCalendarDataSource protocol.
please take a look at my example :
let events = [Date]()
fileprivate lazy var dateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy/MM/dd"
return formatter
}()
func calendar(_ calendar: FSCalendar, numberOfEventsFor date: Date) -> Int {
let dayFormatted = dateFormatter.string(from: date)
var counter = 0
for event in events{
let day = dateFormatter.string(from: event)
if dayFormatted == day{
counter += 1
}
}
return counter
}
or shorter :
func calendar(_ calendar: FSCalendar, numberOfEventsFor date: Date) -> Int {
let dayFormatted = dateFormatter.string(from: date)
return events.filter({ dateFormatter.string(from: $0) == dayFormatted }).count
}
How Can I convert dates into string format?
I am getting dates between two dates ( From to end date). and I was using this below method
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 printing dates here
Dates.printDatesBetweenInterval(Dates.dateFromString("2017-10-02"), Dates.dateFromString("2017-10-9"))
result:
2017-10-02 2017-10-03 2017-10-04 2017-10-05 2017-10-06 2017-10-07 2017-10-08 2017-10-09
Now, I want pass this dates to String format to calendar (I am using FSCalendar lib into app). I want this format
example:
["2017-10-02", "2017-10-03", "2017-10-04", "2017-10-05", "2017-10-06", "2017-10-07", "2017-10-08", "2017-10-09"]
Can anyone guide me . Thanks
static func getDatesStringBetweenInterval(_ startDate: Date, _ endDate: Date)-> String {
var retval = "["
var startDate = startDate
let calendar = Calendar.current
let fmt = DateFormatter()
fmt.dateFormat = "yyyy-MM-dd"
while startDate <= endDate {
if startDate < endDate {
retval.append("\"\(fmt.string(from: startDate))\", ")
} else {
retval.append("\"\(fmt.string(from: startDate))\"")
}
startDate = calendar.date(byAdding: .day, value: 1, to: startDate)!
}
retval.append("]")
return retval
}
Usage:
let aDate = Dates.dateFromString("2017-01-01")
let bDate = Dates.dateFromString("2017-01-05")
let datesString = Dates.getDatesStringBetweenInterval(aDate, bDate)
print(datesString)
Return date string array from your function, like this:
class Dates {
static func printDatesBetweenInterval(_ startDate: Date, _ endDate: Date) -> [String] {
var startDate = startDate
let calendar = Calendar.current
let fmt = DateFormatter()
fmt.dateFormat = "yyyy-MM-dd"
var arrayDateString = [String]()
while startDate <= endDate {
let stringDate = fmt.string(from: startDate)
print("stringDate - \(stringDate)")
arrayDateString.append(stringDate)
startDate = calendar.date(byAdding: .day, value: 1, to: startDate)!
}
return arrayDateString
}
static func dateFromString(_ dateString: String) -> Date {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
return dateFormatter.date(from: dateString)!
}}
Now, print string array
let dateStringArray = Dates.printDatesBetweenInterval(Dates.dateFromString("2017-10-02"), Dates.dateFromString("2017-10-9"))
print("dateStringArray - \(dateStringArray)")
Edit:
Now, as you said, you've data in following format:
let dataArray = [
{ "hlddate": "07-Aug", "frmdt": "07-Aug-2017", "todt": "07-Aug-2017" },
{ "hlddate": "15-Aug", "frmdt": "15-Aug-2017", "todt": "15-Aug-2017" },
{ "hlddate": "10-Oct", "frmdt": "10-Oct-2017","todt": "31-Oct-2017" }
]
Try with following solution (Copy-paste, dataAray and class structure and see result):
class Dates {
static func dateFromString(dateString: String, webResponseDateFormat: String = "yyyy-MM-dd") -> Date? {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = webResponseDateFormat
return dateFormatter.date(from: dateString)
}}
static func printDatesBetweenInterval(startDate: Date, endDate: Date, requiredDateFormat: String = "yyyy-MM-dd") -> [String] {
var startDate = startDate
let calendar = Calendar.current
let fmt = DateFormatter()
fmt.dateFormat = requiredDateFormat
var arrayDateString = [String]()
while startDate <= endDate {
let stringDate = fmt.string(from: startDate)
print("stringDate - \(stringDate)")
arrayDateString.append(stringDate)
startDate = calendar.date(byAdding: .day, value: 1, to: startDate)!
}
return arrayDateString
}
if let stringDateArray = dataArray as? [[String : String]] {
for arrayElement in stringDateArray {
if let startDateString = arrayElement["frmdt"], let startDate = Dates.dateFromString(dateString: startDateString, webResponseDateFormat: "dd-MMM-yyyy"), let endDateString = arrayElement["todt"], let endDate = Dates.dateFromString(dateString: endDateString, webResponseDateFormat: "dd-MMM-yyyy") {
let dateStringArray = Dates.printDatesBetweenInterval(startDate: startDate, endDate: endDate, )
print("\n\n**\ndateStringArray - \(dateStringArray)")
}
}
}
Final Update
// Actual data structure
let dataArray = ["07-8-2017","08-08-2017","10-09-2017","20-10-2017",21-10-2017","23-10-2017", etc..]
Use above method and change data in server response section and getting result.
if let Streams = jsonDict["data"] as! [AnyObject]? {
for arrayElement in Streams {
if let startDateString = arrayElement["frmdt"] {
self.somedateFromString = self.convertStringToDate(string: startDateString as! String)
if let endDateString = arrayElement["todt"] {
self.somedateEndString = self.convertStringToDate(string: endDateString as! String)
}
self.presentdays = Dates.printDatesBetweenInterval(Dates.dateFromString(self.somedateFromString), Dates.dateFromString(self.somedateEndString))
self.totalHolidays.append(contentsOf: self.presentdays)
}
}
}
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)
}
}
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
}