How to create a time stamp from nsdate(timeintervalsince1970) - ios

I have been searching for a while and haven't found a good answer for this. I currently have when a user posts a photo, it takes an nsdate(timeIntervalSince1970) and puts it as a value when uploaded to firebase. One problem, the current way I change the nsdate to a timeStamp or mins/hours/days since it was posted is not Turing out to good, it does not correct to when a day passes, it just shows what time it was posted at. I was hoping I could get an answer or referred to an algorithm that can change an nsdate(timeIntervalSince1970) to a timeStamp or string that just gives me how many hours ago it was posted, and every 24 hours, change it to 1 day(s). I apologize ahead of time for asking kinda of easy question, I'm guessing. Here is my current code:
if let seconds = posts[visibli.row].timeStamp {
let time = NSDate(timeIntervalSince1970: TimeInterval(seconds))
let formatter = DateFormatter()
formatter.dateFormat = "hh:mm a"
labelTime.text = formatter.string(from: time as Date)
}
Thank you for any Help!

What you are looking for is DateComponentsFormatter. You can look at the different formatters Foundation offers, here.
If you want to have a string that denotes the amount of time that has elapsed since a given date, you can say something like:
if let seconds = posts[visibli.row].timeStamp {
let time = Date(timeIntervalSince1970: TimeInterval(seconds))
let dateComponentsFormater = DateComponentsFormatter()
dateComponentsFormater.unitsStyle = .positional
let string = dateComponentsFormater.string(from: time, to: Date())
labelTime.text = string
}

Current Timestamp as String.
public class func getCurrentTimeStamp()->String{
return String(describing: NSNumber(value: round(NSDate().timeIntervalSince1970 * 1000)))
}
this function use get current timestamp.

Related

How to calculate time (minutes) between two dates in swift?

What do we got: Date+time (format yyyy-mm-dd hh:mm a)
What are we looking for: Time difference in minutes
What operation: NewDate - OldDate
So, I wonder how I could accomplish above goal? I would like to format the date and time to US, regardless from which locale the user has. How can I do that?
Then I will save the 'oldTime' into UserDefaults, and use it for later calculation. The goal is to put the user on delay for 5 minutes and the calculations will be performed to determine if user should be on delay or not.
Just make a function that takes two dates and compares them like this.
import UIKit
func minutesBetweenDates(_ oldDate: Date, _ newDate: Date) -> CGFloat {
//get both times sinces refrenced date and divide by 60 to get minutes
let newDateMinutes = newDate.timeIntervalSinceReferenceDate/60
let oldDateMinutes = oldDate.timeIntervalSinceReferenceDate/60
//then return the difference
return CGFloat(newDateMinutes - oldDateMinutes)
}
//Usage:
let myDateFormatter = DateFormatter()
myDateFormatter.dateFormat = "yyyy-MM-dd HH:mm"
//You'll need both dates to compare, you can get them by just storing a Date object when you first start the timer.
//Then when you need to check it, compare it to Date()
let oldDate: Date = myDateFormatter.date(from: String("2019-06-22 11:25"))
func validateRefresh() {
//do the comparison between the old date and the now date like this.
if minutesBetweenDates(oldDate, Date()) > 5 {
//Do whatever
}
}
You can, of course, change the .dateFormat value on the date formatter to be whatever format you'd like. A great website for finding the right format is: https://nsdateformatter.com/.
You say:
I would like to format the date and time to US, regardless from which locale the user has. How can I do that?
Specify a Locale of en_US_POSIX:
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd hh:mm a"
formatter.locale = Locale(identifier: "en_US_POSIX")
The locale is not the only question.
There’s also a timezone question. For example, you're driving out of Chicago and go from Central to Eastern timezones; do you really want to consider that one hour has passed?
Do you really want to discard seconds? If you do that, the 59 seconds between going from 8:00:00pm to 8:00:59pm will be considered “zero minutes” but the one second between 8:00:59pm and 8:01:00pm will be considered “one minute”.
Frankly, if I wanted to save a locale and timezone invariant date string, I’d suggest using ISO8601DateFormatter.
Then I will save the 'oldTime' into UserDefaults, and use it for later calculation.
If that’s why you’re using this DateFormatter, I’d suggest saving the Date object directly.
UserDefaults.standard.set(oldTime, forKey: "oldTime")
And to retrieve it:
if let oldTime = UserDefaults.standard.object(forKey: "oldTime") as? Date {
...
}
In terms of calculating the number of minutes between two Date objects
let minutes = Calendar.current
.dateComponents([.minute], from: date1, to: date2)
.minute
If you want the number of seconds, you can also use timeIntervalSince:
let seconds = date2.timeIntervalSince(date1)
And if you wanted to show the amount of elapsed time as a nice localized string:
let intervalFormatter = DateComponentsFormatter()
intervalFormatter.allowedUnits = [.minute, .second]
intervalFormatter.unitsStyle = .full
let string = intervalFormatter.string(from: date1, to: date2)
I'm not convinced that your question is the best way to go about accomplishing your aim, but the code below will work.
let dateFormatterNow = DateFormatter()
dateFormatterNow.dateFormat = "yyyy-MM-dd hh:mm a"
dateFormatterNow.timeZone = TimeZone(abbreviation: "EST")
let oldDateString = "2019-06-23 12:44 p"
let oldDate = dateFormatterNow.date(from: oldDateString)
let newDateString = "2019-06-23 12:54 p"
let newDate = dateFormatterNow.date(from: newDateString)
if let oldDate = oldDate, let newDate = newDate {
let diffInMins = Calendar.current.dateComponents([.minute], from: oldDate, to: newDate).minute
print(diffInMins)
}

