Objective-C ustawiając NSDate na bieżący UTC

80

Czy istnieje łatwy sposób na zainicjowanie NSDatez aktualną datą / godziną UTC?

Brodie
źródło
1
Zadziała [NSDate date]? Nie jestem pewien, czy to UTC.
zneak
2
Nie ma czegoś takiego jak NSDateustawienie UTC, nie ma z nim skojarzonej strefy czasowej.
Nick Forge
3
@MurraySagal Jesteś nieprawidłowy - NSDatereprezentuje chwilę w czasie (nazwa NSDatejest trochę myląca). Opisując czas, taki jak „pierwsza chwila 1 stycznia 2001 r.”, Potrzebujesz strefy czasowej, aby określić, o jakiej dokładnie chwili w czasie mówisz, ale po NSDateutworzeniu nie ma z nią skojarzonej strefy czasowej.
Nick Forge,
1
@NickForge Data NSDate jest tworzona jako „pierwsza chwila 1 stycznia 2001 r. GMT”, określony czas w określonej strefie czasowej, i ten fakt jest niezmienny i niezwykle ważny dla tego, dlaczego daty działają tak, jak działają. Jeśli jesteśmy w różnych strefach czasowych i zarejestrowaliśmy to w tym samym momencie, NSLog(@"since1970= %f", [[NSDate date] timeIntervalSince1970]);wynik jest taki sam. Czemu? Ponieważ jest to odniesienie do określonego punktu w czasie w określonej strefie czasowej (GMT), bez względu na to, gdzie znajduje się użytkownik. Fakt, że jest on względny w stosunku do GMT, nie znika po utworzeniu. Bez tej kotwicy daty byłyby arbitralne.
Murray Sagal,
2
@MurraySagal Oboje macie rację na różne sposoby, ale Nick ma więcej racji, mówiąc „Nie ma czegoś takiego jak NSDateustawiony na UTC”, ponieważ nie możesz ustawić strefy czasowej NSDatei mylisz się, mówiąc to ma „strefę czasową”. Prawdą jest, że jest zdefiniowany w odniesieniu do określonej strefy czasowej, ale stwierdzenie, że „ma” strefę czasową, oznacza, że ​​strefa czasowa jest własnością NSDate, a to nie jest prawda.
devios1

Odpowiedzi:

148

[NSDate date];

Możesz utworzyć kategorię, która robi coś takiego:

-(NSString *)getUTCFormateDate:(NSDate *)localDate
{
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:@"UTC"];
    [dateFormatter setTimeZone:timeZone];
    [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    NSString *dateString = [dateFormatter stringFromDate:localDate];
    [dateFormatter release];
    return dateString;
}
jessecurry
źródło
2
NSTimeZone * timeZone = [NSTimeZone timeZoneWithName: @ "UTC"]; [dateFormatter setTimeZone: timeZone]; to przydało się dzięki
Brodie
1
jeśli to przenosi się do produkcji, możesz faktycznie chcieć utworzyć statyczny dateFormatter, który jest inicjalizowany z opóźnieniem. Tworzenie dateFormatter jest w rzeczywistości dość kosztowne.
jessecurry
3
Potrzebuję go jako obiektu daty, a nie jako ciągu, co mogę zrobić w tym przypadku?
Maystro
1
Daty istnieją niezależnie od stref czasowych, strefa czasowa jest wykorzystywana jedynie do produkcji produktów przeznaczonych do spożycia przez ludzi.
jessecurry
@jessecurry Nie do końca prawda. Z odwołania do klasy NSDate: „Ta metoda zwraca wartość czasu w odniesieniu do bezwzględnej daty odniesienia - pierwsza chwila 1 stycznia 2001 r. GMT”. Zwróć uwagę na jasne i konkretne odniesienie do GMT.
Murray Sagal
13

NSDate to odniesienie do przedziału od bezwzględnej daty odniesienia, 1 stycznia 2001 r. 00:00 GMT. Zatem metoda klasy [NSDate date] zwróci reprezentację tego interwału. Aby przedstawić te dane w formacie tekstowym w UTC, wystarczy użyć NSDateFormatter z odpowiednią strefą NSTimeZone (UTC), aby renderować w razie potrzeby.

rcw3
źródło
3
Uważam, że [NSDate now] powinno być [NSDate date] w tej odpowiedzi.
foldinglettuce
2

Obiekty NSDate hermetyzują pojedynczy punkt w czasie, niezależnie od konkretnego systemu kalendarza lub strefy czasowej. Obiekty daty są niezmienne i reprezentują niezmienny przedział czasu w stosunku do bezwzględnej daty odniesienia (00:00:00 czasu UTC 1 stycznia 2001 r.).

Wersja Swift:

extension NSDate {
    func getUTCFormateDate() -> String {
        let dateFormatter = NSDateFormatter()
        let timeZone = NSTimeZone(name: "UTC")
        dateFormatter.timeZone = timeZone
        dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
        return dateFormatter.stringFromDate(self)
    }
}
Aleksander Tichonow
źródło