How to update date in fscalender initially while launching an app. i am updating the date while scrolling fscalender but my doubt initially loading app how to send date to Post service Call?
This is my api for getting dates from server.
let now2 = NSDate()
let dateFormatter2 = DateFormatter()
dateFormatter2.dateFormat = "yyyy"
let nameOfyear = dateFormatter2.string(from: now2 as Date)
print("nameOfyear",nameOfyear)
let urlString = Fetch_Parent_Dashboard_Calendar_URL+"&year="+nameOfyear+"&month="+nameOfMonth+"&branch_id=" + Userbranchid!
i am taking date value from user defaults sending to server when user scrolling fscalender.Following is the code for sending date to server when scrolling fscalender.
func calendar(_ calendar: FSCalendar, didSelect date: Date, at monthPosition: FSCalendarMonthPosition)
{
let dateFormatter2 = DateFormatter()
dateFormatter2.dateFormat = "dd/MM/yyyy"
let nameOfDate = dateFormatter2.string(from: date as Date)
print("nameOfDate",nameOfDate)
UserDefaults.standard.set(nameOfDate, forKey: "nameOfDate")
}
My doubt is initially loading the app i have to send current date and scrolling time have to send that user defaults time how to handle date at this case
If i understood correctly you have to do like this.
Make generic function to call web service with the given date
func callWebServiceWithDate(date:Date)
{
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy"
let nameOfyear = dateFormatter.string(from: date)
dateFormatter.dateFormat = "MM"
let nameOfMonth = dateFormatter.string(from: date)
let urlString = Fetch_Parent_Dashboard_Calendar_URL+"&year="+nameOfyear+"&month="+nameOfMonth+"&branch_id=" + Userbranchid!
}
Now call this method from viewDidLoad or viewWillAppear method with Date() as input parameter for initial call.
override func viewDidLoad()
{
super.viewDidLoad()
self.callWebServiceWithDate(date: Date())
}
And call the same method from FSCalendars delegate method
func calendar(_ calendar: FSCalendar, didSelect date: Date, at monthPosition: FSCalendarMonthPosition)
{
self.callWebServiceWithDate(date: date)
}
Related
I am using this code to add dots for events and the dots appear perfectly fine but when I select the day with the event, the dot permanently disappears and even when selecting another day, the dot still doesnt reappear.
here is my code to make the dots appear at the start
func calendar(_ calendar: FSCalendar, willDisplay cell: FSCalendarCell, for date: Date, at monthPosition: FSCalendarMonthPosition) {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
let dateString = dateFormatter.string(from: date)
cell.eventIndicator.isHidden = false
for wp in worriesPanic{
let wPDateStr = dateFormatter.string(from: wp.date!)
if wPDateStr == dateString {
cell.eventIndicator.numberOfEvents = 1
break
}
}
}
You can use image method for show event.
func calendar(_ calendar: FSCalendar, imageFor date: Date) -> UIImage? {
let dateString = self.dateFormatter1.string(from: date)
if self.yourDate.contains(dateString) {
return UIImage(named:"img")
}
return nil
}
I'm setting a date on my text field like so...
override func viewDidLoad() {
super.viewDidLoad()
showDatePicker()
}
func showDatePicker() {
datePickerStartDate.datePickerMode = .date
datePickerStartDate.addTarget(self, action: #selector(EventDetailViewController.startDatePickerSelect(sender:)), for: .valueChanged)
startDateTextfield.inputView = datePickerStartDate
}
#objc func startDatePickerSelect(sender: UIDatePicker) {
let formatter = DateFormatter()
formatter.dateStyle = .medium
startDateTextfield.text = formatter.string(from: sender.date)
}
This opens a datepicker on tap on the textfield and sets the date. But what I want is after I select the date, I want the time picker also to show up so that I can set the time also. And this time should get appended to the date that was set initially. How can I achieve that..?
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "hh:mm"
You can get the time of your choice from the string as :
let timeStr = "2:00"
var time = dateFormatter.dateFromString(timeStr)
Or you can add and subtract specific time from the current date as :
//It will give you the time by adding 5 minutes to the current time you can use (-5*60) to get the time 5 minute back.
var date = Date().addingTimeInterval(TimeInterval(5*60))
var timeStr = dateFormatter.string(from: date)
This function gets the tapped date when tapping the calendar date.
What I want to realize is, for example, when I tap 2018/11/1, I want to get the string "2018/11/01", but I do not know how to do it. Could you tell me?
func getDay(_ date:Date) -> (Int,Int,Int,String){
let tmpCalendar = Calendar(identifier: .gregorian)
let Component = tmpCalendar.component(.weekday, from: date)
let weekName = Component - 1
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "ja")
let year = tmpCalendar.component(.year, from: date)
let month = tmpCalendar.component(.month, from: date)
let day = tmpCalendar.component(.day, from: date)
return (year,month,day,formatter.shortWeekdaySymbols[weekName])
}
func calendar(_ calendar: FSCalendar, didSelect date: Date, at monthPosition: FSCalendarMonthPosition){
let selectDay = getDay(date)
let scheduleForDate = "\(String(selectDay.0))/\(String(selectDay.1))/\(String(selectDay.2))"
print(scheduleForDate)
getStartScheduleDate(date: scheduleForDate)
tableView.reloadData()
}
By the way, the library I am using is FSCalendar.
Use a DateFormatter set to the format you want.
let formatter = DateFormatter()
formatter.dateFormat = "yyyy/MM/dd"
let result = formatter.string(from: someDate)
But it's not a good idea to use such a format to show dates to a user. It's ambiguous. Is that November 1st or January 11th?
It's better to use a date style so the date is shown to the user in their own expected format given their locale.
let formatter = DateFormatter()
formatter.dateStyle = .short
let result = formatter.string(from: someDate)
Or at least localize the specific format:
let formatter = DateFormatter()
formatter.setLocalizedDateFormatFromTemplate("yyyyMMdd")
let result = formatter.string(from: someDate)
I have two datepickers that contains time with format 7:00 AM and 8:00 PM for login and logout. These times may vary. I wanted to change the logout time and tried to use the login time as the minimum time but my code does not work, I can still select time like 1:00 AM or 6:00 AM as logout.
This is the code in my ViewDidLoad
if let actualLoginText = loginTextField.text {
let start = actualLoginText
let formatter = DateFormatter()
formatter.dateStyle = .none
formatter.timeStyle = .short
formattedTime = formatter.date(from: start)!
}
And this is the code of my logout picker
#objc func timeOutPickerValueChanged(sender: UIDatePicker) {
let formatter = DateFormatter()
formatter.dateStyle = .none
formatter.timeStyle = .short
timeOutPicker.minimumDate = Calendar.current.date(byAdding: .minute, value: 5, to: formattedTime)
logoutTextField.text = formatter.string(from: sender.date)
}
I also tried this but still doesn't work
if let actualLoginText = loginTextField.text {
let start = actualLoginText
let formatter = DateFormatter()
formatter.dateFormat = "hh:mm a"
formattedTime = formatter.date(from: start)!
}
Thank you.
When working with dates / times, work with Date objects, not strings. The "string representation" should only be used to display the date/time to the user, not when manipulating the values.
Here is a simple example (assuming you have added two UIDatePickers and connected their Value Changed events). On load, it initializes the timeInPicker to the current date/time. Any time you select a new "Time In", the timeOutPicker.minimumDate is set to 5-minutes from the selected time, and the timeOutPicker.maximumDate is set to 8-hours from the minimum time:
class ViewController: UIViewController {
#IBOutlet weak var timeInPicker: UIDatePicker!
#IBOutlet weak var timeOutPicker: UIDatePicker!
let dateFormatter: DateFormatter = {
let df = DateFormatter()
df.dateStyle = .short
df.timeStyle = .short
return df
}()
override func viewDidLoad() {
super.viewDidLoad()
// Initialize the TimeIn and TimeOut pickers to the current Date/Time
let now = Date()
updateTimeOutPicker(now)
}
func updateTimeOutPicker(_ withStartDateTime: Date) -> Void {
// add 5 minutes to the selected "In" time to get the "minimum time" for the Out Picker
guard let minDateTime = Calendar(identifier: .gregorian).date(byAdding: .minute, value: 5, to: withStartDateTime) else { return }
// add 8 hours to the to get the "maximum time" for the Out Picker
guard let maxDateTime = Calendar(identifier: .gregorian).date(byAdding: .hour, value: 8, to: minDateTime) else { return }
timeOutPicker.minimumDate = minDateTime
timeOutPicker.maximumDate = maxDateTime
print("New Min Out Time:", dateFormatter.string(from: minDateTime))
print("New Max Out Time:", dateFormatter.string(from: maxDateTime))
print()
}
#IBAction func timeInPickerValueChanged(_ sender: UIDatePicker) {
print("Selected In Time:", dateFormatter.string(from: sender.date))
print()
updateTimeOutPicker(sender.date)
}
#IBAction func timeOutPickerValueChanged(_ sender: UIDatePicker) {
print("Selected Out Time:", dateFormatter.string(from: sender.date))
print()
}
}
The login and logout time strings were pulled up from database. And when I don't edit the login textfield it's data remains as string since there was no value change, so I'm forced to use a string value as reference to my logout picker.
the result login being: 1999-12-31 23:00:00 +0000
and logout: 2018-01-04 22:24:20 +0000
this is the reason why using the login as my minimum time didn't work
so here's what I did, I added the current date so I can use it.
#objc func timeOutPickerValueChanged(sender: UIDatePicker) {
if let actualLoginText = loginTextField.text {
let date = Date()
let start = actualLoginText
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
let nowTime = formatter.string(from: date)
let concat = nowTime + " " + start
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd hh:mm a"
formattedTime = dateFormatter.date(from: concat)!
}
let formatter = DateFormatter()
formatter.dateStyle = .none
formatter.timeStyle = .short
timeOutPicker.minimumDate = Calendar.current.date(byAdding: .minute, value: 5, to: formattedTime)
logoutTextField.text = formatter.string(from: sender.date)
}
I'm using fs calendar and i'm trying to set event dots from an array named dates. this array has event dates in it that are saved in string form. so i have to convert each index to date and then set an event dot for that date.
here is my attempt to do so:
if dates.isEmpty == false {
func calendar(_calendar: FSCalendar!, hasEventForDate dateFormatter: DateFormatter) -> Bool {
for i in 0...dates.count - 1 {
let dateFormatter = DateFormatter ()
dateFormatter.dateFormat = "yyyy/MM/dd"
dateFormatter.locale = Locale.init(identifier: "fa_IR")
dateFormatter.date(from: dates[i])
dateFormatter.dateFormat = "yyyy/MM/dd"
return true
}
return false
}
}
but nothing happens and there is no event dot when i compile the code. what am i doing wrong?
First recommendation, use a dictionary instead of array of dates, is less demanding to lookup dates in a dictionary
Second if you need use values in an array then you should use for in and use objects directly, not index to get objects in the original array, also declare the date formatter only once
Third you need use func calendar(_ calendar: FSCalendar, numberOfEventsFor date: Date) -> Int because func calendar(_calendar: FSCalendar!, hasEventForDate dateFormatter: DateFormatter) -> Bool is deprecated
Try with this code
func calendar(_ calendar: FSCalendar, numberOfEventsFor date: Date) -> Int {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy/MM/dd"
dateFormatter.locale = Locale.init(identifier: "fa_IR")
for dateStr in dates{
if(dateFormatter.string(from: date) == dateStr)
{
return 1
}
}
return 0
}