End Date showing Wrong - iphone

I want to find start date and end date of week I am geting start date but not find right end date of week
startDate = NSDate().startOfWeek(2)
print(startDate)
endDate = startDate.endOfWeek(3)
print(endDate)
I am getting this start date -2016-07-04 06:30:00 +0000 and end date - 5828963-12-20 00:00:00 +0000
extension NSDate {
func startOfWeek(weekday: Int?) -> NSDate? {
guard
let cal: NSCalendar = NSCalendar.currentCalendar(),
let comp: NSDateComponents = cal.components([.YearForWeekOfYear, .WeekOfYear], fromDate: self) else { return nil }
comp.to12pm()
cal.firstWeekday = weekday ?? 1
return cal.dateFromComponents(comp)!
}
func endOfWeek(weekday: Int) -> NSDate? {
guard
let cal: NSCalendar = NSCalendar.currentCalendar(),
let comp: NSDateComponents = cal.components([.WeekOfYear], fromDate: self) else { return nil }
comp.weekOfYear = 1
comp.day -= 1
comp.to12pm()
return cal.dateByAddingComponents(comp, toDate: self.startOfWeek(weekday)!, options: [])!
}
}
internal extension NSDateComponents {
func to12pm() {
self.hour = 12
self.minute = 0
self.second = 0
}
}

extension Date {
enum Weekday: Int {
case sunday = 1, monday, tuesday, wednesday, thursday, friday, saturday
}
func startOfWeek(_ firstWeekday: Weekday = .sunday) -> Date? {
var cal = Calendar.current
var dateComponents = cal.dateComponents([.yearForWeekOfYear, .weekOfYear], from: self)
dateComponents.setTimeComponentsToNoon()
cal.firstWeekday = firstWeekday.rawValue
return cal.date(from: dateComponents)
}
func endOfWeek(_ firstWeekday: Weekday = .sunday) -> Date? {
guard let startOfWeek = startOfWeek(firstWeekday) else { return nil }
var dateComponents = DateComponents()
dateComponents.weekOfYear = 1
dateComponents.day = -1
return Calendar.current.date(byAdding: dateComponents, to: startOfWeek)
}
}
extension DateComponents {
mutating func setTimeComponentsToNoon() {
self.hour = 12
self.minute = 0
self.second = 0
self.nanosecond = 0
}
}
Testing:
if let startDate = Date().startOfWeek(.monday),
let endDate = Date().endOfWeek(.monday) {
print(startDate) // "2020-02-03 15:00:00 +0000\n"
print(endDate) // "2020-02-09 15:00:00 +0000\n"
}
if let startDate = Date().startOfWeek(),
let endDate = Date().endOfWeek() {
print(startDate) // "2020-02-02 15:00:00 +0000\n"
print(endDate) // "2020-02-08 15:00:00 +0000\n"
}

Related

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 hide next day with FSCalendar based on week

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!
}
}

How to get day and month from Date type - swift 4

