Getting unexpected date from day formatter using weekOfYear - swift

I'm trying to get the start of the week using the current week and my return value is a week off. For example, if I input weekNumber 17 I would expected April 25th to be returned based off this, but I'm getting back April 17th.
I did check out the following post and that is where I got the function below. get first day of week using Weeknumber in Swift
func getFirstDay(WeekNumber weekNumber:Int, CurrentYear currentYear: Int)->String?{
let Calendar = NSCalendar(calendarIdentifier: .gregorian)!
var dayComponent = DateComponents()
dayComponent.weekOfYear = weekNumber
dayComponent.weekday = 1
dayComponent.year = currentYear
var date = Calendar.date(from: dayComponent)
if(weekNumber == 1 && Calendar.components(.month, from: date!).month != 1){
dayComponent.year = currentYear - 1
date = Calendar.date(from: dayComponent)
}
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy/MM/dd"
return String(dateFormatter.string(from: date!))
}

There are a few issues
For week numbers use always the ISO8601 calendar.
For week numbers the correct year property is yearForWeekOfYear.
In your code the week starts on Sunday (1), the linked site refers to Monday.
In Swift use native Calendar.
In the last line the String initializer is redundant.
Don't force unwrap dates.
func getFirstDay(weekNumber:Int, currentYear: Int) -> String? {
let calendar = Calendar(identifier: .iso8601)
var dayComponent = DateComponents()
dayComponent.weekOfYear = weekNumber
dayComponent.yearForWeekOfYear = currentYear
guard let date = calendar.date(from: dayComponent) else { return nil }
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.dateFormat = "yyyy/MM/dd"
return dateFormatter.string(from: date)
}

Related

How do I return the correct day of the week using dateFormatter in Swift 4?

The following Swift 4 code returns the incorrect day of the week for some cities.
// should be "Thu" but returns "Wed" for Aleppo for example
// current location set to Cupertino
// US Cities are correct
let date = "2021-04-29T07:00:00+03:00" // Aleppo
//let date = "2021-04-29T07:00:00-07:00" // Cupertino
let day = self.getDayName(stringDate: date)
print(day)
func getDayName(stringDate: String) -> String
{
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
let date = dateFormatter.date(from: stringDate)!
dateFormatter.dateFormat = "E"
let day = dateFormatter.string(from: date)
return day
}
Any ideas on how to fix this? Thanks

Date from String in Swift but it becomes the previous day

I am trying to create a day from a string (mSince) :
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
let newDate = dateFormatter.date(from:mSince as! String)!
and the print values are:
mSince = Optional(2021-04-25)
newDate = 2021-04-24 21:00:00 +0000
I could not figure out why newDate becomes the previous day.
Thank you!
Below is an example of how to create dates from multiple UTC timezones and an example of how to get the delta (in seconds) between the dates:
extension Date {
static func - (lhs: Date, rhs: Date) -> TimeInterval {
return lhs.timeIntervalSinceReferenceDate - rhs.timeIntervalSinceReferenceDate
}
}
let utcDateFormatter = DateFormatter()
utcDateFormatter.dateStyle = .medium
utcDateFormatter.timeStyle = .medium
// Set the timeZone to the device’s local time zone.
utcDateFormatter.timeZone = TimeZone(abbreviation: "UTC")
let date1 = Date()
print(utcDateFormatter.string(from: date1))
// Parsing a string date
let dateString1 = "May 11, 2020 at 4:23:11 AM"
let utcDate1 = utcDateFormatter.date(from: dateString1)
// Set a date for a different timeZone (2 hours difference)
utcDateFormatter.timeZone = TimeZone(secondsFromGMT: 3600)
// Printing a Date
let date2 = Date()
print(utcDateFormatter.string(from: date2))
// Parsing a string representing a date
let dateString2 = "May 11, 2020 at 4:23:11 AM"
let utcDate2 = utcDateFormatter.date(from: dateString2)
let diff = utcDate1! - utcDate2!
print(diff)

Wrong Day From date

