How to hide next day with FSCalendar based on week - swift

Hi I want to hide the next business day, if user registration date and current date both are same. I need to hide next working day.
Sunday and Saturday are holidays.
I write code following if user is register on Friday I need to hide Monday, how to resolve this problem.
I write like this how to hide businessday
func calendar(_ calendar: FSCalendar, shouldSelect date: Date, at monthPosition: FSCalendarMonthPosition) -> Bool {
let joingdate = "2019-01-30" //modeldata.joindate
let currentdate = date.toString(dateFormat: "yyyy-MM-dd")
let currentDate = date
let currentdayweek = date.toString(dateFormat: "EEEE")
if joingdate == currentdate
{
if currentdayweek == "Friday"{
let businessday = Calendar.current.date(byAdding: .day, value: 3, to: currentDate)
return false
}
else if currentdayweek == "Saturday"{
let businessday = Calendar.current.date(byAdding: .day, value: 2, to: currentDate)
return false
}
else if currentdayweek == "Sunday"{
let businessday = Calendar.current.date(byAdding: .day, value: 1, to: currentDate)
return false
}
else
{
let businessday = Calendar.current.date(byAdding: .day, value: 1, to: currentDate)
return false
}
}
}

func minimumDate(for calendar: FSCalendar) -> Date {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let myString = formatter.string(from: Date())
let yourDate = formatter.date(from: myString)
formatter.dateFormat = "yyyy-MM-dd"
let strCurrentDate = formatter.string(from: yourDate!)
var addDay = 0
if let model = modeldata{
if let joiningdate = "2019-01-31"
{
if strCurrentDate == joiningdate
{
addDay = 2
}
let currentdayweek = yourDate!.toString(dateFormat: "EEEE")
if currentdayweek == "Friday"{
addDay = 4
}
else if currentdayweek == "Saturday"{
addDay = 3
}
else if currentdayweek == "Sunday"{
addDay = 2
}
}
}
let tomorrow = Calendar.current.date(byAdding:
.day, // updated this params to add hours
value: addDay,
to: formatter.date(from: strCurrentDate)!)
return tomorrow!
}
}

Related

Convert string time into date swift

I have json from rest API :
{
"status": "ok",
"query": {
"format": "json",
"kota": "703",
"tanggal": "2017-02-07"
},
"jadwal": {
"status": "ok",
"data": {
"ashar": "15:26",
"dhuha": "06:21",
"dzuhur": "12:10",
"imsak": "04:28",
"isya": "19:31",
"maghrib": "18:20",
"subuh": "04:38",
"tanggal": "Selasa, 07 Feb 2017",
"terbit": "05:54"
}
}
}
I want convert jadwal -> data -> ashar and other into Date format
I have this code,
extension String {
func convertToDate() -> Date? {
let arr = self.split(separator: ":")
guard
let hour = Int(arr.first ?? ""),
let minute = Int(arr.last ?? "")
else { return nil }
let component = DateComponents(hour: hour, minute: minute)
var cal = Calendar.current
guard let timezone = TimeZone(identifier: "Asia/Jakarta") else { return nil }
cal.timeZone = timezone
let date = cal.date(from: component)
return date
}
}
But i get this result on my console debug
ashar: 0001-01-01 08:27:48 +0000
i expect for example on asr/ashar = 2021-01-12 15:26:00 for Indonesia Time, do you guys have advice or something?
You can create an extension for string that returns a full date object by passing only the time string as follows.
extension String {
func createDateObjectWithTime(format: String = "HH:mm") -> Date? {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = format
guard let dateObjectWithTime = dateFormatter.date(from: self) else { return nil }
let gregorian = Calendar(identifier: .gregorian)
let now = Date()
let components: Set<Calendar.Component> = [.year, .month, .day, .hour, .minute, .second]
var dateComponents = gregorian.dateComponents(components, from: now)
let calendar = Calendar.current
dateComponents.hour = calendar.component(.hour, from: dateObjectWithTime)
dateComponents.minute = calendar.component(.minute, from: dateObjectWithTime)
dateComponents.second = 0
return gregorian.date(from: dateComponents)
}
}
You can call the extension by:
let date = "15:26".createDateObjectWithTime()
Just get the current date and set hour and minute to the extracted values
extension String {
func convertToDate() -> Date? {
let arr = self.split(separator: ":")
guard
let hour = Int(arr.first ?? ""),
let minute = Int(arr.last ?? "")
else { return nil }
var cal = Calendar.current
guard let timezone = TimeZone(identifier: "Asia/Jakarta") else { return nil }
cal.timeZone = timezone
return cal.date(bySettingHour: hour, minute: minute, second: 0, of: Date())
}
}

