I'm trying to record an event at its happening time by accuracy of milliseconds. Below is my code:
NSDate * now = [NSDate date];
NSDateFormatter *outputFormatter = [[NSDateFormatter alloc] init];
[outputFormatter setDateFormat:#"HH:mm:ss.SSS"];
NSString *timeString = [outputFormatter stringFromDate:now];
However, the results are as this:
45:11.3
It looks like time record has been rounded to 0.1 second, while all the second and third decimal accuracy is lost. Can anyone suggest where the problem is and how I can get the millisecond information?
Thank you all!
Paul
Your code works fine for me. Here it is (in Swift):
let f = NSDateFormatter()
f.dateFormat = "HH:mm:ss.SSS"
let timeString = f.stringFromDate(NSDate()) // "20:26:19.118"
You do not show the code by which you read the resulting timeString but perhaps the fault lies in how you are doing that. It is odd that the Hour part is missing from your output too.
Related
I have simple code that transforms a date into a string:
+ (NSString *)dateStringFromDate:(NSDate *)date {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss'Z'"];
return [dateFormatter stringFromDate:date];
}
I would expect a string like:
2020-10-19T11:55:29Z
But instead it is outputting a string like this:
2020-10-19T12:38:06 p.m.Z
Note the "p.m." in the output. I am not using the "a" date format character, so I would not expect to see AM or PM.
When I run the code in the simulator, it produces the correct result. When I run it on a physical iPad running iPadOS 14.0.1 it produces the incorrect result.
I have noticed that forcing the locale with this fixes the issue:
dateFormatter.locale = [NSLocale localeWithLocaleIdentifier:#"en_US_POSIX"];
But, I'm not sure if that is the correct approach, as this seems like a bug.
Can anyone shed light on why this is happening?
I am trying to get a NSDate object from a UTC time string. The example of the time string is this:
2016-07-29T11:43:55+02:00
I am usingNSDateFormatter and set the formate as: yyyy-MM-dd'T'HH:mm:ss
However this gives me the take with incorrect time zone. So the above date will be: 2016-07-29T09:43:55+00:00
How do I keep the time zone aspect as well?
I did try adding a 'Z' to the end of the formatter but that just returns a nil date.
Try this
NSDateFormatter *userFormatter = [[NSDateFormatter alloc] init];
[userFormatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss.SSSZ"];
NSLocale *posix = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US_POSIX"];
[userFormatter setLocale:posix];
NSString *dateConverted = [userFormatter stringFromDate:theDate];
Thanks to all that help. Solved the issue. The time on my iOS Simulator was correct. However when I called [NSDate date]; it show'd me a time two hours before local time. Hence the 'errors' I was seeing in the formatting of NSDate.
Use NSISO8601DateFormatter if targeting iOS 10 and above. https://developer.apple.com/documentation/foundation/nsiso8601dateformatter
I am trying to get the epoch time for a date (2016-03-31T17:58:30.812Z) and I'm having trouble converting. Here is what I have tried:
NSDateFormatter* df = [NSDateFormatter new];
NSDate* tokenCreated = [NSDate new];
[df setDateFormat:#"yyyy-MM-dd'T'HH:mm:sssZ"];
tokenCreated = [df dateFromString:#"2016-03-31T17:58:30.812Z"];
NSTimeInterval timeTokenCreated = [tokenCreated timeIntervalSince1970];
NSLog(#"TIME TOKEN::::%f", timeTokenCreated);
What is happening is that tokenCreated is being set to nil, and I'm unable to convert. Can someone please point me in the right direction and tell me where I'm going wrong?
What is happening is that tokenCreated is being set to nil
Because your date format doesn't match your string. For example, your format fails to distinguish between the seconds and the fractional seconds. You would need this:
#"yyyy-MM-dd'T'HH:mm:ss.SSSZ"
Ok this one really has me stumped. The challenge seems simple but has a few restrictions that are really throwing me off.
Gist of the program:
(1) When the minute changes the application should output the current time with the format HH:mm:ss.
(2) When the second changes the application should output a character for every second and a different character for every tenth second (i.e. ".........|.........|"). Here it is important to note that I cannot just count seconds; rather, the program must know the value of the second of the current time and output the corresponding character only if it is divisible by 10.
Restrictions:
(1) The program can have 2 classes -- one for the minute display and one for the second display.
(2) Each class can contain only one void method that takes a timer as a parameter.
(3) The main function will create an object of each class and 2 NSTimers. The first timer must have its interval set at 0.5 and must target the minutes object. The second timer must have its interval set at 0.1 and must target the seconds object.
I would love to just set the first time to fire every minute and the second timer to fire ever second, but I am not allowed to tamper with that. This is as far as I got before I was stumped:
main.m:
MinuteDisplay *minutes = [[MinuteDisplay alloc] init];
__unused NSTimer *minutesTimer =
[NSTimer scheduledTimerWithTimeInterval:0.5
target:minutes
selector:#selector(minuteChange:)
userInfo:nil
repeats:YES];
[[NSRunLoop currentRunLoop] run];
MinuteDisplay.m:
- (void)minuteChange:(NSTimer *)timer
{
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"HH:mm:ss"];
NSDateFormatter *testFormatter = [[NSDateFormatter alloc] init];
[testFormatter setDateFormat:#"ss"];
NSDate *now = [NSDate date];
NSString *nowString = [dateFormatter stringFromDate:now];
NSString *testString = [testFormatter stringFromDate:now];
if ([testString isEqual:#"00"]) {
NSLog(#"%#", nowString];
}
}
Example output:
01:09:00
//.5 second interval
01:09:00
I haven't even bothered with the second half of this challenge yet because I got stumped here. This technically works, but I know I'm doing it wrong, since the output isn't dependent upon the program knowing the value of the minute has changed. Also, because the timer is set to fire every .5 seconds, I get two lines of output every minute instead of just one (which does not satisfy the specs).
Can anyone suggest where to go from here? This one really has my mind boggled.
If you can not modify the timer interval, the other alternative is to use an instance variable in your MinuteDisplay class, for example, displayString. And modify the minuteChange method as follows:
- (void)minuteChange:(NSTimer *)timer
{
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"HH:mm:ss"];
NSDateFormatter *testFormatter = [[NSDateFormatter alloc] init];
[testFormatter setDateFormat:#"ss"];
NSDate *now = [NSDate date];
NSString *nowString = [dateFormatter stringFromDate:now];
NSString *testString = [testFormatter stringFromDate:now];
if ([testString isEqual:#"00"]) {
if(![nowString isEqualToString:dispString]) {
dispString = nowString;
NSLog(#"*************** %#", dispString);
}
}
}
This will make sure that it is logged only once a minute
Working minuteChange method:
- (void)minuteChange:(NSTimer *)timer
{
NSDate *now = [NSDate date];
if (!self.lastTime) {
self.lastTime = [NSDate date];
}
if (now > self.lastTime) {
if ([[self.seconds stringFromDate:now] isEqualToString:#"00"]) {
printf("\n%s", [[self.output stringFromDate:now] UTF8String]);
self.lastTime = now;
}
}
self.output = [[NSDateFormatter alloc] init];
[self.output setDateFormat:#"HH:mm:ss"];
self.seconds = [[NSDateFormatter alloc] init];
[self.seconds setDateFormat:#"ss"];
}
Working secondChange method:
- (void)secondChange:(NSTimer *)timer
{
long secondsSince1970 = time(NULL);
if (!self.lastSecond) {
self.lastSecond = secondsSince1970;
}
if (secondsSince1970 > self.lastSecond) {
if (secondsSince1970 % 10 == 0) {
printf("|");
self.lastSecond = secondsSince1970;
} else {
printf(".");
self.lastSecond = secondsSince1970;
}
}
}
Changes to minuteChange:
The most important change was the addition of the lastTime ivar to the class. Now it's simple...if lastTime is null, assign it the value of the current date. If current time is greater than last time, test if it's a new minute and then output the time if it is. ONLY update lastTime if a new minute was output (this ensures that the time is only displayed once per minute).
secondChange:
Took a different approach with this one and now I'm wishing I had gone with straight C the first time around. This one is so simple! Check if the current second is greater than the last second. If so, check if it's divisible by 10. If so, print "|". If not, print ".". Super easy and actually more accurate than setting the timer to fire every second. Sheesh.
Alright, here is the skinny. I've searched on this but haven't found this question quite right. (I'm writing this in xcode fyi)
I have been tasked with something that should be easy and it probably is but I'm having trouble getting started...
I need to download JSON data and it is a list of objects that only have three items, date, tite, contents. Basically 3 strings. The date is not the date created but the date the whole object is intended for. The users are wanting to be able to preload a few weeks at a time w/o people being able to see the future dates.
I can download the JSON data no problem, I can display it in a list, not a problem. I am not certain how to make the program ignore objects with a date not equal to today.
Anyone have any insight into this? Below is what one of the test objects looks like.
#type: "Devotional",
#url: "http://api.storageroomapp.com/accounts/50ff0ad80f66027d84001680/collections/51c1ba270f6602499f0000ae/entries/51c1bc390f6602442c0002ec",
#collection_url: "http://api.storageroomapp.com/accounts/50ff0ad80f66027d84001680/collections/51c1ba270f6602499f0000ae",
#version: 2,
#trash: false,
#created_at: "2013-06-19T14:12:09Z",
#updated_at: "2013-07-08T19:38:51Z",
devotional_date: "2013-07-08",
devotional_title: "Test Today Devotional",
devotional_body: "This is a test of what Today's Daily Devotional would look like!"
},
Thanks in advance for any help.
Here is the basic idea for doing this comparison:
- (void)testDateIsToday {
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDate *now = [NSDate date];
NSInteger dateUnits = NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit;
NSDateComponents *dateParts = [gregorian components:dateUnits fromDate:now];
NSString *dateString = #"2013-07-08"; // Date from your JSON
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat = #"yyyy-MM-dd";
NSDate *requestedDate = [dateFormatter dateFromString:dateString];
NSDateComponents *requestedParts = [gregorian components:dateUnits fromDate:requestedDate];
NSLog(#"Equal? %i", [[gregorian dateFromComponents:requestedParts] compare:[gregorian dateFromComponents:dateParts]] == NSOrderedSame);
}
Note that this will do the comparison based on the time zone the device it runs on is set in, which I'm guessing will not impact you since you don't specify time zone in your JSON. Using a calendar and date components is the safest way to do such a comparison.