Swift: Convert Nsdate to C# Ticks

NSDate to Tick conversion

I would like to share my experience:

I tried to find the seconds from 01/01/0001 and then multiply by 10,000,000. However, it gave me wrong results. So, I found out that 01/01/1970 is 621355968000000000 ticks from 01/01/0001 and used the following formula along with timeIntervalSince1970 function of NSDate.

Ticks = (MilliSeconds * 10000) + 621355968000000000

MilliSeconds = (Ticks - 621355968000000000) / 10000

Here is the outcome:

+(NSString *) dateToTicks:(NSDate *) date
{
NSString *conversionDateStr = [self dateToYYYYMMDDString:date];
NSDate *conversionDate = [self stringYYYYMMDDToDate:conversionDateStr];
NSLog(@"%@",[date description]);
NSLog(@"%@",[conversionDate description]);
double tickFactor = 10000000;
double timeSince1970 = [conversionDate timeIntervalSince1970];
double doubleValue = (timeSince1970 * tickFactor ) + 621355968000000000;
NSNumberFormatter *numberFormatter = [[[NSNumberFormatter alloc] init] autorelease];
[numberFormatter setNumberStyle:NSNumberFormatterNoStyle];
NSNumber *nsNumber = [NSNumber numberWithDouble:doubleValue];
return [numberFormatter stringFromNumber:nsNumber];
}

Likewise, to convert from tick to date:

//MilliSeconds = (Ticks - 621355968000000000) / 10000
+(NSDate *) ticksToDate:(NSString *) ticks
{
double tickFactor = 10000000;
double ticksDoubleValue = [ticks doubleValue];
double seconds = ((ticksDoubleValue - 621355968000000000)/ tickFactor);
NSDate *returnDate = [NSDate dateWithTimeIntervalSince1970:seconds];
NSLog(@"%@",[returnDate description]);
return returnDate;
}

Convert .NET DateTime.Ticks Property to Date in Objective-C

This C# code might help you:

// The Unix epoch is 1970-01-01 00:00:00.000
DateTime UNIX_EPOCH = new DateTime( 1970 , 1 , 1 ) ;

// The Unix epoch represented in CLR ticks.
// This is also available as UNIX_EPOCH.Ticks
const long UNIX_EPOCH_IN_CLR_TICKS = 621355968000000000 ;

// A CLR tick is 1/10000000 second (100ns).
// Available as Timespan.TicksPerSecond
const long CLR_TICKS_PER_SECOND = 10000000 ;

DateTime now = DateTime.Now ; // current moment in time
long ticks_now = now.Ticks ; // get its number of tics
long ticks = ticks_now - UNIX_EPOCH_IN_CLR_TICKS ; // compute the current moment in time as the number of ticks since the Unix epoch began.
long time_t = ticks / CLR_TICKS_PER_SECOND ; // convert that to a time_t, the number of seconds since the Unix Epoch
DateTime computed = EPOCH.AddSeconds( time_t ) ; // and convert back to a date time value

// 'computed' is the the current time with 1-second precision.

Once you have your time_t value, the number of seconds since the Unix epoch began, you should be able to get an NSDATE in Objective-C thusly:

NSDate* myNSDate = [NSDate dateWithTimeIntervalSince1970:<my_time_t_value_here> ] ;

which see: https://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSDate_Class/Reference/Reference.html

How to get 18-digit current timestamp in Swift?

You seem be looking for what DateTime.Ticks is in C#, i.e. the
time since 0001-01-01 measured in 100-nanosecond intervals.

The code from your provided link Swift: convert NSDate to c# ticks can be translated to Swift easily:

// Swift 2:
extension NSDate {
var ticks: UInt64 {
return UInt64((self.timeIntervalSince1970 + 62_135_596_800) * 10_000_000)
}
}

// Swift 3:
extension Date {
var ticks: UInt64 {
return UInt64((self.timeIntervalSince1970 + 62_135_596_800) * 10_000_000)
}
}

Example (Swift 3):

let ticks = Date().ticks
print(ticks) // 636110903202288256

or as a string:

let sticks = String(Date().ticks)
print(sticks)

And while are are at it, the reverse conversion from ticks to Date
would be

