0

I am retrieving some dates from a remote server. Unfortunately one of the possible formats is just h:mm:a

Example of data I downloaded yesterday May, 21, 2013:

1) 04:36PM EDT

2) 11:51PM EDT

The data server TimeZone is "America/New_York".

My data TimeZone is "Europe/Rome".

This is the code I've written and until this morning at 5am I thought it worked:

NSDate *myDate = @"04:36PM EDT"; //11:51PM EDT (I know the date is May, 21 2013 but it is not in the data!)

NSArray *component = [mydate componentsSeparatedByString:@" "];

//Remove any reference to the TimeZone
//set it in the dateFormatter

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat =@"MM dd yyyy h:mma";
dateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];
dateFormatter.timeZone = [[NSTimeZone alloc] initWithName:@"America/New_York"];

//Create a valid date for the hour

NSDate *date = [NSDate date];
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *dateComponents = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:date];

NSDate *dateObject = [self.dateFormatter dateFromString: [NSString stringWithFormat:@"%u %u %u %@",
                dateComponents.month,
                dateComponents.day,
                dateComponents.year,
                [component objectAtIndex:0]]];

//Convert to local timeZone             

dateFormatter.timeZone = [NSTimeZone localTimeZone]; //  @"Europe/Rome"
dateFormatter.dateStyle = NSDateFormatterShortStyle;
dateFormatter.timeStyle = NSDateFormatterLongStyle;


NSString *localTimeZoneDate = dateFormatter stringFromDate:[dateObject];

NSLog(@"Local Time Zone Date = %@", localTimeZoneDate);

Output

While yesterday the code seemed to work fine because when I made the tests I still was in the 6 hour timespan that kept me in the same day, the May 21, this morning I found it doesn't. The problem is in the creation of the right date.

1) 04:36PM EDT ----> 22/05/2013 22:36:00 CEST

The correct output should have been 21/05/2013 22:36 CEST

2) 11:51PM EDT ----> 23/05/2013 05:51:00 CEST

The correct output should have been 22/05/2013 05:51 CEST

What would be the best code to handle this special case?

Thanks

Nicola

nico9T
  • 2,496
  • 2
  • 26
  • 44
  • After you have the date components for the day, why don't you add the time values to it? You should try to work in UTC and then apply your time zone at the end for display. – Wain May 22 '13 at 06:48

3 Answers3

0

Try

NSString *dateString = @"04:36PM EDT"; //11:51PM EDT (I know the date is May, 21 2013 but it is not in the data!)

NSArray *component = [dateString componentsSeparatedByString:@" "];

//Remove any reference to the TimeZone
//set it in the dateFormatter

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat =@"MM dd yyyy";
dateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];
dateFormatter.timeZone = [[NSTimeZone alloc] initWithName:@"America/New_York"];

NSString *tempDateString = [dateFormatter stringFromDate:[NSDate date]];
dateString = [tempDateString stringByAppendingFormat:@" %@",component[0]];

dateFormatter.dateFormat =@"MM dd yyyy hh:mma";
NSDate *tempDate = [dateFormatter dateFromString:dateString];

dateFormatter.timeZone = [NSTimeZone localTimeZone]; 
dateFormatter.dateStyle = NSDateFormatterShortStyle;
dateFormatter.timeStyle = NSDateFormatterLongStyle;

NSString *localDateString = [dateFormatter stringFromDate:tempDate];

NSLog(@"Local Time Zone Date = %@", localDateString);
Anupdas
  • 10,211
  • 2
  • 35
  • 60
  • The output is the same as my code: "04:36PM EDT" is converted to "22-05/2013 22:36:00 CEST" instead of "21 05 2013 22:36:00 CEST". The same for the 11:51PM EDT case. – nico9T May 22 '13 at 07:42
  • @NicolaP. It's very difficult to do this with a guess work. How are you planning to do this when you need to do this conversion after two days. It's better to include all the necessary info in the string. You can use the formatter to display which information you want to show. – Anupdas May 22 '13 at 08:48
  • You made a valid point but unfortunately the date string I get from the server is just "04:36PM EDT", no way to have another format :( When more than a day is passed it changes automatically the format adding the month and the day so I can guess with high probabilities that when I only see hours:minutes:timezone the data are about TODAY (or the day before, according to the timezone). If it is May 22 on my timezone and the data says "04:36PM EDT" I can be almost sure it refers to the day before in the original timezone. – nico9T May 22 '13 at 09:04
0

I haven't checked this yet, but I think it is because the calendar you create is for yuor time zone. Try setting the calendar timezone to America/New York before getting the date components out.

JeremyP
  • 84,577
  • 15
  • 123
  • 161
  • Initially I thought that what you suggest it could have been an easy and ideal solution but then I realized that can easily breaks. Between New York and Rome there are 6 hours. Original date is "04:36PM EDT" (we know it refers to May 21 in New York). This is a "last update change", it won't change anymore until the next day (May 22 in New York). If I use your trick before the day change in New York it works fine. But suppose I ask the date when in Europe/Rome it's 15:00PM of the May, 22. In New York it would be 09:00AM of the May,22. But the "04:36PM EDT" refers to May 21. – nico9T May 24 '13 at 07:20
  • @NicolaP. I don't follow. If it's 1500 in Rome, it's 2100 in New York. – JeremyP May 24 '13 at 11:00
  • I explain. Today is May 25. There are 6 hours between Rome and New York(EDT) so if it is 15:00 in Rome it is 09:00 in New York. The date I am retrieving refers to the closing price of a stock index, and it will be around 16:30 in New York, the 22:30Rome time.So, despite being the May 25 both in Rome and in New York the price refers to the May 24 and it won't change until the market reopen the morning of the 25 in New York. I fixed comparing the synthetic date against the current local date. – nico9T May 24 '13 at 16:14
0

For now I am doing this: I look if the recreated date in local time is in the future in respect to the current hour local time. If yes it should be enough to remove one or more days from the recreated date.

nico9T
  • 2,496
  • 2
  • 26
  • 44