Timestamp (milliseconds) in Swift - ios

I am receiving a creation date for an object in a database as milliseconds (# of milliseconds since epoch or whatever) and would like to convert it to/from a string in Swift!
I think I'd need a data type of CUnsignedLong?
I am trying something like this but it outputs the wrong number:
var trial: CUnsignedLong = 1397016000000
println(trial) //outputs 1151628800 instead!
I'm guess this is the wrong data type so what would you all advise in a situation like this?
In Java I was using long which worked.
Thanks!

func currentTimeMillis() -> Int64{
let nowDouble = NSDate().timeIntervalSince1970
return Int64(nowDouble*1000)
}
Working fine

On 32-bit platforms, CUnsignedLong is a 32-bit integer, which is not large
enough to hold the number 1397016000000. (This is different from Java, where
long is generally a 64-bit integer.)
You can use UInt64 or NSTimeInterval (a type alias for Double), which is what the
NSDate methods use.

Related

Getting Garbage value while convert into long Objective -C

I am trying to convert NSString to long but I am getting garbage value. Below is my code :
long t1 = [[jsonDict valueForKeyPath:#"detail.amount"]doubleValue] * 1000000000000000000;
long t2 = [[jsonDict valueForKeyPath:#"detail.fee"]doubleValue] * 10000000000000000;
NSLog(#"t1: %ld",t1);
NSLog(#"t2: %ld",t2);
detail.amout = 51.74
detail.fee = 2.72
O/P :
t1: 9223372036854775807 (Getting Garbage value here)
t2: 27200000000000000 (Working fine)
Thanks in advance.
Each number types (int, long, double, float) has limits. For your long 64 bit (because your device is 64bit) number the upper limit is :9,223,372,036,854,775,807 (see here: https://en.wikipedia.org/wiki/9,223,372,036,854,775,807)
In your case, 51.74 * 1,000,000,000,000,000,000 =
51,740,000,000,000,000,000
While Long 64bit only has a maximum of
9,223,372,036,854,775,807
So an overflow happens at 9,223,372,036,854,775,808 and above. Which is what your calculation evaluates into.
Also to note, that what you are doing will also cause problem if you only cater for 64bit long range, because what happens when your app runs on a 32bit (like iPhone 5c or below)?
Generally a bad idea to use large numbers, unless you're doing complex maths. If number accuracies are not critical, then you should consider simplifying the number like 51,740G (G = Giga). etc.
It's because you're storing the product to long type variables t1 and t2.
Use either float or double, and you'll get the correct answer.
Based on C's data types:
Long signed integer type. Capable of containing at least the
[−2,147,483,647, +2,147,483,647] range; thus, it is at least 32
bits in size.
Ref: https://en.wikipedia.org/wiki/C_data_types
9223372036854775807 is the maximum value of a 64-bit signed long. I deduce that [[jsonDict valueForKeyPath:#"detail.amount"]doubleValue] * 1000000000000000000 is larger than the maximum long value, so when you cast it to long, you get the closest value that long can represent.
As you read, it is not possible with long. Since it looks like you do finance math, you should use NSDecimalNumber instead of double to solve that problem.

Dart: DateTime.parse() not including microseconds

See the following code:
void main()
{
String test = '2017-10-11T12:03:46.351363-04:00';
DateTime testDate = DateTime.parse(test);
print(testDate.microsecond);
print(testDate.toString());
}
When running this code I lose the microseconds in the string that I parse. Why is this and is there anyway to solve this?
The Dart docs say that the parse method supports microseconds.
'2017-10-11T12:03:46.351363-04:00' is not a format Dart's DateTime can handle.
DateTime only supports Z for GMT or no Z for local time.
Just print the value from a created DateTime to see what format it can parse.
print(DateTime.now());
print(DateTime.now().toUtc())
DateTime has also 2 constructors fromMicrosecondsSinceEpoch and fromMillisecondsSinceEpoch to create an instance from an integer value.
There's an issue here
https://github.com/dart-lang/co19/issues/17
As the test show it only 6 decimal places
https://github.com/dart-lang/co19/commit/8465825f60c9580d82ae01ffc040f3b589aaf667#diff-02c526d1dcb5aa2dcdab3500c14ede87R40
You can parse format 2018-12-11T12:00:32.304272Z
but cannot parse 2018-12-11T12:00:32.304272001Z
I found an issue for dart-lang/sdk.
https://github.com/dart-lang/sdk/issues/44876
The web Date object doesn't support microseconds. It's implemented
using the JavaScript Date object which only supports millisecond
precision. So, working as well as possible.

Cast String to Int64 causes crash on 32bit devices

I have to deal with a pretty long Int, that comes to me as a String. Calling
Int64(String) works fine on 64bit devices, but I see crashes on 32bit devices. What is the reason for this?
Here is the code:
let predicateBarcode = NSPredicate(format: "barcode = %ld", Int64(searchTerm)!)
I cannot tell anything about the searchterm, it comes from the barcode scanner and is an ean-13. I can also not reproduce the crash, as this is only happening to my costomers.
It's not the problem of Int64.init(_:) but the problem of the format given to NSPredicate.
Length specifier l means its argument needs to be long or unsigned long, which are equivalent to Int or UInt in Swift.
String Format Specifiers
If you want to use Int64 value as a format argument, the right length specifier is ll, meaning long long which is equivalent to Int64 in Swift.
let predicateBarcode = NSPredicate(format: "barcode = %lld", Int64(searchTerm)!)
You may need to fix some other parts, but I cannot see as you are hiding other parts. (And as far as I test, I could not make my testing app crash.) In addition, are you 100%-sure about Int64(searchTerm)! may not crash?
Anyway, the format string needs to be fixed at least.

Date.copy() in Swift 3.0

Since the switch to Swift 3.0, and along with it the change of NSDate to Date, the class no longer conforms to the NSCopying protocol.
In Swift 2, this was valid:
let newDate = oldDate.copy()
But now returns a compiler error.
With this being the case, what is the best way to duplicate a Date object?
let newDate = Date(timeIntervalSince1970: oldDate.timeIntervalSince1970)
This will do the trick, but it doesn't seem particularly elegant. And it is potentially (theoretically) susceptible to loss of precision as a TimeInterval is a Double (and we have no way of confirming that a Date object internals uses - or always will use - a Double).
Answering my own question as I figured it out before I finished typing it. Hopefully it will help someone else.
Date in Swift 3 is now a struct, not a class. Which is a value type. Which means that it does not need to be 'copied', simply assigning it to a new variable will copy the data:
let newDate = oldDate

adding a big offset to an os.time{} value

I'm writing a Wireshark dissector in lua and trying to decode a time-based protocol field.
I've two components 1)
local ref_time = os.time{year=2000, month=1, day=1, hour=0, sec=0}
and 2)
local offset_time = tvbuffer(0:5):bytes()
A 5-Byte (larger than uint32 range) ByteArray() containing the number of milliseconds (in network byte order) since ref_time. Now I'm looking for a human readable date. I didn't know this would be so hard, but 1st it seems I cannot simple add an offset to an os.time value and 2nd the offset exceeds Int32 range ...and most function I tested seem to truncate the exceeding input value.
Any ideas on how I get the date from ref_time and offset_time?
Thank you very much!
Since ref_time is in seconds and offset_time is in milliseconds, just try:
os.date("%c",ref_time+offset_time/1000)
I assume that offset_time is a number. If not, just reconstruct it using arithmetic. Keep in mind that Lua uses doubles for numbers and so a 5-byte integer fits just fine.

Resources