Add milliseconds to current time - swift

So I currently have a now playing swift app, that requests to the server every 30 seconds, and seems to be overloading the server.
Since we request data from iTunes API about the current song that is playing, I was thinking that I could possibly limit the request if a result was found by iTunes API.
Using trackTimeMillis I could add that trackTimeMillis to the current time and if not greater than the time don't ping the server. If greater than ping server for latest track.
I am thinking I will need to wrap the function that pings the server in a
Calendar.current.dateComponents([.hour], from: Date(), to: Date()), diff > Date())+ trackTimeMillis {
But that does not work
basically I need to add trackTimeMillis to the current Date() and if that users current timestamp (date) is larger than the Date() + trackTimeMillis then allow request.

I don't really understand what you are trying to do with the code snippet you put in your question.
Focusing on how you add some number of milliseconds to a Date():
Date has the function addingTimeInterval(_:)
If you need to add a certain number of milliseconds do a date, use this:
newDate = Date().addingTimeInterval( Double(millis) / 1000)
Edit:
As Matt pointed out, you can do that even more simply by writing
newDate = Date() + Double(millis) / 1000
Since there is an override of the + operator that takes a Date and a Double and returns a Date.
Both versions of this add a Double containing a specified number of seconds to the Date. Since Doubles can represent very small and very large numbers you can add or subtract values ranging from tiny fractions of a second to thousands of years to any Date.

A simpler alternative. When I am doing a task like this, I usually store the Date of the previous request, e.g.:
let lastRequestTime = Date()
and then simply check the elapsed time:
if Date().timeIntervalSince(lastRequestTime) > 30 {
...
}
Another option is to use Timer. Basically, you can schedule a Timer that will send the request after X seconds. If you receive a response from a different source first, you simply cancel the Timer and possibly the request if it is already running.

Related

Calculate timeInterval between two dates with different time zone in swift

I'm trying to protect game from abusing time changing. The game save current time and if you enter game soon it check if timeInterval is greater than 0 (if not you can't play). But what about changing timeZone?
If player moved from France to e.g. United Kingdom timeZone changes. Let's say first point was 10:07AM in France and the second in UK after 30 minutes (-1 hour difference). The second point is gonna be 09:37AM? How Date() works when devise TimeZone changes? Do timeInterval() function takes into account that changes? Or it possible to just ignore changing timeZone?
Game should working offline.
Update
How that works
The Date() is saved at the very first entry in app. (In CoreData)
The next time the app enters, it will check the new and old dates. Using TimeInterval()
Case1 - result is greater than 0. It means the entry in "Future". Entry allows. Save the new Date instead of the old.
Case2 - result is less than 0. It means the entry in "Past". That impossible without date changing. Entry is prohibited until the new date is greater than old.
From the Date() documentation:
A Date value encapsulate a single point in time, independent of any particular calendrical system or time zone.
I would therefore expect this to be a non-issue - the first point in time would still be 30 minutes before the second point in time, and I'd expect that to be respected by timeInterval. I'd expect the same Date() to be returned by now at a given point in time, regardless of the time zone of the system running the code.

Limiting functionality usage per month in Swift

There are a lot of apps that allow the user to use a functionality a certain number of times per month. And when the quota is reached that functionality is blocked till the end of the month.
I am trying to do the same thing and I seem to have run into a bit of a problem.
struct Data{
var text:String
var date:Date
}
var array : [Data] = [
Data(text: "Cars", date: Date()),
Data(text: "Bikes", date: Date()),
Data(text: "Trucks", date: Date())
]
func countForCurrentMonth(date: Date) -> Int{
let currentMonth = Calendar.current.component(.month, from: date)
print(currentMonth)
var datesArray = [Int]()
for item in array{
let month = Calendar.current.component(.month, from: item.date)
if month == currentMonth{
datesArray.append(month)
}
}
let itemCount = datesArray.count
return itemCount
}
func addItem(){
if countForCurrentMonth(date:Date()) > 120{
//functionality locked
print("subscribe to unlock")
}else{
//allowed
print("allowed")
}
}
The problem is here, the date property is compared with Date() which gives the users system date. As the users system date can be manually set, one could easily by bypass this limitation.
So my question is, how can I implement the same thing without using the system date and which doesn't require an internet connection.
One of the things that I tried was keeping a stored date on the device and every time the user opens the app it checks the system date and if it's not equal to the stored date incrementing the day count and replacing the stored date with the new date. However, this would only work if the user opens the app everyday of the month.
I don't think that there is a proper solution for this without an internet connection but you cloud also save the latest registered date your app has been used with. This way you could check if the current date is earlier and lock your app for instance and try to fetch the correct timestamp online, if possible.
But it may be possible this leads to other issues when the user travels and changes his timezone for example but generally this solution should work.
One option would be to store the date and have it be a crucial component. That way if a user was cheating, when compared to other users the date would be too far in the future to count in the app against the competition. Then you would just store the latest date and any earlier date would invalid the session or lock the progress of the app. For instance you could say apply changes to the user account if current date < item date. This could be a problem if you update all users every few seconds. But, in that case you'd probably be online. In this case it seems you want to limit by month though. So even if the user applied 120 changes this month and another 120 changes next month, the changes would only be valid in that next month. So they still get the number of changes applied in that month. Or the first 120 of them. Also, you may want to check the year while you're looking for valid dates.