Can't get the necessary date

I am trying to get the difference between dates in days. I have a problem translating dates to the desired format.
func daysBefore(_ date: String) -> Int {
let currentDate = Date()
let dateFormater = DateFormatter()
dateFormater.dateFormat = "dd.mm.YYYY"
guard let nextDate = dateFormater.date(from: date) else {
return 0
}
return currentDate.interval(ofComponent: .day, fromDate: nextDate)
}
extension Date {
func interval(ofComponent comp: Calendar.Component, fromDate date: Date) -> Int {
let currentCalendar = Calendar.current
guard let start = currentCalendar.ordinality(of: comp, in: .era, for: date) else { return 0 }
guard let end = currentCalendar.ordinality(of: comp, in: .era, for: self) else { return 0 }
return end - start
}
}
daysBefore("22.09.2019")
When I convert the date from String to Date in:
let currentDate = Date()
let dateFormater = DateFormatter()
dateFormater.dateFormat = "dd.mm.YYYY"
guard let nextDate = dateFormater.date(from: date) else {
return 0
}
I always get something like: 2018-12-22 21:09:00 +0000.
But expected(in example): 22.09.2019.

How to get all days in current week in swift

I am making an application where I need to get the day of the year for all days in the current week.
To achieve this, I am looking for a result similar to below (Today is Thursday the 23rd of March)
Monday = 79
Tuesday = 80
Wednesday = 81
Thursday = 82
Friday = 83
Saturday and Sunday can be included, however my application only needs weekdays rather then weekends. Today is day 82
To get the weekdays of the week, it is:
let calendar = Calendar.current
let today = calendar.startOfDay(for: Date())
let dayOfWeek = calendar.component(.weekday, from: today)
let dates = calendar.range(of: .weekday, in: .weekOfYear, for: today)!
.compactMap { calendar.date(byAdding: .day, value: $0 - dayOfWeek, to: today) }
.filter { !calendar.isDateInWeekend($0) }
To display that as “Thursday = 82”, it is:
let formatter = DateFormatter()
formatter.dateFormat = "eeee' = 'D"
for date in dates {
print(formatter.string(from: date))
}
Or
let strings = dates.map { formatter.string(from: $0) }
If you want it to consider firstWeekday (generally only a concern if you are no longer filtering weekends out of the results, hence no filter on isDateInWeekend, below):
let calendar = Calendar.current
let today = calendar.startOfDay(for: Date())
let todaysDayOfWeek = calendar.component(.weekday, from: today)
guard
let weekdaysRange = calendar.range(of: .weekday, in: .weekOfYear, for: today),
let index = weekdaysRange.firstIndex(of: calendar.firstWeekday)
else { return }
let weekdays = weekdaysRange[index...] + weekdaysRange[..<index].map { $0 + weekdaysRange.count }
let dates = weekdays.compactMap { calendar.date(byAdding: .day, value: $0 - todaysDayOfWeek, to: today) }
I had problems with adapting Rob's solution for when the week starts on Monday. This solution adapts to your calendar.firstWeekday setting.
var calendar = Calendar.autoupdatingCurrent
calendar.firstWeekday = 2 // Start on Monday (or 1 for Sunday)
let today = calendar.startOfDay(for: Date())
var week = [Date]()
if let weekInterval = calendar.dateInterval(of: .weekOfYear, for: today) {
for i in 0...6 {
if let day = calendar.date(byAdding: .day, value: i, to: weekInterval.start) {
week += [day]
}
}
}
return week
I made a small extension on Calendar, which might be helpful for anyone else looking for a more functional solution to this.
import Foundation
extension Calendar {
func intervalOfWeek(for date: Date) -> DateInterval? {
dateInterval(of: .weekOfYear, for: date)
}
func startOfWeek(for date: Date) -> Date? {
intervalOfWeek(for: date)?.start
}
func daysWithSameWeekOfYear(as date: Date) -> [Date] {
guard let startOfWeek = startOfWeek(for: date) else {
return []
}
return (0 ... 6).reduce(into: []) { result, daysToAdd in
result.append(Calendar.current.date(byAdding: .day, value: daysToAdd, to: startOfWeek))
}
.compactMap { $0 }
}
}
You could also use enumerateDates like this:
func getAllDaysOfTheCurrentWeek() -> [Date] {
var dates: [Date] = []
guard let dateInterval = Calendar.current.dateInterval(of: .weekOfYear,
for: Date()) else {
return dates
}
Calendar.current.enumerateDates(startingAfter: dateInterval.start,
matching: DateComponents(hour:0),
matchingPolicy: .nextTime) { date, _, stop in
guard let date = date else {
return
}
if date <= dateInterval.end {
dates.append(date)
} else {
stop = true
}
}
return dates
}

