abas-ERP (FO-Language): Exact time difference between 2 abas dates - erp

Is there any FO-native possibility for getting the exact difference between two abas date objects?
I have a AJO-based solution comparing two Calendar-Objects, but it's too slow for my use-case (it's called to many times) and I hope there is a native solution.
And what is the highest accuracy the abas dates (GD-Fields) can represent? Just Seconds or is there a way to get a UNIX-time-stamp or something comparable for a higher precision.

Yes, you can use the GP4 type.
.type GD19 xdbegin xdend
.type GP4 xgdiff
.formula U|xdbegin = "1.1.2015 00:00:00"
.formula U|xdend = "1.1.2016 00:00:00"
.formula U|xgdiff = U|xdend-U|xdbegin
'U|xgdiff'
output will be 365D00h00m00s
Now you can convert it e.g. into seconds:
.type text xtcmd
.type int xisec
.formula U|xtcmd = "formula U|xisec = " + F|regreplace(F|regreplace(F|regreplace(F|regreplace('U|xgdiff', "D", "*24*60*60+"), "h", "*60*60+"), "m", "*60+"), "s", "")
.'U|xtcmd'
As far as I know "seconds" is the highest precision you can use in FO.
If you need more, you have to use (as you already mentioned) UNIX-time-stamps

Related

Time to word converter

I was wondering if I could make an app in which time is display in words instead of conventional numbers. Do you think that there is any package for dart to convert time or numbers to words?
For example
1:30 AM will be One : Thirty AM
Thanks for reading this question. Have a wonderful day.
You can use any of available package to convert from number to words example
package: https://pub.dev/packages/number_to_words
import 'package:number_to_words/number_to_words.dart';
main(){
String input = '1:30 AM';
var s1 = input.split(':');
var s2 = s1[1].split(' ');
String hour = s1[0];
String minute = s2[0];
String hourWord = NumberToWord().convert('en-in',int.parse(hour));
String minuteWord = NumberToWord().convert('en-in',int.parse(minute));
print('$hourWord:$minuteWork ${s2[1]}');
}

lua Converting strings to numbers

Converting strings to numbers
prise = "1200$"
print(tonumber( prise))
prise = "1$20das0$"
print(tonumber( prise))
tell me how to get only numbers from a string
You can use pattern matching. The pattern [^%d] matches everything that is not a digits and we replace it with nothing.
local prise = "1$20das0$"
local onlydigits = string.gsub(prise, "[^%d]", "")
print(tonumber(onlydigits))
Live example on Wandbox

Why does NumberFormatter's string(from:) return an optional?

Documentation link
Why does the NumberFormatter function func string(from number: NSNumber) -> String? return a String? rather than a String? Are there particular inputs or states for a NumberFormatter where this function could return nil? Sometimes I hear these less-than-ideal return types are from Objective-C holdover files, is this one of those cases?
Just for fun: Here is a (constructed, not real-world) example where
string(from:) actually returns nil:
let num = NSNumber(bytes: UnsafeRawPointer(bitPattern: 1)!, objCType: "v")
print(num) // <>
let fmt = NumberFormatter()
fmt.numberStyle = .decimal
let str = fmt.string(from: num)
print(str as Any) // nil
The reason is that this num does not represent a number: It is created
using the NSValue (from which its inherits) initializer
init(bytes:objCType:) with a value representing void. ("v" is the type encoding for void,
the pointer value is irrelevant.)
There's an ancient (2002) response on the Apple mailing list which might partially answer your question:
The strange behavior isn't NSNumber -- NSNumber -stringValue seems to be returning results one would expect. It's NSNumberFormatter which is returning unusual results.
The abstract problem here is that NSNumberFormatter was originally written to handle money amounts for EOF, so it doesn't deal with unusual numbers well (or general purpose string formatting for that matter).
The more concrete problem is that when you ask an NSNumberFormatter for -stringForObjectValue:, if the object is not an NSDecimalNumber, it converts it to an NSDecimalNumber using
[NSDecimalNumber decimalNumberWithString:[objectValue stringValue]]
which is not going to handle unusual values well, in addition to potentially other issues. A further issue, though I don't know this is the case, is that I don't think there is an NSDecimal (the struct) representation of positive and negative infinity, as there is for NaN.
I don't actually understand that response enough to say that it's why an optional is returned, but I suspect it's related.
There's example code in the original question, but none of it returns a nil, it always gives a string.
I think it's fair to say that if you try to format a common type (like Double) to String using a NumberFormatter, there is no way it would return nil.
In my opinion, this is one of the few cases where force-unwrapped optionals make perfect sense.
func formatToDecimalNumber(_ value: Double) -> String {
let formatter = NumberFormatter()
formatter.numberStyle = .decimal
formatter.minimumFractionDigits = 0
formatter.maximumFractionDigits = 2
formatter.locale = Locale.current
return formatter.string(from: NSNumber(value: value))!
}