Difference between boarding time and current time in UTC in iOS , Swift

I am getting Boarding Time from service ( lets say BT- Boarding Time)
I need to find out the differnce between Boarding Time and current time and then find out the difference in Hour , Min.
The condition is user may check the difference between these from any country in the world. so i used UTC to calculate but its giving correct result , kindly help me in this.
func dayStringFromTime() -> String {
let currentTimeUnix = Date().timeIntervalSince1970
let date = NSDate(timeIntervalSince1970: currentTimeUnix)
let dateFormatter = DateFormatter()
// dateFormatter.dateFormat = "HH:mm:ss"
return date.description
}
let CT = dayStringFromTime() //time1
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-mm-dd HH:mm:ss"
let CTDate = formatter.date(from: CT)
let time1 = boardingDateTime//timeformatter.date(from: CT)
let time2 = CT_Date//timeformatter.date(from: ETD)
//You can directly use from here if you have two dates
let interval = time1.timeIntervalSince(time2! as Date)
let hour = (interval ) / 3600;
let minute = interval.truncatingRemainder(dividingBy: 3600) / 60
let intervalInt = Int(interval)
print("\(intervalInt < 0 ? "-" : "+") \(Int(hour)) Hours \(Int(Int(minute))) Minutes")
let minText = Int(minute) > 0 && Int(minute) != 0 ? " \(Int(minute)) min" : (Int(minute) < 0 ? " \(Int(abs(minute))) min" : "")
let hrText = Int(hour) > 0 && Int(hour) != 0 ? " \(Int(hour)) hr" : (Int(hour) < 0 ? " \(Int(abs(hour))) hr" : "")
this url https://stackoverflow.com/a/28608779/3400991 shows the exact problem about this result, kindly help
This is way easier that you have made it out to be:
let boardingTime = Date().addingTimeInterval(3200) // the `addingTimeInterval` is for demonstration purposes only.
let now = Date()
let difference = Calendar.current.dateComponents([.hour, .minute, .second], from: now, to: boardingTime)
print("Boarding will be in: \(difference.hour!):\(difference.minute!):\(difference.second!)")
First of all, be very careful with date/time mathematics, it's not a straight linear conversion, there are lots and lots of rules which go around it and make it ... complicated.
The first thing you need is to calculate the difference between the two times, lucky for you, this is relatively easy...
var boardingTime = Date()
boardingTime = bordingTime.addingTimeInterval(Double.random(in: 0.0..<86400.0))
let now = Date()
let difference = boardingTime.timeIntervalSince(now)
This gives you the number of seconds between these two values (a positive value been the time till, a negative value been the time after)
Next, you need the hours/minutes in some form of human readable notation. It might seem tempting to just start by multiplying and dividing everything by 60, but that would be a mistake and lead you into bad habits (sure over a short range it's not bad, but you need to be very careful)
A better solution would be to use a DateComponentsFormatter...
let formatter = DateComponentsFormatter()
formatter.allowedUnits = [.hour, .minute]
formatter.unitsStyle = .abbreviated
formatter.string(from: difference)
Which will take care of all the "rules" for you, but, it will also localise the results, always a bonus.
The above example will print something like...
10h 28m

How to check the amount of time between two NSDates?

I'm making a kind of challenge based app that requires that the user comes back every day. If he misses one day, he has to start all over again.
My problem is my dateChanged()-function; the first thing is, that it doesn't work very reliable, the second is that I just check if the date changed, I accordingly don't know if there were one or two days between using the app.
Here's my current function:
public func changeDays()
{
myFormatter.dateStyle = .short
myFormatter.locale = Locale(identifier: "de_DE")
oldDate = defaults.string(forKey: "oldDate")!
let newDate = Date()
let newDateString = myFormatter.string(from: newDate)
if newDateString == oldDate
{
NumberOfDaysInARow.text = "\(days) / 30"
}
else if newDateString != oldDate
{
days += 1
NumberOfDaysInARow.text = "\(days) / 30"
defaults.set(days, forKey: "days")
}
oldDate = newDateString
defaults.set(oldDate, forKey: "oldDate")
}
Just today it started giving me a fatal error when starting the app on my iPhone, did not happen in the simulator though... weird.
How do I have to change my function to make it a 100% reliable (and working) while also being able to check the amount of time between the two dates?
Thank you for having a look! Have a great day
You could extend Date with the function below that returns the amount of days from another date.
extension Date {
// Returns the amount of days from another date
func days(from date: Date) -> Int {
return Calendar.current.dateComponents([.day], from: date, to: self).day ?? 0
}
}
Instead of saving oldDate as a string you can set it to defaults as a date:
defaults.set(Date(), forKey: "oldDate")
You can get the old date from defaults using:
let oldDate = defaults.object(forKey:"oldDate") as! Date
Once you have your old date
let dateNow = Date()
let timeDifference = dateNow.days(from: oldDate!)
If timeDifference > 1 {
// older than 1 day
} else {
// Streak still alive
}
}
If you look in the documentation you will see that Date has a method whose sole purpose is too determine the interval between two dates time​Interval​Since(_:​).
If you set the old date to always be 11:59PM on the day it was last used you only have to see if the interval is greater than 24 hours worth of seconds (60 seconds * 60 minutes * 24 hours).
You may want to look at the docs for DateComponents for help creating a date that uses the current date but with a specific time.