I have variable with data type Date, where I have stored date in this format
2018-12-24 18:00:00 UTC
How can I get from this day or month?
Details
Xcode Version 11.0 (11A420a), Swift 5
Links
How to convert string to Date
Solution
extension Date {
func get(_ components: Calendar.Component..., calendar: Calendar = Calendar.current) -> DateComponents {
return calendar.dateComponents(Set(components), from: self)
}
func get(_ component: Calendar.Component, calendar: Calendar = Calendar.current) -> Int {
return calendar.component(component, from: self)
}
}
Usage
let date = Date()
// MARK: Way 1
let components = date.get(.day, .month, .year)
if let day = components.day, let month = components.month, let year = components.year {
print("day: \(day), month: \(month), year: \(year)")
}
// MARK: Way 2
print("day: \(date.get(.day)), month: \(date.get(.month)), year: \(date.get(.year))")
Is that String or Date type?
if it is date you can do so:
let calendarDate = Calendar.current.dateComponents([.day, .year, .month], from: date)
that will give you the day, year and month
If you saved "2018-12-24 18:00:00 UTC" as a String, you can try this:
let dateString = "2018-12-24 18:00:00 UTC"
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss 'UTC'"
guard let date = formatter.date(from: dateString) else {
return
}
formatter.dateFormat = "yyyy"
let year = formatter.string(from: date)
formatter.dateFormat = "MM"
let month = formatter.string(from: date)
formatter.dateFormat = "dd"
let day = formatter.string(from: date)
print(year, month, day) // 2018 12 24
Best Wishes!
The date string is not ISO8601 compliant, nevertheless you can use ISO8601DateFormatter if you replace <space> + UTC with Z and use custom format options.
Create a Date from the string and get the DateComponents for day and month
let string = "2018-12-24 18:00:00 UTC"
let formatter = ISO8601DateFormatter()
let trimmedString = string.replacingOccurrences(of: "\\s?UTC", with: "Z", options: .regularExpression)
formatter.formatOptions = [.withFullDate, .withFullTime, .withSpaceBetweenDateAndTime]
if let date = formatter.date(from: trimmedString) {
let components = Calendar.current.dateComponents([.day, .month], from: date)
let day = components.day!
let month = components.month!
print(day, month)
}
This is how I did in swift 4. I have a Billing class with "billDate" a field that contains the date.
extension Billing:Identifiable{
func month() -> String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MMM"
if let inputDate = billDate {
let month = dateFormatter.string(from: inputDate)
return month.uppercased()
}
return ""
}
Extention Date All Time RETURN String:
extension Date {
func dateDistance(_ startDate: Date = Date()) -> String {
var remainingTime = ""
let dateValue = Calendar.current.dateComponents([.year,.month,.weekOfMonth,.day,.hour,.minute,.second], from: startDate, to: self)
remainingTime = String(format: "%2d Y - %2d M - %2d W - %2d D\n%02d:%02d:%02d",
dateValue.year ?? 0,
dateValue.month ?? 0,
dateValue.weekOfMonth ?? 0,
dateValue.day ?? 0,
dateValue.hour ?? 0,
dateValue.minute ?? 0,
dateValue.second ?? 0
)
return remainingTime
}
}
extension Date {
func getRemainingDayMonthYear (_ startDate: Date = Date()) -> String
{
var remainingTime = ""
let dateValue = Calendar.current.dateComponents([.year,.month,.weekOfMonth,.day,.hour,.minute,.second], from: startDate, to: self)
if dateValue.year ?? 0 > 0 {
remainingTime = dateValue.year ?? 0 > 1 ? String(format: "%2d Years",dateValue.year ?? 0) : String(format: "%2d Year",dateValue.year ?? 0)
} else if dateValue.month ?? 0 > 0 {
remainingTime = dateValue.month ?? 0 > 1 ? String(format: "%2d Months",dateValue.month ?? 0) : String(format: "%2d Month",dateValue.month ?? 0)
} else {enter code here
remainingTime = dateValue.day ?? 0 > 1 ? String(format: "%2d Days",dateValue.day ?? 0) : String(format: "%2d Day",dateValue.day ?? 0)
}
return remainingTime
}
}
If you have a date variable you can also use this solution for SwiftUi:
let date = Date()
Text(date, style: .time) // January 8, 2023
Text(date, style: .date) // 12:08 PM

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!

Swift - Start day and end day of the week before previous week

