views:

892

answers:

2

I'm writing some code to acquire images that live on a server. The image filenames are in yyyyMMdd_HHmm format (in UTC) and generated every 3 hours (1200,1500,1800,..etc). When the code starts, I get the current UTC date and extract the time. I then create an NSDateComponent from this, and looking at the current time, set the hour of the NSDateComponent to the hour of the next image. Very strangely, if I set the hour to 3, the NSDate I get back from NSCalendar dateFromComponents has a different hour... what gives? (I have added in the console output as well).

// get current time in UTC
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
NSTimeZone *UTC = [NSTimeZone timeZoneWithName:@"UTC"];
[dateFormatter setTimeZone:UTC];

//  get the current hour & min
[dateFormatter setDateFormat:@"HHmm"];
NSDate *today = [NSDate date];
NSString *str = [dateFormatter stringFromDate:today];
NSInteger hour = [str integerValue];
NSLog(str);

// find next image hour
NSCalendar *cal = [[NSCalendar alloc]   initWithCalendarIdentifier:NSGregorianCalendar];
unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit |  NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit;
NSDateComponents *currentImageDateComps = [cal components:unitFlags fromDate:today];

if (hour > 2100) {
    [currentImageDateComps setHour:0];
    // add an extra day as next image is start of new day
    [currentImageDateComps setDay:[currentImageDateComps day]+1];

} else if (hour < 300) {
    [currentImageDateComps setHour:3];
} else if (hour < 600) {
    [currentImageDateComps setHour:6];
} else if (hour < 900) {
    [currentImageDateComps setHour:9];
} else if (hour < 1200) {
    [currentImageDateComps setHour:12];
} else if (hour < 1500) {
    [currentImageDateComps setHour:15];
} else if (hour < 1800) {
    [currentImageDateComps setHour:18];
} else if (hour < 2100) {
    [currentImageDateComps setHour:21];
}
[currentImageDateComps setMinute:0];


NSLog(@"hour %d", [currentImageDateComps hour]);
NSLog(@"minute %d", [currentImageDateComps minute]);
// construct the date
NSDate *currentImageDate = [cal dateFromComponents:currentImageDateComps];
[dateFormatter setDateFormat:@"yyyyMMdd_hhmm"];
NSString *nextImage = [dateFormatter stringFromDate:currentImageDate];

self.currentFilename = [nextImage stringByAppendingString:@".png"];
NSLog(self.currentFilename);

The console output produced from the NSLogs is this. I get a value of 3 for hour but it gets returned as '1700'?

2010-01-25 12:25:02.049 Forecast[8447:207] viewDidLoad

2010-01-25 12:25:02.052 Forecast[8447:207] 0225

2010-01-25 12:25:02.052 Forecast[8447:207] hour 3

2010-01-25 12:25:02.053 Forecast[8447:207] minute 0

2010-01-25 12:25:02.053 Forecast[8447:207] 20100124_1700.png

(I'm aware there are some memory release issues but I want to get it functional first..)

+1  A: 

What's wrong with:

NSString *nextImage = [NSString stringWithFormat:@"%04d%02d%02d_%02d%02d.png", [currentImageDateComps year], [currentImageDateComps month], [currentImageDateComps day], [currentImageDateComps hour], [currentImageDateComps minute]];

and

self.currentFilename = nextImage;

David Kanarek
Yes, it works *where you can be definitely sure that none of the parms are outside a valid time range*. In fact, as self.currentFilename is an NSString I can simply use 'self.currentFilename = [NSString stringWithFormat:@".... But if you want to generate dates, say by looping and incrementing hours, you will get invalid dates. In this case, [cal dateFromComponents:..] will produce valid dates....given your timezone is ok :-)
timbo
+3  A: 

A time zone issue maybe?

Ken Aspeslagh
Yes, it appears this is the problem. I'm guessing that when you create an NSCalendar it uses your default timezone. My NSDateFormatter had timezone set to UTC however the NSDateComponents derived from the NSCalendar did not, and thus the difference. I haveadded [cal setTimeZone:UTC] after creating the NSCalendar object and all my dates/times are now what I would expect.
timbo