How long ago did the User create a post, NSDate(), Manipulating the format of the "time of post" created

I am making a social app that saves its posts in user specific nodes , with that i am also saving the time of post in this format :-
Wednesday, July 20, 2016, 00:14
which i display with the post in the global feed of friends of the user.
Before 24 hours of that post , i want to display time of post on the feed as this :- "5 Hours Ago"
After 24 hours of that post time of post becomes something like this :- "Yesterday"...
After 48 hours of that post time of post becomes something like this :- "On 5 Aug"...
So far i have come up with these two options:-
1.) Change the time of the feed in the database, which i think would be much better option.
2.) Retrieve the time of post , iterate through MULTIPLE if conditions and set the time of post accordingly.
I would be able to implement the second option but i have no clue to how to go forward with option one
Given that my JSON tree is something like this
appname:{
users : {....
.....
user1 : {....
.....
postsCreated : {
post1 : {
..
timeofPost : ""Wednesday, Aug 5, 2016, 00:14""
}
}
}
}
}
I did stumble upon http://momentjs.com/ but thats for Javascript
Also any suggestion on my JSON tree or is it fine the way it is?
You propose:
Change the time of the feed in the database, which i think would be much better option.
No, the date in the database, as well as that which is communicated with web service, should not be a formatted string. The database and the web service should be capturing the raw dates (or, more accurately, RFC3339/ISO8601 format or seconds from some reference date). The formatting of the elapsed time in a string for the UI is the responsibility of the app.
Retrieve the time of post, iterate through MULTIPLE if conditions and set the time of post accordingly.
Yes, that's what you should do.
By the way, if you're going to omit the year, you probably have a fourth permutation which includes year if the date is more than one year in the past, e.g.:
func formattedPostDateString(date: NSDate) -> String {
let now = NSDate()
let elapsed = NSCalendar.currentCalendar().components([.Day, .Year], fromDate: date, toDate: now, options: [])
switch (elapsed.year, elapsed.day) {
case (0, 0):
return "\(elapsedFormatter.stringFromDate(date, toDate: now)!) \(agoDateString)"
case (0, 1):
return yesterdayString
case (0, _):
return "\(onDateString) \(lessThanOneYearFormatter.stringFromDate(date))"
default:
return "\(onDateString) \(moreThanOneYearFormatter.stringFromDate(date))"
}
}
Where
let onDateString = NSLocalizedString("On", comment: "prefix used in 'On 5 Aug'")
let agoDateString = NSLocalizedString("ago", comment: "suffix use in '4 hours ago'")
let yesterdayString = NSLocalizedString("Yesterday", comment: "showing 'date' where it's between 24 and 48 hours ago")
let elapsedFormatter: NSDateComponentsFormatter = {
let formatter = NSDateComponentsFormatter()
formatter.allowedUnits = [.Year, .Month, .Day, .Hour, .Minute, .Second]
formatter.unitsStyle = .Full
formatter.maximumUnitCount = 1
return formatter
}()
let lessThanOneYearFormatter: NSDateFormatter = {
let formatter = NSDateFormatter()
formatter.dateFormat = NSDateFormatter.dateFormatFromTemplate("MMM d", options: 0, locale: nil)
return formatter
}()
let moreThanOneYearFormatter: NSDateFormatter = {
let formatter = NSDateFormatter()
formatter.dateStyle = .MediumStyle
return formatter
}()
The only thing you need to do is to convert the string returned by the web service into NSDate object. To that end, the web service should probably return the post date in ISO 8601/RFC 3339 format (e.g. 2016-08-26T15:01:23Z format).
To create ISO8601/RFC3339 dates in Swift 2:
let isoDateFormatter: NSDateFormatter = {
let formatter = NSDateFormatter()
formatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
formatter.timeZone = NSTimeZone(forSecondsFromGMT: 0)
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ"
return formatter
}()
And then:
let string = isoDateFormatter.stringFromDate(date)
Or
let date = isoDateFormatter.dateFromString(string)
Or in iOS 10+ using Swift 3, you can use the new ISO8601DateFormatter:
let isoDateFormatter = ISO8601DateFormatter()

