我在将时间字符串转换为其他时区时遇到问题。
这是我从服务器检索的字符串示例:@“5/14/2013 4:19 am”
我知道timeZone是America / New_York,我想将其转换为我当地的时区:欧洲/罗马。
以下是我为测试而编写的代码:
-(void) convertTimeZone
{
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.timeZone=[NSTimeZone timeZoneWithAbbreviation:@"GMT"];
dateFormatter.dateFormat=@"MM/dd/yyyy HH:mma";
NSString *sourceDateString = @"5/14/2013 4:19am";
NSTimeZone *sourceTimeZone = [[NSTimeZone alloc] initWithName:@"America/New_York"];
NSTimeZone *destinationTimeZone = [NSTimeZone localTimeZone];
NSInteger sourceGMToffset = sourceTimeZone.secondsFromGMT;
NSInteger destinationGMToffset = destinationTimeZone.secondsFromGMT;
NSInteger interval = destinationGMToffset-sourceGMToffset;
NSLog(@"DateFormatter TimeZone: %@", dateFormatter.timeZone);
NSLog(@"Source TimeZone: %@", sourceTimeZone);
NSLog(@"Destination TimeZone: %@", destinationTimeZone);
NSLog(@"sourceOffset: %u destinationOffset: %u interval: %u", sourceGMToffset, destinationGMToffset, interval);
NSLog(@"----------------------------------------------------------------------------------------------------");
NSLog(@"sourceDateString : %@", sourceDateString);
//Convert from string to date
NSDate *dateObject = [dateFormatter dateFromString:sourceDateString];
NSLog(@"From string to date: %@", dateObject);
//Now back from date to string
NSLog(@"From date to string: %@", [dateFormatter stringFromDate:dateObject]);
//Convert from sourceTimeZone to destinationTimeZone
NSDate *newDate = [[NSDate alloc] initWithTimeInterval: interval sinceDate:dateObject];
NSLog(@"destinationDateString: %@", [dateFormatter stringFromDate: newDate]);
}
的输出 :
DateFormatter TimeZone:GMT(GMT)偏移0
来源TimeZone:America / New_York(GMT-04:00)偏移-14400(日光)
目的地时区:当地时区(欧洲/罗马(CEST)偏移7200(日光))
sourceOffset:4294952896 destinationOffset:7200 interval:21600
sourceDateString:5/14/2013 4:19 am
从字符串到日期:2013-05-14 00:19:00 +0000
从日期到字符串:05/14/2013 00:19 AM
destinationDateString:05/14/2013 06:19 AM
我生气了!!!!
如果原始日期是“2013年5月14日上午4:19”,为什么日期格式化程序将其更改为“05/14/2013 00:19 AM”????????? 如果它已正确保存到“05/14/2013 04:19 AM +0000”,转换将是完美的(两个时区之间6小时)!!!
任何提示?
由于
尼古拉
修改
按照lithu-t-v建议设置这些参数:
dateFormatter.timeZone=[NSTimeZone timeZoneWithAbbreviation:@"GMT"];
NSString *sourceDateString = @"5/14/2013 4:19am -0400";
似乎有效,但事实并非如此。
我说“似乎”因为:
sourceDateString:5/14/2013 04:19 am -0400
从字符串到日期:2013-05-13 04:19:00 +0000(确定)
从日期到字符串:05/14/2013 04:19(好)
destinationDateString:05/14/2013 10:19(正确)
是正确但是如果我尝试下午晚些时候:
sourceDateString:5/14/2013 10:19 pm -0400
从字符串到日期:2013-05-14 16:19:00 +0000(错误)
从日期到字符串:05/14/2013 16:19
destinationDateString:05/14/2013 22:19(错!)
正确的结果应该是:05/15/2013 04:19 AM
答案 0 :(得分:1)
+0000组件定义带时区的日期并提供实际时间。一个NSDate对象也包含此部分。因为缺少部分时间差,相对于本地时区
这里你停止了时区,但没有设置为datefromatter。设置时区到dateformatter并尝试
将+0000附加到字符串并执行剩余的操作。它将起作用
答案 1 :(得分:0)
谢谢大家的所有提示! 经过大量的试验,我结束了编写一个使用DateComponent的函数:
-(NSString*) convertToLocalTimeZoneDate: (NSString*) sourceDate
Time: (NSString*) sourceTime
{
//Date and time parsing
//Expected: NSString *sourceDate = @"5/13/2013";
//Expected: NSString *sourceTime = @"04:19am";
NSArray *dateArray = [sourceDate componentsSeparatedByString:@"/"];
NSDateComponents *dateComps = [[NSDateComponents alloc] init];
dateComps.calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
dateComps.year = [[dateArray objectAtIndex:2] integerValue];
dateComps.month = [[dateArray objectAtIndex:0] integerValue];
dateComps.day = [[dateArray objectAtIndex:1] integerValue];
NSString *timeInDay = [sourceTime substringFromIndex:5];
if ([[timeInDay uppercaseString] isEqualToString:@"PM"]){
dateComps.hour = 12 + [[sourceTime substringWithRange:NSMakeRange(0, 2)] integerValue];
} else {
dateComps.hour = [[sourceTime substringWithRange:NSMakeRange(0, 2)] integerValue];
}
dateComps.minute = [[sourceTime substringWithRange:NSMakeRange(3, 2)] integerValue];
dateComps.timeZone = [[NSTimeZone alloc] initWithName:@"America/New_York"];
NSLog(@"Original Date Time: %@ %@", sourceDate, sourceTime);
NSLog(@"GMT Date Time: %@", dateComps.date);
//Return a string with the local date and time
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.locale = [NSLocale currentLocale];
dateFormatter.dateStyle = NSDateFormatterShortStyle;
dateFormatter.timeStyle = NSDateFormatterLongStyle;
return[dateFormatter stringFromDate:dateComps.date];
}
返回正确的输出:
原始日期时间:2013年5月13日上午04:19(我知道它是America / New_York)
GMT日期时间:2013-05-13 08:19:00 +0000(好)
输出:13/05/13 10:19:00 CEST
答案 2 :(得分:0)
这就是你想要的:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat=@"dd/MM/yyyy h:mma"; // Note: lower case h
NSString *sourceDateString = @"14/5/2013 5:19am"; // in New Yourk
NSTimeZone *sourceTimeZone = [[NSTimeZone alloc] initWithName:@"America/New_York"];
NSTimeZone *destinationTimeZone = [NSTimeZone localTimeZone];
dateFormatter.timeZone = sourceTimeZone;
NSLog(@"DateFormatter TimeZone: %@", dateFormatter.timeZone);
NSLog(@"Source TimeZone: %@", sourceTimeZone);
NSLog(@"Destination TimeZone: %@", destinationTimeZone);
NSLog(@"---------------------------------------");
NSLog(@"sourceDateString : %@", sourceDateString);
//Convert from string to date
NSDate *dateObject = [dateFormatter dateFromString:sourceDateString];
NSLog(@"From string to date should be in GMT: %@", dateObject);
//Convert from sourceTimeZone to destinationTimeZone
dateFormatter.timeZone = destinationTimeZone;
NSLog(@"Hopefully works: %@", [dateFormatter stringFromDate: dateObject]);
输出:
Test Case '-[TestOrderedList testFoo]' started.
2013-05-15 11:44:04.263 LogicSim[43238:303] DateFormatter TimeZone: America/New_York (EDT) offset -14400 (Daylight)
2013-05-15 11:44:04.264 LogicSim[43238:303] Source TimeZone: America/New_York (EDT) offset -14400 (Daylight)
2013-05-15 11:44:04.264 LogicSim[43238:303] Destination TimeZone: Local Time Zone (Europe/London (BST) offset 3600 (Daylight))
2013-05-15 11:44:04.264 LogicSim[43238:303] ---------------------------------------
2013-05-15 11:44:04.264 LogicSim[43238:303] sourceDateString : 14/5/2013 5:19am
2013-05-15 11:44:04.265 LogicSim[43238:303] From string to date should be in GMT: 2013-05-14 09:19:00 +0000
2013-05-15 11:44:04.265 LogicSim[43238:303] Hopefully works: 14/05/2013 10:19AM
Test Case '-[TestOrderedList testFoo]' passed (0.002 seconds).
您犯的第一个错误是日期格式规范HH
是24小时格式的时间。当与am / pm说明符一起使用时,这似乎总是将小时解析为0.您的测试数据巧合地有一个小时4,这与GMT和纽约之间的偏移相同,导致您假设它刚刚获得抵消错误。我将小时说明符更改为h
以获得12小时的时间。我也改变了测试时间,使其不那么混乱。
第二个错误是弄乱了NSDate对象,那种方式就是疯狂。 GMT中的NSDates 始终。不要添加或减去时间间隔来更正时区,只需在日期格式化程序中正确设置时区即可。所以我的代码将时区设置为纽约并解析日期。然后它将时区设置为当地时间(我在BST的英国)并将日期字符串化。任务完成。