Core-Plot: Wrong date on x-Axis - xcode

Following different tutorials, I've successfully created a scatter plot using Core-Plot. Now, setting dates on X-Axis I'm obtaining totally wrong dates.
The source of my graph is an array containing a dictionary. In every record of the dictionary the first key of the dictionary is a unix timestamp and the second key, the value to draw. It looks like this:
(
{
0 = 1334152500;
1 = 0;
},
{
0 = 1334152800;
1 = 0;
},
{
0 = 1334153100;
1 = 0;
},
AFAIK Core-Plot Needs a start date and a step. In this case start date is 1334152500 (Wed, 11 Apr 2012 13:55:00 GMT) and step is 300 seconds. Every 300 seconds a new value is present.
Now the code I use to draw the X-axis:
// this string contains the first UNIX Timestamp registered
NSString *tstamp_start = [NSString stringWithFormat:#"%#", [[[self.graphData objectForKey:#"1"] objectAtIndex:0] objectForKey:#"0"]];
NSDate *refDate = [NSDate dateWithTimeIntervalSince1970:[tstamp_start doubleValue]];
// definition of the graph skipped...
CPTXYAxisSet *axisSet = (CPTXYAxisSet *)self.graph.axisSet;
// tInterval is previous set to 300 - float.
// here I should set the Interval between every value on graph...
axisSet.xAxis.majorIntervalLength = CPTDecimalFromFloat(tInterval);
axisSet.xAxis.axisLineStyle = axisLineStyle;
axisSet.xAxis.majorTickLineStyle = axisLineStyle;
axisSet.xAxis.minorTickLineStyle = axisLineStyle;
axisSet.xAxis.labelTextStyle = textStyle;
axisSet.xAxis.labelOffset = 3.0f;
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"dd/MM/yyyy hh:mma"];
CPTTimeFormatter *timeFormatter = [[CPTTimeFormatter alloc] initWithDateFormatter:dateFormatter];
timeFormatter.referenceDate = refDate;
axisSet.xAxis.labelFormatter = timeFormatter;
axisSet.xAxis.labelingPolicy = CPTAxisLabelingPolicyAutomatic;
axisSet.xAxis.orthogonalCoordinateDecimal = CPTDecimalFromFloat(yAxisMin);
(...)
The line is correctly shown, but on X Axis I'm reading values/labels like: '22/07/2054 06:35AM'. Year 2054? Without considering the timezone (local +2, unix +0) and CPTAxisLabelingPolicyAutomatic, at least I should read a date between 13:55 and now on current day. What I'm missing?
Thank's a lot!
Simon

The referenceDate is the offset applied to each data point when formatting. Therefore, the value of the first data point is being doubled. You either need to adjust the reference date or change the data values to start from 0.
NSDate *refDate = [NSDate dateWithTimeIntervalSince1970:0.0];

Related

Xcode preprocessor macro for dates

I want to "hardcode" an expiration date into my beta code. Right now I manually calculate a unix date and compare that to the current date time:
if([[NSDate date] timeIntervalSince1970]>1422748800) mustHalt = TRUE;
I'd like a way of replacing the 1422748800 with a macro that generates the equivalent number for a date 90 days in the future at compile time.
Any suggestions?
The predefined macro __DATE__ is what you need. Here is a SO question related to this. But maybe you want to use a code like this:
const int daysToExpire = 14;
NSString *compileDate = [NSString stringWithUTF8String:__DATE__];
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:#"MMM d yyyy"];
NSLocale *usLocale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US"];
[df setLocale:usLocale];
NSDate *expireDate = [df dateFromString:compileDate];
bool isExpired = ([[NSDate date] compare:expireDate] == NSOrderedDescending); // decide for it

Xcode time difference in days, hours, minutes and seconds

First of all: I want to say happy new year to everybody reading this!! May 2015 be a great year for all of us :-).
I'm busy with making a function which calculates the time difference between two dates. To be more precise: the time between a time and date given and the current time and date.
So the user selects a date in the past and then the program shows the time difference between the given date and todays date in a timer like so: "hh:mm:ss"
It works okay and updates every second when i select a time of todays date (01-01-2015 10:00:00), but when selecting a date and time in the past (31-12-2014 17:00:00) and compare it to todays date where the time is earlier than yesterday (01-01-2015 14:01:01), it gives me a negative time like a sort of countdown timer: -2:-59:-59.
But i want it to show the opposite of it: 21:01:01 and if possible if it exceeds the 24:00:00, just count on. For example 25:12:39.
This is the code that calculates the difference:
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:#"dd-MM-YYYY HH:mm:ss"];
NSDate *date1 = [df dateFromString:[NSString stringWithFormat:#"30-12-2014 %#", startedTime]];
NSDate *date2 = [df dateFromString:[NSString stringWithFormat:#"31-12-2014 %#", [self getCurrentTime]]];
NSTimeInterval interval = [date2 timeIntervalSinceDate:date1];
int hours = (int)interval / 3600; // integer division to get the hours part
int minutes = (interval - (hours*3600)) / 60; // interval minus hours part (in seconds) divided by 60 yields minutes
int seconds = (interval - (hours*3600) - (minutes*60)); // interval minus hours part (in seconds) divided by 60 yields minutes
NSString *timeDiff = [NSString stringWithFormat:#"%02d:%02d:%02d", hours, minutes, seconds];
_workingTime.text = [NSString stringWithFormat:#"%#",timeDiff];
Can someone please help?
[df setDateFormat:#"dd-MM-yyyy hh:mm:ss"];
Try after this change of the format string!
And this.. finally.
NSTimeInterval interval = [date2 timeIntervalSinceDate:date1];
if( interval < 0 ) {
interval = [date1 timeIntervalSinceDate:date2];
}
More about date formats here

UILocalNotifications repeatInterval using NSWeekdayCalendarUnit

OK, so I have seen several posts that say you cannot set a UILocalNotification to repeat any more or less than a few given options (every minute/hour/day/week/month etc.).
However, none of those posts addressed what setting the repeatInterval property of UILocalNotification to NSWeekdayCalendarUnit would do.
I'm very new to all this NSDate and NSCalendar stuff, so I am sure I am missing something, but I have read over the documentation and, it sounds like you CAN use NSWeekdayCalendarUnit to make a NSLocalNotification repeat say, every Monday, Tuesday and Thursday if NSWeekdayCalendarUnit is set to 2,3,5.
NSWeekdayCalendarUnit
Specifies the weekday unit.
The corresponding value is an int. Equal to kCFCalendarUnitWeekday. The weekday units are the numbers 1 through N (where for the Gregorian calendar N=7 and 1 is Sunday).
Is that not correct?
Thanks in advance.
Yes you can. I do it like this. The user can choose a scheme with a picker. And then the choice goes to the following method:
- (void)setOneLocalAlarmNotification: (NSDate *)firstFireDate withRepeat: (NSInteger)repeat {
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
if (localNotif == nil)
return;
localNotif.fireDate = firstFireDate;
localNotif.timeZone = [NSTimeZone defaultTimeZone];
localNotif.repeatCalendar = [NSCalendar currentCalendar];
switch(repeat) {
case 0:
break ;
case 1:
localNotif.repeatInterval = kCFCalendarUnitDay;
break;
case 2:
localNotif.repeatInterval = kCFCalendarUnitWeekday;
break;
default:
break;
}
// Notification details
localNotif.alertBody = #"Message?";
// Set the action button
localNotif.alertAction = #"Yes";
localNotif.soundName = #"glas.caf"; //UILocalNotificationDefaultSoundName;
localNotif.applicationIconBadgeNumber = 1;
// Specify custom data for the notification
NSDictionary *infoDict = [NSDictionary dictionaryWithObject:#"Alarm" forKey:#"type"];
localNotif.userInfo = infoDict;
// Schedule the notification
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
[localNotif release]
}

Why can't I control Core-Plot date-axis ticks?

I have a Core-Plot scatter plot that seems to be working great. The x axis shows date/time, the y axis a value from 0-500. I set up the x axis as follows:
plotSpace.xRange = [CPPlotRange plotRangeWithLocation:
CPDecimalFromFloat(maxTime - 2*60*60*24)
length:CPDecimalFromFloat(2.5*60*60*24)];
plotSpace.globalXRange = [CPPlotRange plotRangeWithLocation:
CPDecimalFromFloat(minTime - 1.5*60*60*24)
length:CPDecimalFromFloat(maxTime - minTime + 2*60*60*24)];
x.majorIntervalLength = CPDecimalFromFloat(12*60*60);
x.minorTicksPerInterval = 0;
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setDateFormat:#"M/d H:mm a"];
CPTimeFormatter *timeFormatter = [[[CPTimeFormatter alloc]
initWithDateFormatter:dateFormatter] autorelease];
timeFormatter.referenceDate = [NSDate
dateWithTimeIntervalSinceReferenceDate:0];
x.labelFormatter = timeFormatter;
My x-axis points are plotted as follows:
-(NSNumber *)numberForPlot:(CPPlot *)plot
field:(NSUInteger)fieldEnum
recordIndex:(NSUInteger)index
{
if(fieldEnum == CPScatterPlotFieldX) {
return [NSNumber numberWithDouble:[[(Entry *)
[datapoints objectAtIndex:index] datetime]
timeIntervalSinceReferenceDate]];
}
As far as I can tell, everything is being plotted accurately. BUT, for some reason, the ticks occur at 5 AM and 5 PM, rather than noon and midnight as I would prefer.
I've tried everything -- changing the xRange and globalXRange location and length, altering my dataset, etc. But every time the labels reappear at 5 AM and 5 PM. Can you help? Thanks!
5 hours sounds like a time zone problem. Try setting the timeZone property on your dateFormatter to [NSDateFormatter timeZoneForSecondsFromGMT:0].

Calculate time difference in Cocoa

I have got two timevalues in the format: %H%M%S (E.G.161500)
These values are text-based integers.
Is there a simple function in Cocoa that calculates the difference between these two integers using a 60 seconds and minutes scale?
So if
time 1 = 161500
time 2 = 171500
timedifference = 003000
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setDateFormat:#"HHmmss"];
NSDate *date1 = [dateFormatter dateFromString:#"161500"];
NSDate *date2 = [dateFormatter dateFromString:#"171500"];
NSTimeInterval diff = [date2 timeIntervalSinceDate:date1]; // diff = 3600.0
The class for manipulating dates is NSDate. The method for getting time intervals is -timeIntervalSinceDate:. The result is a NSTimeInterval value, which is a double representing the interval in seconds.
You can create a NSDate object from a NSString with +dateWithString:, provided that your date is formatted as 2001-03-24 10:45:32 +0600.
try this code.
- (NSTimeInterval)intervalBetweenDate:(NSDate *)dt1 andDate:(NSDate *)dt2 {
NSTimeInterval interval = [dt2 timeIntervalSinceDate:dt1];
NSLog(#"%f",interval);
return interval;
}
I would create an NSFormatter subclass to parse time values in that format from input data (you can put one on a text field to automatically convert user input, or use it to parse from a data source in code). Have it return the combined number of seconds as an NSTimeInterval (double representing seconds) wrapped in an NSNumber. From there it's easy to subtract the difference, and display it using the same NSFormatter class you created. In both parsing and displaying values, you're the one responsible to write code converting from seconds to hours:minutes:seconds or whatever format you like. You could also convert these values to an NSDate like mouviciel mentioned, if it makes sense for your application. Just keep in mind you're always going to be storing the time difference from a reference date, usually Jan 1st 1970 (NSDate has methods to do this for you).

Resources