Get tomorrow's date with Swift 2

I have this code which gives today's date in this formate M/dd/yy
let dateFormater = NSDateFormatter()
dateFormater.dateFormat = "M/dd/yy"
let todayDate = dateFormater.stringFromDate(NSDate())
How can I get the same thing but with next day's date please?
First, you get a NSDate for the day you need, in this example (one day from now is tomorrow):
var oneDayfromNow: Date? {
Calendar.current.date(byAdding: .day, value: 1, to: Date())
}
print(oneDayfromNow)
Then you convert it to your format as string (your case M/dd/yy):
if let oneDayfromNow {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "M/dd/yy"
let str = dateFormatter.string(from: oneDayfromNow)
print(str)
}
It's a bit complicated, but it's all things that you need to know anyway.
Why it's difficult: You would think that you could just take NSDate (timeIntervalSinceNow:24 * 60 * 60), adding one day to now. But when you turn on daylight savings time, then 11:30pm plus 24 hours is 00:30am two days later. When daylight savings time is turned off, then 00:30am plus 24 hours can be 11:30pm on the same day.
So you need to create an NSCalendar object, convert NSDate () into components, add one day to the components, convert back to an NSDate (all that gives you the same time on the next day, handling all special cases), and then format the result as you did now.
I finally used this code to fix it :
let dateFormater = NSDateFormatter()
dateFormater.dateFormat = "M/dd/yy"
let todayDate = dateFormater.stringFromDate(NSDate().dateByAddingTimeInterval(24 * 60 * 60))

Resources