2016-10-19 33 views
9

Bierze się bieżący czas, w UTC, i umieszczam go w nanaosekundach, a następnie muszę wziąć nanosekundy i wrócić do daty w czasie lokalnym. Jestem w stanie uzyskać czas na nanosekundy, a następnie wrócić do łańcucha daty, ale czas staje się zawiły, gdy przechodzę z ciągu znaków do daty.Data do milisekund i na bieżąco w Swift

//Date to milliseconds 
    func currentTimeInMiliseconds() -> Int! { 
      let currentDate = NSDate() 
      let dateFormatter = DateFormatter() 
      dateFormatter.dateFormat = format 
      dateFormatter.timeZone = NSTimeZone(name: "UTC") as TimeZone! 
      let date = dateFormatter.date(from: dateFormatter.string(from: currentDate as Date)) 
      let nowDouble = date!.timeIntervalSince1970 
      return Int(nowDouble*1000) 
     } 

    //Milliseconds to date 
    extension Int { 
     func dateFromMilliseconds(format:String) -> Date { 
      let date : NSDate! = NSDate(timeIntervalSince1970:Double(self)/1000.0) 
      let dateFormatter = DateFormatter() 
      dateFormatter.dateFormat = format 
      dateFormatter.timeZone = TimeZone.current 
      let timeStamp = dateFormatter.string(from: date as Date) 

let formatter = DateFormatter() 
      formatter.dateFormat = format 
      return (formatter.date(from: timeStamp))! 
     } 
    } 

// Znacznik czasu jest poprawna, ale data nie jest zwracana

+1

Jaki jest cel konwertowania daty na łańcuch znaków i powrót do niej (w currentTimeInMiliseconds() ')? – vadian

+0

Firma, w której pracuję, przechowuje wszystkie daty w milisekundach. – user1079052

+1

Ale jaka jest data podwójnej konwersji -> ciąg -> data i jaki jest dany "format", którego brakuje w kodzie? – vadian

Odpowiedz

44

Nie rozumiem dlaczego robisz coś z ciągów ...

extension Date { 
    var millisecondsSince1970:Int { 
     return Int((self.timeIntervalSince1970 * 1000.0).rounded()) 
    } 

    init(milliseconds:Int) { 
     self = Date(timeIntervalSince1970: TimeInterval(milliseconds/1000)) 
    } 
} 


Date().millisecondsSince1970 // 1476889390939 
Date(milliseconds: 0) // "Dec 31, 1969, 4:00 PM" (PDT variant of 1970 UTC) 
+0

Robię ciąg, ponieważ potrzebuję millisecondsSince1970, aby być w UTC i init (milliseconds: Int) być przywrócić w czasie lokalnym. – user1079052

+2

Obiekty daty są * zawsze * w UTC. Te wartości w moim przykładzie to UTC (zauważ, że metoda opisu renderuje epokę UTC zaczynającą się w PDT). –

+2

Lepiej zrobić init (milliseconds: Double) zamiast Int lub w przeciwnym razie stracisz milisekundy podczas konwersji. – dickyj

2
let dateTimeStamp = NSDate(timeIntervalSince1970:Double(currentTimeInMiliseconds())/1000) //UTC time //YOUR currentTimeInMiliseconds METHOD 
let dateFormatter = NSDateFormatter() 
dateFormatter.timeZone = NSTimeZone.localTimeZone() 
dateFormatter.dateFormat = "yyyy-MM-dd" 
dateFormatter.dateStyle = NSDateFormatterStyle.FullStyle 
dateFormatter.timeStyle = NSDateFormatterStyle.ShortStyle 


let strDateSelect = dateFormatter.stringFromDate(dateTimeStamp) 
print("Local Time", strDateSelect) //Local time 


let dateFormatter2 = NSDateFormatter() 
dateFormatter2.timeZone = NSTimeZone(name: "UTC") as NSTimeZone! 
dateFormatter2.dateFormat = "yyyy-MM-dd" 

let date3 = dateFormatter.dateFromString(strDateSelect) 
print("DATE",date3) 
4
//Date to milliseconds 
func currentTimeInMiliseconds() -> Int { 
    let currentDate = Date() 
    let since1970 = currentDate.timeIntervalSince1970 
    return Int(since1970 * 1000) 
} 

//Milliseconds to date 
extension Int { 
    func dateFromMilliseconds() -> Date { 
     return Date(timeIntervalSince1970: TimeInterval(self)/1000) 
    } 
} 

usunąłem pozornie bezużyteczne konwersji poprzez łańcuch i tych wszystkich, losowo !.

+0

Byłoby świetnie, ale potrzebuję currentTimeInMilliseconds do konwersji czasu lokalnego na UTC i potrzebuję dateFromMilliseconds do konwersji z UTC na czas lokalny – user1079052

+0

[Timestamp ** jest ** w UTC już.] (https://developer.apple.com/reference/foundation/nsdate/1416453-init). > 'Liczba sekund od daty referencyjnej (00:00:00 ** UTC ** 1 stycznia 1970)' – user28434

10

Jak działa @Travis rozwiązanie, ale w niektórych przypadkach

var millisecondsSince1970:Intspowoduje CRASH WNIOSEK,

z błędem

Podwójna wartość może nie być konwertowane do int, ponieważ wynik będzie większy niż Int.max jeśli występuje Proszę zaktualizować swoją odpowiedź z Int64

Oto Updated odpowiedź

extension Date { 
var millisecondsSince1970:Int64 { 
     return Int64((self.timeIntervalSince1970 * 1000.0).rounded()) 
     //RESOLVED CRASH HERE 
    } 

    init(milliseconds:Int) { 
     self = Date(timeIntervalSince1970: TimeInterval(milliseconds/1000)) 
    } 
} 

nadzieję, że jest pomocny dla kogoś, kto ma również ten sam problem:

+2

Dlaczego ten błąd miałby się zdarzyć? Przedział czasu od 1970 roku to liczba 32-bitowa. Przynajmniej dopóki nie dojdziemy do tego: https://en.wikipedia.org/wiki/Year_2038_problem – DoesData

+1

@DoesData Jeśli widzisz, mnożymy liczbę przez 1000.to powoduje, że jest poza zasięgiem Int32 –