// Swift 2:
extension NSDate {
convenience init(ticks: UInt64) {
self.init(timeIntervalSince1970: Double(ticks)/10_000_000 - 62_135_596_800)
}
}

// Swift 3:
extension Date {
init(ticks: UInt64) {
self.init(timeIntervalSince1970: Double(ticks)/10_000_000 - 62_135_596_800)
}
}

Example (Swift 3):

let date = Date(ticks: 636110903202288256)

Converting 12 digit ticks to Date

Just don't subtract 62_135_596_800

extension Date {
init(ticks: UInt64) {
self.init(timeIntervalSince1970: Double(ticks)/10_000_000)
}
}

1970-01-01 18:00:00 +0000

The other problem: When you create date and print it, the string is formatted in UTC time zone (offset GMT+0). But DateFormatter returns string representation dependent on its time zone, which is the local timezone by default.

You can fix your code just by setting dateFormatter's timeZone to UTC

dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)

18:00

Convert Date to Integer in Swift

Date to Int

// using current date and time as an example
let someDate = Date()

// convert Date to TimeInterval (typealias for Double)
let timeInterval = someDate.timeIntervalSince1970

// convert to Integer
let myInt = Int(timeInterval)

Doing the Double to Int conversion causes the milliseconds to be lost. If you need the milliseconds then multiply by 1000 before converting to Int.

Int to Date

Including the reverse for completeness.

// convert Int to TimeInterval (typealias for Double)
let timeInterval = TimeInterval(myInt)

// create NSDate from Double (NSTimeInterval)
let myNSDate = Date(timeIntervalSince1970: timeInterval)

I could have also used `timeIntervalSinceReferenceDate` instead of `timeIntervalSince1970` as long as I was consistent. This is assuming that the time interval is in seconds. Note that Java uses milliseconds.

Note

  • For the old Swift 2 syntax with NSDate, see this answer.

Swift convert unix time to date and time

To get the date to show as the current time zone I used the following.

if let timeResult = (jsonResult["dt"] as? Double) {
let date = NSDate(timeIntervalSince1970: timeResult)
let dateFormatter = NSDateFormatter()
dateFormatter.timeStyle = NSDateFormatterStyle.MediumStyle //Set time style
dateFormatter.dateStyle = NSDateFormatterStyle.MediumStyle //Set date style
dateFormatter.timeZone = NSTimeZone()
let localDate = dateFormatter.stringFromDate(date)
}

Swift 3.0 Version

if let timeResult = (jsonResult["dt"] as? Double) {
let date = Date(timeIntervalSince1970: timeResult)
let dateFormatter = DateFormatter()
dateFormatter.timeStyle = DateFormatter.Style.medium //Set time style
dateFormatter.dateStyle = DateFormatter.Style.medium //Set date style
dateFormatter.timeZone = self.timeZone
let localDate = dateFormatter.string(from: date)
}

Swift 5

if let timeResult = (jsonResult["dt"] as? Double) {
let date = Date(timeIntervalSince1970: timeResult)
let dateFormatter = DateFormatter()
dateFormatter.timeStyle = DateFormatter.Style.medium //Set time style
dateFormatter.dateStyle = DateFormatter.Style.medium //Set date style
dateFormatter.timeZone = .current
let localDate = dateFormatter.string(from: date)
}

How to convert C#'s BitConverter.GetBytes(date.ToBinary()) to Swift

Yes, I solved it.
This is my solution (Swift 2.0 if IIRC)

let dateNumber = NSNumber(double: NSDate().timeIntervalSince1970)
let ticks = NSNumber(longLong:dateNumber.longLongValue * 10000000 + 621355968000000000)
let dateDataByteArray:[UInt8] = self.toByteArray(ticks.longLongValue)

and for the conversion to byteArray

func toByteArray<T>(var value: T) -> [UInt8] {
return withUnsafePointer(&value) {
Array(UnsafeBufferPointer(start: UnsafePointer<UInt8>($0), count: sizeof(T)))
}
}

Date to milliseconds and back to date in Swift

I don't understand why you're doing anything with strings...

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

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

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


Related Topics



Leave a reply



Submit