How to determine if a user has entered only date or also time in the form field?

I have a field where user can enter only date or also time in a text field. Now I know if I make 2 fields, one for date and one for time, I can check if the time field is empty or not.
What I'd like to do is have only one field. If user puts the ending date it takes time only, if user inputs date and time it takes both.
The problem I have is this: If user enters "8.12.2013" it in fact means "8.12.2013 0:0:0" where I convert it to Cdate. But then the end time is the first second of the date 8.12.2013 which means it 8.12.2013 means stop on that date (this is a stop time field). But in fact if a user writes 8.1.2013 it means roll till the end of the day.
Of course I can do date()>"8.12.2013" and it will work, but then if user enters date and time it will not work as it strips time part.
My question: Is there any function in ASP that would check if the time part of the date is set in a variable? I tried to use TIME but it shows 0 for hours, 0 for minutes and 0 for seconds even if the Cdate("8.12.2013") is used. I'd need the function to tell me that the time is not set so I could make a comparation using date() instead of now().
I hope that makes sense.
You could try something as simple as:
If CLng(myDate) = myDate Then ...
Dates are treated as time past a particular date etc., therefore integerising the date will remove the time.
-- EDIT --
Just to add to the above code: The CLng will convert a Date and Time into just a Date. By comparing this against the whole date you can see if any fractional part was included.
Please be aware that this would be considered bad practice in a strictly typed environment, such as .NET, but Classic ASP types are variants and are quite malleable.

Is there a simple way to fetch records from the last N days in MongoDB?

If my records have a created_date field, is there a simple way to fetch all records that were created within the 7 days without calculating and adding the start and end date manually?
Mongo doesn't have a symbolic date like SQL NOW() which you can use on the client and have evaluated on the server.
The best way to solve your problem is to evaluate calculate the dates on the client. In your specific case, since records aren't created in the future, likely you only need to calculate "now minus 7 days" in your client, and put that date in your query.
Sort of an aside, if you need the exact date from the server, you can fetch it like this:
db.eval( function() { return new Date() } );
Using most of the drivers you should be able to accomplish that using the $eval command.
Finally, you could accomplish this entirely on the server using a where() expression. However, I don't recommend this approach. Such queries can't take advantage of indexes and therefore must deserialize every record in the collection. They're very slow unless your collection is tiny. If you want to take this approach, though, you can use new Date() in the JavaScript for your where() expression.
Try something like this in the mongo console to return records created in the last 7 days (assuming created_date is the insertion date):
> startDate = new Date() // Current date
> startDate.setDate(startDate.getDate()-7) // Subtract 7 days
> startDate.setHours(0) // Set the hour, minute and second components to 0
> startDate.setMinutes(0)
> startDate.setSeconds(0)
> db.mycollection.find({created_date:{$gte: startDate}})
Quite a few lines of code, but at least you won't have to do date arithmetics.

How replace hours and minutes put by user into current date and compare it

I have two Strings with two digits in each (12) and (30) as example(It`s for alarm)
I want to put String in current data, and change current hours and minutes to which user put.
Convert it to programm format(look like 211232131134) for comparison current time with putable.
(4. Do some actions when it will be comparison)
That`s i need get minutes and hours from new date(putting by user), add current year, mm, and d to it. Compare with current date.
What are you writing the code in? In general you could convert the date entered into UNIX time (seconds since 1970-01-01) and get the current time in UNIX time and just compare those as a integer.