A method which returns an array of dates that are in between two dates - Swift 3

I'm trying to get an array of dates between the time stamp of one of my objects and 30 days into the future.
I've used the code below but i'm not getting the desired result and am having trouble trying to make a method described in the title. Any help would be great, thank you.
var dates = [Date]()
func fetchDays() {
let cal = Calendar.current
var dateComponents = DateComponents()
dateComponents.year = 2017
dateComponents.month = 2
dateComponents.day = 12
guard let startDate = cal.date(from: dateComponents) else {
return }
var start = cal.startOfDay(for: startDate)
for _ in 0 ... 30 {
guard let daysBetween = cal.date(byAdding: .day, value: 1, to: startDate) else { return }
start = daysBetween
dates.append(start)
}
}
You are adding 1 to the same start date so your array is filled with the same date over and over. Simply replace 1 with the loop index + 1.
for i in 0 ... 30 {
if let newDate = cal.date(byAdding: .day, value: i + 1, to: startDate) {
dates.append(newDate)
}
}
And you don't need the start variable.
Hi #Breezy to make it work you need only to change a little thing
change the value of to parameter for start like this:
for _ in 0 ... 30 {
guard let daysBetween = cal.date(byAdding: .day, value: 1, to: start) else { return }
start = daysBetween
dates.append(start)
}
Edited:
if you don't want to use 30 days you can add a month end then get the days between the 2 dates like this:
var dates = [Date]()
func fetchDays() {
let cal = Calendar.current
var dateComponents = DateComponents()
dateComponents.year = 2017
dateComponents.month = 2
dateComponents.day = 12
guard let startDate = cal.date(from: dateComponents) else {
return }
var start = cal.startOfDay(for: startDate)
guard let endDate = cal.date(byAdding: .month, value: 1, to: start) else { return }
guard let daysBetween = cal.dateComponents([.day], from: start, to: endDate).day else { return }
for _ in 0 ... daysBetween {
guard let newDate = cal.date(byAdding: .day, value: 1, to: start) else { return }
start = newDate
dates.append(newDate)
}
}

Get the first day of a month in swift