Today is Friday 6 March. How to find that 16 Feb is the start day and 22 Feb is the end day of the week before previous week.
16 is for my country Bulgaria in USA will be 15 and 21 I use .currentCalendar()
Something like this should work:
let cal = NSCalendar.currentCalendar()
let components = NSDateComponents()
components.weekOfYear -= 1
if let date = cal.dateByAddingComponents(components, toDate: NSDate(), options: NSCalendarOptions(0)) {
var beginningOfWeek: NSDate?
var weekDuration = NSTimeInterval()
if cal.rangeOfUnit(.CalendarUnitWeekOfYear, startDate: &beginningOfWeek, interval: &weekDuration, forDate: date) {
let endOfWeek = beginningOfWeek?.dateByAddingTimeInterval(weekDuration)
print(beginningOfWeek) // Optional(2015-02-15 05:00:00 +0000)
print(endOfWeek) // Optional(2015-02-22 05:00:00 +0000)
}
}
A simpler Swift 2 alternative as an extension, derived from Martin R's answer for getting the end of the month:
extension: NSDate {
func startOfWeek(weekday: Int?) -> NSDate? {
guard
let cal: NSCalendar = NSCalendar.currentCalendar(),
let comp: NSDateComponents = cal.components([.YearForWeekOfYear, .WeekOfYear], fromDate: self) else { return nil }
comp.to12pm()
cal.firstWeekday = weekday ?? 1
return cal.dateFromComponents(comp)!
}
func endOfWeek(weekday: Int) -> NSDate? {
guard
let cal: NSCalendar = NSCalendar.currentCalendar(),
let comp: NSDateComponents = cal.components([.WeekOfYear], fromDate: self) else { return nil }
comp.weekOfYear = 1
comp.day -= 1
comp.to12pm()
return cal.dateByAddingComponents(comp, toDate: self.startOfWeek(weekday)!, options: [])!
}
}
Usage:
// Use 2 for Monday, 1 for Sunday:
print(NSDate().startOfWeek(1)!) // "2016-01-24 08:00:00 +0000\n"
print(NSDate().endOfWeek(1)!) // "2016-01-30 08:00:00 +0000\n"
To guard against DST and such, you should also implement an extension to force the time to 12 pm:
internal extension NSDateComponents {
func to12pm() {
self.hour = 12
self.minute = 0
self.second = 0
}
}
If anyone looking for swift 3 answer:
func startOfWeek(weekday: Int?) -> Date {
var cal = Calendar.current
var component = cal.dateComponents([.yearForWeekOfYear, .weekOfYear], from: self)
component.to12am()
cal.firstWeekday = weekday ?? 1
return cal.date(from: component)!
}
func endOfWeek(weekday: Int) -> Date {
let cal = Calendar.current
var component = DateComponents()
component.weekOfYear = 1
component.day = -1
component.to12pm()
return cal.date(byAdding: component, to: startOfWeek(weekday: weekday))!
}
I set to 00:00:00 of that day
internal extension DateComponents {
mutating func to12am() {
self.hour = 0
self.minute = 0
self.second = 0
}
mutating func to12pm(){
self.hour = 23
self.minute = 59
self.second = 59
}
}
Swift 4+:
A very straightforward approach using mainly Calendar with the help of DateComponents:
Get Date
Go to previous week
Calendar.current.date(byAdding: .weekdayOrdinal, value: -1, to: aDate)
Get the current weekday
Calendar.current.component(.weekday, from: bDate)
Compute an offset from this weekday
Negative offset to reach the start of week
Positive offset to the reach end of the week
Use offset to go to the required date
Calendar.current.date(byAdding: .day, value: offset, to: bDate)
Solution:
extension Date {
var firstWeekdayOfLastWeek: Date? {
guard let previousWeek = Calendar.current.date(byAdding: .weekdayOrdinal,
value: -1, to: self)
else { return nil }
let offsetToFirstWeekday: Int = {
let currentWeekday = Calendar.current.component(.weekday, from: previousWeek)
guard currentWeekday > 0 else { return 0 }
return 1 - currentWeekday
}()
let result = Calendar.current.date(byAdding: .day,
value: offsetToFirstWeekday,
to: previousWeek)
return result
}
var lastWeekdayOfLastWeek: Date? {
guard let previousWeek = Calendar.current.date(byAdding: .weekdayOrdinal,
value: -1, to: self)
else { return nil }
let offsetToLastWeekday: Int = {
let currentWeekday = Calendar.current.component(.weekday, from: previousWeek)
return 7 - currentWeekday
}()
let result = Calendar.current.date(byAdding: .day,
value: offsetToLastWeekday,
to: previousWeek)
return result
}
}
Usage Example:
let formatter = DateFormatter()
formatter.dateStyle = .long
let date = Date()
//My current system date (as of time of writing)
print(formatter.string(from: currentDate)) //December 11, 2020
//Results (my system has Sunday as the start of the week)
print(formatter.string(from: date.firstWeekdayOfLastWeek!)) //November 29, 2020
print(formatter.string(from: date.lastWeekdayOfLastWeek!)) //December 5, 2020
Force unwrap is for example purposes only