将任何日期转换为本地日期问题

时间:2013-07-26 11:16:46

标签: objective-c macos cocoa nsdate nsdateformatter

由于时区问题,我被卡在NSDateNSDateFormatter的某处。

我只需要以UTC(将其转换为unix时间)向服务器发送时间。

以下是我正在做的几个步骤:

  1. 应使用当前时间添加日历中的日期并转换为UTC。

  2. 将所选日期与当前日期进行比较。只是想知道所选日期是过去日期还是将来日期。 (根据过去/未来/当前日期,很少有其他操作要做。)

  3. 我试过这段代码:

    NSDate上的类别中:

    -(NSDate *) toLocalTime{
        NSDate* sourceDate = self;
        NSTimeZone* sourceTimeZone = [NSTimeZone timeZoneWithName:@"UTC"];
        NSTimeZone* destinationTimeZone = [NSTimeZone systemTimeZone];
    
        NSInteger sourceGMTOffset = [sourceTimeZone secondsFromGMTForDate:sourceDate];
        NSInteger destinationGMTOffset = [destinationTimeZone secondsFromGMTForDate:sourceDate];
        NSTimeInterval interval = destinationGMTOffset - sourceGMTOffset;
    
        NSDate* destinationDate = [[NSDate alloc] initWithTimeInterval:interval sinceDate:sourceDate];
    
        return destinationDate;
    }
    

    但是当我尝试将日期转换为本地时存在问题(有时我不确定当前时间是否在本地时区)。如果它们是UTC,那么上面的方法工作正常。

    如果时间已经在当地时区,则会再次添加interval ,我的时间不正确。

    我没有想法,请帮助我。

    任何想法都将受到高度赞赏。

1 个答案:

答案 0 :(得分:1)

NSDate表示1970年1月1日以来的UTC时间。永远不要试图假装它是别的。永远不要试图将NSDate视为特定的当地时间。

所需要的是日历中的日期+偏移量,表示自今天午夜起的时间。

今天上午0:00 UTC,你首先需要一个格林历日历作为UTC时区。

NSTimeZone* utcTimeZone = [NSTimeZone timeZoneWithName:@"UTC"];
NSCalendar* gregorian = [[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar];
[gregorian setTimeZone: utcTimeZone];

现在您使用日期组件来获取自UTC午夜以来的小时,分​​钟和秒钟

NSUInteger unitFlags = NSHourCalendarUnit | NSMinuteCalendarUnit |  NSSecondCalendarUnit;
NSDate *date = [NSDate date];
NSDateComponents *comps = [gregorian components: unitFlags fromDate:date];

如果您的日历是日期的午夜UTC,那么您可以获得午夜UTC +您的小时,分​​钟和秒数:

NSDate* theDateIWant = [gregorian dateByAddingComponents: comps 
                                                 toDate: midnightUTCDateFromCalendar
                                                options: 0];
NSLog(@"The final date is %@", theDateIWant);