I'm looking for a way to get the first day of a month (in Swift).
I would like to know if it is a Monday, Tuesday etc... by returning the number corresponding.
I try many solution like getting a NSCalendar component .weekDay but no one work.
Example :
print(getTheFirstDate("2016-2-18"))
// Should return : 0 (because the first day of February 2016 is Monday).
Any help would be appreciate.
First you need to parse your date string, then you can use Calendar method dateComponents to get the calendar, year and month components from that date and create a new date from those components. Then you can extract the weekday date component from it:
Xcode 11.5 • Swift 5.2
extension Date {
var weekday: Int { Calendar.current.component(.weekday, from: self) }
var firstDayOfTheMonth: Date {
Calendar.current.dateComponents([.calendar, .year,.month], from: self).date!
}
}
extension String {
static var dateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
return formatter
}()
var date: Date? {
String.dateFormatter.date(from: self)
}
}
"2016-2-18".date?.firstDayOfTheMonth.weekday // 2 = Monday (Sunday-Saturday 1-7)
extension Date {
var startOfWeek: Date {
let gregorian = Calendar(identifier: .gregorian)
let sunday = gregorian.date(from: gregorian.dateComponents([.yearForWeekOfYear, .weekOfYear], from: self))
return gregorian.date(byAdding: .day, value: 1, to: sunday!)!
}
var endOfWeek: Date {
let gregorian = Calendar(identifier: .gregorian)
let sunday = gregorian.date(from: gregorian.dateComponents([.yearForWeekOfYear, .weekOfYear], from: self))
return gregorian.date(byAdding: .day, value: 7, to: sunday!)!
}
var startOfPreviousWeek: Date {
let gregorian = Calendar(identifier: .gregorian)
let sunday = gregorian.date(from: gregorian.dateComponents([.yearForWeekOfYear, .weekOfYear], from: self))
return gregorian.date(byAdding: .day, value: -6, to: sunday!)!
}
var endOfPreviousWeek: Date {
let gregorian = Calendar(identifier: .gregorian)
let sunday = gregorian.date(from: gregorian.dateComponents([.yearForWeekOfYear, .weekOfYear], from: self))
return gregorian.date(byAdding: .day, value: 0, to: sunday!)!
}
var startDateOfMonth: Date {
return Calendar.current.date(from: Calendar.current.dateComponents([.year, .month], from: Calendar.current.startOfDay(for: self)))!
}
var endDateOfMonth: Date {
return Calendar.current.date(byAdding: DateComponents(month: 1, day: -1), to: self.startDateOfMonth)!
}
var getPreviousMonthDate: Date {
return Calendar.current.date(byAdding: .month, value: -1, to: self)!
}
var startDateOfPreviousMonth: Date {
return getPreviousMonthDate.startDateOfMonth
}
var endOfPreviousMonth: Date {
return getPreviousMonthDate.endDateOfMonth
}
}
Well to get the corresponding number of the day of the week you can use:
var weekday = calendar!.component(NSCalendarUnit.Weekday, fromDate: yourNSDate)
var weekdayName = self.getDayOfWeek(weekday)
Then you can call this function I created to get the corresponding name of the day of the week based on the number passed in to getDayOfWeek()
func getDayOfWeek(weekday:Int) -> String {
if(weekday == 1) {
return "Sunday"
}
else if(weekday == 2) {
return "Monday"
}
else if(weekday == 3) {
return "Tuesday"
}
else if(weekday == 4) {
return "Wednesday"
}
else if(weekday == 5) {
return "Thursday"
}
else if(weekday == 6) {
return "Friday"
}
else {
return "Saturday"
}
}
And if you are using a String as a date to begin with you can change it into an NSDate like this:
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = /*place date format here*/
let date = dateFormatter.dateFromString(/*your_date_string*/)
I like Leo's answer, but in case you want to encapsulate the logic into a single function or don't want to use extensions.
func getDayOfWeekForFirstDayOfMonthFromDateString(dateString:String) -> String? {
let formatter = NSDateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
if let date = formatter.dateFromString(dateString) {
if let firstOfMonth = NSCalendar.currentCalendar().dateFromComponents(NSCalendar.currentCalendar().components([.Year, .Month], fromDate: date)) {
formatter.dateFormat = "EEEE"
return formatter.stringFromDate(firstOfMonth)
}
}
return nil
}
EDIT: Adjusted code to utilize Leo's great suggestion, and borrowed his more terse creation of the creation of the first of the month object. Thanks, Leo!