I get wrong Day from a Date.
I put in for example formatter.date(from: "14.03.2019") which is a Thursday and later in formatter.weekSymbols I get printed the day after it (Friday)
why is that happening? Here's my code
`
func returnFormattedDate() -> String {
let formattedDay = String(format: "%02d.%02d", day, month)
return "\(formattedDay).2019"
}
func returnWeekDay() -> String? {
let formatter = DateFormatter()
formatter.dateFormat = "dd.MM.yyyy"
formatter.locale = Locale(identifier: "de_DE")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
print(returnFormattedDate())
guard let todayDate = formatter.date(from: returnFormattedDate()) else { return nil }
print(todayDate) // prints 2019-03-14 00:00:00 +0000
let nameOfDay = formatter.weekdaySymbols[Calendar(identifier: .gregorian).component(.weekday, from: todayDate)]
print(nameOfDay) // prints 'Friday' instead of thursday
return nameOfDay
}
Two mistakes in your code.
You have to set time zone
weekday values are 1...7 (1 = Sunday, 7 = Saturday) but the array of weekdaySymbols obviously starts with index 0 (weekdaySymbols[0] = Sunday, weekdaySymbols[6] = Saturday). So let's just subtract 1.
let dateString = "14.3.2019"
let formatter = DateFormatter()
formatter.dateFormat = "dd.MM.yyyy"
formatter.locale = Locale(identifier: "de_DE")
// ERROR 1
// you have to set timezone. Since we don't care about time, let's just use UTC.
formatter.timeZone = TimeZone(secondsFromGMT: 0)
let todayDate = formatter.date(from: dateString)!
print(todayDate)
var calendar = Calendar(identifier: .gregorian)
calendar.timeZone = TimeZone(secondsFromGMT: 0)!
// ERROR 2: you are indexing incorrectly
let nameOfDay = formatter.weekdaySymbols[calendar.component(.weekday, from: todayDate) - 1]
print(nameOfDay)

Convert time to yesterday after 12am

I would like to convert the time to yesterday after 12AM.
For example: If message sent at 11:35PM and the time now is 12:00AM i would to convert it to yesterday
let dateformatter = DateFormatter()
dateformatter.timeZone = NSTimeZone.local
dateformatter.dateFormat = "MM/dd/yyyy"
let interval = Calendar.current.dateComponents([.year, .month, .day], from: self, to: Date())
if let day = interval.day, day > 0 {
return day == 1 ? "Yesterday at" + " " + formatter.string(from: date as Date) : dateformatter.string(from: date as Date)
}
This code converting to yesterday 24hrs later from sent time.
There is a method in Calendar called isDateInYesterday
extension Date {
func isYesterday() -> Bool {
let calendar = Calendar.current
return calendar.isDateInYesterday(self)
}
}

NSDateFormatter. Setting time elapsed since date in swift

I'm looking to call a function that checks time elapsed since date. This will determine how the timeLable displays in my messages view controller, similar to IMessage.
The code I'm using below only shows HH:MM
let date = dateFormatter().dateFromString((recent["date"] as? String)!)
timeLabel.text = NSDateFormatter.localizedStringFromDate(date!, dateStyle: NSDateFormatterStyle.NoStyle, timeStyle: NSDateFormatterStyle.NoStyle)
I'm looking to change it to something along the lines of:
If date is today, date = "HH:MM"
If date is Yesterday, date = "Yesterday"
If date is the day before yesterday and so on, date = "Monday, Tuesday, Wednesday..."
If date is over 1 week, date = MM/DD/YY
Or try this. Note that we have to use components:fromDate: and then use components:fromDateComponents:toDateComponents:options: because if we don't 23:59 last night returns 23:59 instead of Yesterday.
extension NSDateFormatter {
static func friendlyStringForDate(date:NSDate) -> String {
// Fetch the default calendar
let calendar = NSCalendar.currentCalendar()
// Compute components from target date
let from = calendar.components([.Day, .Month, .Year], fromDate: date)
// Compute components from current date
let to = calendar.components([.Day, .Month, .Year], fromDate: NSDate())
// Compute days difference between the two
let delta = calendar.components(.Day, fromDateComponents: from, toDateComponents: to, options: [])
switch delta.day {
case 0:
let formatter = NSDateFormatter()
formatter.timeZone = NSTimeZone.defaultTimeZone()
formatter.dateFormat = "HH:mm"
return formatter.stringFromDate(date)
case 1:
return "Yesterday"
case 2..<7:
let formatter = NSDateFormatter()
formatter.timeStyle = .NoStyle
formatter.dateFormat = "EEEE"
return formatter.stringFromDate(date)
default:
let formatter = NSDateFormatter()
formatter.timeStyle = .NoStyle
formatter.dateFormat = "MM/dd/YY"
return formatter.stringFromDate(date)
}
}
}
Now then, to use it just:
timeLabel.text = NSDateFormatter.friendlyStringForDate(date!)
SWIFT 3:
extension DateFormatter {
static func friendlyStringForDate(date: Date) -> String {
// Fetch the default calendar
let calendar = Calendar.current
let unitFlags: NSCalendar.Unit = [.day]
// Compute days difference between the two
let delta = (calendar as NSCalendar).components(unitFlags, from: date, to: Date(), options: [])
if let day = delta.day {
switch day {
case 0:
let formatter = DateFormatter()
formatter.timeZone = NSTimeZone.default
formatter.dateFormat = "hh:mm a"
return formatter.string(from: date)
case 1:
return "Yesterday"
case 2..<7:
let formatter = DateFormatter()
formatter.timeStyle = .none
formatter.dateFormat = "EEEE"
return formatter.string(from: date)
default:
let formatter = DateFormatter()
formatter.timeStyle = .none
formatter.dateFormat = "MM/dd/YY"
return formatter.string(from: date)
}
}
return ""
}
}