Convert time to yesterday after 12am - swift

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

Related

Getting unexpected date from day formatter using weekOfYear

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

How do I programatically determine the time (hours/minutes) and set them to 00/00 in Swift?

I am doing some date math and before doing so am trying to programatically adjust the time associated with a date based on its current value. In the code below I am able to set the hours and minutes to 00/00 but I have to know the offset and manually set the value. Below is my code and next to each print statement I have listed the value I am getting. Any assistance in pointing out the error I am making will be appreciated. I wonder if it is a timezone issue relative to GMT.
Chris
func AdjustDateTime(vooDate: Date) -> Date {
let date = vooDate
let _ = print("date")
let _ = print(date) // returns 2021-10-25 06:00:00 +000
let calendar = Calendar.current
let components = calendar.dateComponents([.year, .month, .day, .hour, .minute], from: date)
let year = components.year
let month = components.month
let day = components.day
let hour = components.hour
let minute = components.minute
let _ = print("hour")
let _ = print(hour!) // returns 0 even though the date above say 06
let _ = print("minute")
let _ = print(minute!) // returns 0
var comps = DateComponents()
comps.year = year
comps.month = month
comps.day = day! + 1
comps.hour = -06 // setting manually, would like to do so programatically
comps.minute = 00
let returnDate: Date = Calendar.current.date(from: comps)!
let _ = print("Return Date")
let _ = print(returnDate) // returns 2021-10-26 00:00:00 +0000, which is what I want
return returnDate
}
Setting the time zone as indicated by Jacob was the key to solving the problem. In the code where I read in the JSON file I modified my dateFormatter to what's shown below. This returns a date object as shown below the code. Now I do not need to worry about the hours, since they are 0. From there it is easy to add 1 day with a function, shown below. Before doing my date math I make the same adjustments to a date in the future, i.e. timezone and locale, and I get the correct difference between the two dates which was the ultimate goal. Thank you for the assistance.
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
dateFormatter.locale = Locale(identifier: "en_US_POSIX") // added
dateFormatter.timeZone = TimeZone(secondsFromGMT: 0) // added
2021-10-25 00:00:00 +0000
func AdjustDateTime(vooDate: Date) -> Date {
return Calendar.current.date(byAdding: .day, value: 1, to: vooDate)!
}

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)

Date not convert in AM/PM Format in swift

I need to date and time with my own format like time in AM/PM (12 hours).
extension Date {
func getStringFromDateWithUTCFormat() -> ObjTimeStamp {
let dateFormatterPrint = DateFormatter()
dateFormatterPrint.timeZone = TimeZone.init(abbreviation: "UTC")
// Get Date
dateFormatterPrint.dateFormat = "MM/dd/yyyy" //"MMM dd,yyyy"
let date = dateFormatterPrint.string(from: self)
// Get Time
dateFormatterPrint.dateFormat = "hh:mm:ss a"
let time = dateFormatterPrint.string(from: self)
return ObjTimeStamp.init(date: date, time: time, timeStamp: self)
}
}
Update
Calling function
self.currentDate = Date()
let objTimeStamp = currentDate.getStringFromDateWithUTCFormat()
Perfect work when device time in 12-hour format when I try to change device time in 24-hour formate then given wrong time format.
set your dateFormatter locale to en-US then try to convert, it's works for me when iPhone's time format is 24 hour:
let date = Date()
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en-US")
formatter.dateFormat = "hh:mm a"
let time12 = formatter.string(from: date)
print(time12)
output:
01:37 PM

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