我制作的移动应用程序使用来自我无法控制的.NET服务器的Web服务。
在安排不同时区的事件时,我们总是遇到麻烦。
服务器在EST时间,来自Web服务的大部分数据以这种方式呈现。
我们最终不得不添加显示日期字段,这非常令人困惑。
此外,我的代码基本上是相同的,除非它取决于我是否正在与服务器通信或者我是否在设备上计算某些内容。也是一种痛苦。
以下是我处理EST时间的例子:
- (void)initWithWebServiceData:(NSDictionary *)data {
self.scheduleDate = [self dateFromDotNetJSONString:data[@"ScheduleDate"]];
//...and other stuff
}
- (NSDate *)dateFromDotNetJSONString:(NSString *)stringInEST {
int secondsESToffset = 14400;
static NSRegularExpression *dateRegEx = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
dateRegEx = [[NSRegularExpression alloc] initWithPattern:@"^\\/date\\((-?\\d++)(?:([+-])(\\d{2})(\\d{2}))?\\)\\/$" options:NSRegularExpressionCaseInsensitive error:nil];
});
NSTextCheckingResult *regexResult = [dateRegEx firstMatchInString:stringInEST options:0 range:NSMakeRange(0, [stringInEST length])];
if (regexResult) {
// milliseconds
NSTimeInterval seconds = [[stringInEST substringWithRange:[regexResult rangeAtIndex:1]] doubleValue] / 1000.0;
// timezone offset
if ([regexResult rangeAtIndex:2].location != NSNotFound) {
NSString *sign = [stringInEST substringWithRange:[regexResult rangeAtIndex:2]];
// hours
seconds += [[NSString stringWithFormat:@"%@%@", sign, [stringInEST substringWithRange:[regexResult rangeAtIndex:3]]] doubleValue] * 60.0 * 60.0;
// minutes
seconds += [[NSString stringWithFormat:@"%@%@", sign, [stringInEST substringWithRange:[regexResult rangeAtIndex:4]]] doubleValue] * 60.0;
}
return [NSDate dateWithTimeIntervalSince1970:seconds - secondsESToffset];
}
return nil;
}
- (void)requestRegistrationForEvent
{
NSString *fullDateTime = [NSString stringWithFormat:@"%@ %@", [self.scheduleDate webServiceStringValue], [self.scheduleDate dateTimeText]];
[self.dataController requestRegistrationForEvent:[self.eventID stringValue]
onDate:fullDateTime];
}
- (NSString *)webServiceStringValue {
NSString *webServiceStringValue = nil;
if ([self isKindOfClass:NSDate.class]) {
NSDate *date = (NSDate *)self;
//format the date how the web service expects it
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"M/d/yyyy"];
NSTimeZone *gmt = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];
[dateFormatter setTimeZone:gmt];
webServiceStringValue = [dateFormatter stringFromDate:date];
}
return webServiceStringValue;
}
- (NSString *)dateTimeText {
NSString *text = @"";
NSDate *date;
if ([self isKindOfClass:NSDate.class]) {
date = (NSDate *)self;
NSDateFormatter *timeFormatter = [[NSDateFormatter alloc] init];
[timeFormatter setDateFormat:@"h:mm a"];
NSTimeZone *gmt = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];
[timeFormatter setTimeZone:gmt];
text = [timeFormatter stringFromDate:date];
text = [text lowercaseString];
text = [text stringByReplacingOccurrencesOfString:@" " withString:@""];
}
return text;
}
我做错了什么,我可以向我的.NET合作伙伴推荐什么来处理时区?
答案 0 :(得分:1)
移动行业标准与集成和国际时间标准的区别并非如此:时间戳应始终使用偏移或UTC(祖鲁)时间。 GMT是一个时区,就像EST一样,因此UTC更适合作为通用时间。事实上,GMT没有观察夏令时,所以它通常是可以互换的。您的合作伙伴应使用UTC标准发送时间戳:https://en.wikipedia.org/wiki/ISO_8601,如2014-11-09T10:37:27+00:00
或zulu:2014-11-09T10:37:27Z
。有时人们使用2014-11-09 10:37:27UTC
等变体,但您可以为其中任何一个构建日期格式化程序。
日期格式为dateFormatter.dateFormat = @"yyyy-MM-dd'T'HH:mm:ss.SSSz"
。我通常将UTC日期格式工厂放入NSDateFormatter类别。
如果这一天是唯一重要的事情而且确切的时间确实没有,那么你的方法应该足够了,除了你还需要无时间格式化时间戳产生的任何东西或使用日历进行计算。 / p>