How to store long in a Swift array?

I got a couple user IDs I want to send in an array, but can't figure out the correct Swift 3 syntax for creating an array with very long integers. I tried casting, # prefix and using as AnyObject, but that did not work.
let idArray = [10211420262370680, 10211420262370680]
Error: integer literal overflows when stored into int
What is the correct way to create an array with such long integers?
Try this instead:
let idArray: [UInt64] = [10_211_420_262_370_680, ...]
As a back of the envelope calculation, every 10 bits buys you 3 decimal digits. For instance, UInt32 maxes out around 4_000_000_000 and so on.
By the way, the underscores _ above are just syntax sugar for big number literals ;-)
Signed long's array:
let signed64BitIntegerArray: [Int64] = [-10211420262370680, 10211420262370680]
Unsigned long's array:
let unsigned64BitIntegerArray: [UInt64] = [ 10211420262370680, 10211420262370680]
If you need C interop/FFI, use CLong or CUnsignedLong.

What's the best way to transform an Array of type Character to a String in Swift?

This question is specifically about converting an Array of type Character to a String. Converting an Array of Strings or numbers to a string is not the topic of discussion here.
In the following 2 lines, I would expect myStringFromArray to be set to "C,a,t!,🐱"
var myChars: [Character] = ["C", "a", "t", "!", "🐱"]
let myStringFromArray = myChars.joinWithSeparator(",");
However, I can't execute that code because the compiler complains about an "ambiguous reference to member joinWithSeparator".
So, two questions:
1) Apple says,
"Every instance of Swift’s Character type represents a single extended
grapheme cluster. An extended grapheme cluster is a sequence of one or
more Unicode scalars that (when combined) produce a single
human-readable character."
Which to me sounds at least homogeneous enough to think it would be reasonable to implement the joinWithSeparator method to support the Character type. So, does anyone have a good answer as to why they don't do that???
2) What's the best way to transform an Array of type Character to a String in Swift?
Note: if you don't want a separator between the characters, the solution would be:
let myStringFromArray = String(myChars)
and that would give you "Cat!🐱"
Which to me sounds at least homogeneous enough to think it would be reasonable to implement the joinWithSeparator method to support the Character type. So, does anyone have a good answer as to why they don't do that???
This may be an oversight in the design. This error occurs because there are two possible candidates for joinWithSeparator(_:). I suspect this ambiguity exists because of the way Swift can implicit interpret double quotes as either String or Character. In this context, it's ambiguous as to which to choose.
The first candidate is joinWithSeparator(_: String) -> String. It does what you're looking for.
If the separator is treated as a String, this candidate is picked, and the result would be: "C,a,t,!,🐱"
The second is joinWithSeparator<Separator : SequenceType where Separator.Generator.Element == Generator.Element.Generator.Element>(_: Separator) -> JoinSequence<Self>. It's called on a Sequence of Sequences, and given a Sequence as a seperator. The method signature is a bit of a mouthful, so lets break it down. The argument to this function is of Separator type. This Separator is constrained to be a SequenceType where the elements of the sequence (Seperator.Generator.Element) must have the same type as the elements of this sequence of sequences (Generator.Element.Generator.Element).
The point of that complex constraint is to ensure that the Sequence remains homogeneous. You can't join sequences of Int with sequences of Double, for example.
If the separator is treated as a Character, this candidate is picked, the result would be: ["C", ",", "a", ",", "t", ",", "!", ",", "🐱"]
The compiler throws an error to ensure you're aware that there's an ambiguity. Otherwise, the program might behave differently than you'd expect.
You can disambiguate this situation by this by explicitly making each Character into a String. Because String is NOT a SequenceType, the #2 candidate is no longer possible.
var myChars: [Character] = ["C", "a", "t", "!", "🐱"]
var anotherVar = myChars.map(String.init).joinWithSeparator(",")
print(anotherVar) //C,a,t,!,🐱
This answer assumes Swift 2.2.
var myChars: [Character] = ["C", "a", "t", "!", "🐱"]
var myStrings = myChars.map({String($0)})
var result = myStrings.joinWithSeparator(",")
joinWithSeparator is only available on String arrays:
extension SequenceType where Generator.Element == String {
/// Interpose the `separator` between elements of `self`, then concatenate
/// the result. For example:
///
/// ["foo", "bar", "baz"].joinWithSeparator("-|-") // "foo-|-bar-|-baz"
#warn_unused_result
public func joinWithSeparator(separator: String) -> String
}
You could create a new extension to support Characters:
extension SequenceType where Generator.Element == Character {
#warn_unused_result
public func joinWithSeparator(separator: String) -> String {
var str = ""
self.enumerate().forEach({
str.append($1)
if let arr = self as? [Character], endIndex: Int = arr.endIndex {
if $0 < endIndex - 1 {
str.append(Character(separator))
}
}
})
return str
}
}
var myChars: [Character] = ["C", "a", "t", "!", "🐱"]
let charStr = myChars.joinWithSeparator(",") // "C,a,t,!,🐱"
Related discussion on Code Review.SE.
Context: Swift3(beta)
TL;DR Goofy Solution
var myChars:[Character] = ["C", "a", "t", "!", "🐱"]
let separators = repeatElement(Character("-"), count: myChars.count)
let zipped = zip(myChars, separators).lazy.flatMap { [$0, $1] }
let joined = String(zipped.dropLast())
Exposition
OK. This drove me nuts. In part because I got caught up in the join semantics. A join method is very useful, but when you back away from it's very specific (yet common) case of string concatenation, it's doing two things at once. It's splicing other elements in with the original sequence, and then it's flattening the 2 deep array of characters (array of strings) into one single array (string).
The OPs use of single characters in an Array sent my brain elsewhere. The answers given above are the simplest way to get what was desired. Convert the single characters to single character strings and then use the join method.
If you want to consider the two pieces separately though... We start with the original input:
var input:[Character] = ["C", "a", "t", "!", "🐱"]
Before we can splice our characters with separators, we need a collection of separators. In this case, we want a pseudo collection that is the same thing repeated again and again, without having to actually make any array with that many elements:
let separators = repeatElement(Character(","), count: myChars.count)
This returns a Repeated object (which oddly enough you cannot instantiate with a regular init method).
Now we want to splice/weave the original input with the separators:
let zipped = zip(myChars, separators).lazy.flatMap { [$0, $1] }
The zip function returns a Zip2Sequence(also curiously must be instantiated via free function rather than direct object reference). By itself, when enumerated the Zip2Sequence just enumerates paired tuples of (eachSequence1, eachSequence2). The flatMap expression turns that into a single series of alternating elements from the two sequences.
For large inputs, this would create a largish intermediary sequence, just to be soon thrown away. So we insert the lazy accessor in there which lets the transform only be computed on demand as we're accessing elements from it (think iterator).
Finally, we know we can make a String from just about any sort of Character sequence. So we just pass this directly to the String creation. We add a dropLast() to avoid the last comma being added.
let joined = String(zipped.dropLast())
The valuable thing about decomposing it this way (it's definitely more lines of code, so there had better be a redeeming value), is that we gain insight into a number of tools we could use to solve problems similar, but not identical, to join. For example, say we want the trailing comma? Joined isn't the answer. Suppose we want a non constant separator? Just rework the 2nd line. Etc...

Resources