Limits of string transformations in q, stars in TOK - kdb

I'm trying to convert int values to minutes, and in some cases it gives me stars * in the result:
string "U"$"99:59" / "99:59"
string "U"$"100:00" / "**:00"
What are the rules for this stars to appear?
Update for seconds:
string "V"$"1000" / "10:00:00"
string "V"$"10000" / "**:00:00"
string "V"$"100000" / "10:00:00"
string "V"$"1000000" / "**:00:00"
Is it possible to configure this rules, say to stop smudging the origin values?

I think the stars that appear are just kdb's way of saying that the result couldn't be displayed.
The minute and second datatypes have the form hh:mm and hh:mm:ss, respectively. So if kdb reads the hour part as having more than 3 digits (i.e greater than 99), the stars will appear.
If you're casting a string into a minute datatype, then kdb converts the last two chars into minutes, and the rest into hours, eg
"U"$"1234" / 12:34
"U"$"12345" / **:45
Something similar occurs when you convert a string into seconds. If the length of the string is 6 or greater, then the last two chars are converted into seconds. Otherwise, the seconds are set to 00. The rest of the string is then converted into hh:mm as above. To illustrate this, look at:
"V"$"1234" / 12:34:00
"V"$"12345" / **:45:00
"V"$"123456" / 12:34:56
"V"$"1123456" / **:34:56
I should also note that even though stars appear, you can still do things like temporal arithmetic as usual, eg
"U"$"100:00 / **:00
("U"$"100:00")-"U"$"1:00" / 99:00

Related

Powershell cast string to time only

I have created a Powershell/XAML app, that on button press makes a RESTAPI call, parses the JSON response into fields in the app front end. All fine so far.
These fields will be populated with a string representing a time, so "1800" or "2000" etc.
The user can then change this from 1800 to 1900 for example.
This is all fine, and in the background the app will use 1900 to update a setting to be used in a POST back.
However there are other settings that are offset by 90 mins of the time above. I don't want the user to have update each one, which is why I am trying to programmatically.
But try as I might, I cannot take a string of 1800, add 90 mins to it and make the value 1930 (not 1890).
You could parse the input as a DateTime object (ignoring the date part) and then use the AddMinutes method.
$input = '1800'
$hour = $input.Substring(0,2)
$minute = $input.Substring(2,2)
$dateInputStr = "0001-01-01,${hour}:${minute}:00"
[datetime]$dateInput = ([datetime]$dateInputStr)
$dateInput = $dateInput.AddMinutes(90)
$dateInput.ToString("HHmm")
Using [timespan] instances is another option:
$time = '1800'
([timespan] ($time -replace '(?<=^..)', ':') + '01:30').ToString('hhmm') #->'1930'
$time -replace '(?<=^..)', ':' uses the regex-based -replace operator to insert : after the first two characters - see this regex101.com page for an explanation of the regex and the ability to experiment with it.
Due to expressing the results only in terms of hours and minutes, the calculation wraps around at midnight, so that adding '05:30', for instance, would yield '0030'
The RHS operand needn't be cast to [timespan] directly, because the data type of the LHS - with its explicit [timespan] cast - implicitly converts the RHS to [timespan] too, with '01:30' representing 1 hour and 30 minutes, i.e. 90 minutes.
If you want to define the duration to add in terms of 90 minutes, use the following instead (there are analogous static methods for other units, such as ::FromSeconds():
[timespan]::FromMinutes(90)
Alternatively, you can cast a number to [timespan], which is interpreted as ticks, which are 100-nanosecond units; there are 1e9 (10 to the power of 9) nanoseconds in a second, and therefore 1e7 100-nanosecond units in a second. Thus, multiplying with 1e7 gives you seconds, and multiplying that with 60 minutes.
# 90 minutes expressed as ticks
[timespan] 90 * (60 * 1e7)
When I read this question I wanted to solve it with minimal string manipulation, leaning on time related objects and methods instead. datetime was the first object I thought of, but it expects a date (year, month, day). Things actually simplify if we use timespan. Its static method, ParseExact, can parse the string directly.
$offsetTimeSpan = [timespan]::FromMinutes(90)
$timeField = '830'
$timeStr = $timeField.PadLeft(4, '0')
$timeSpan = [timespan]::ParseExact($timeStr, 'hhmm', [CultureInfo]::InvariantCulture)
$offsetTime = $timeSpan.Add($offsetTimeSpan)
$offsetTime.ToString('hhmm')
$timeField is used to represent the time you get from the RESTAPI. PadLeft is only needed if it's possible for a leading 0 to be missing. ParseExact does the heavy lifting of converting the string to a time type. Because timespan doesn't have an AddMinutes member, we use the Add method passing in a timespan of 90 minutes, $offsetTimeSpan.
You don't mention anything about overflowing past midnight. You can test for overflow using $offsetTime.Days, if any special processing is required.

Rounding seconds of time with HH:MM:SS format to nearest minute

For Example: Sunset-Sunrise.org provides sunset/sunrise time with HH:MM:SS format.
Given a time such as 12:53:57, I want to round the seconds to 12:54:00. Please advise.
A general technique for rounding is to add half of the unit you want to round to and then truncating. For example, if you want to round an integer to the nearest ten's digit, you can add 5 and discard the one's digit: ((x + 5) ~/ 10) * 10.
The same technique works for times too. You can first parse the HH:MM:SS string into a DateTime object. Then, to round the DateTime to the nearest minute, you can add 30 seconds and copy all of the resulting fields except for the seconds (and subseconds):
DateTime roundToMinute(DateTime dateTime) {
dateTime = dateTime.add(const Duration(seconds: 30));
return (dateTime.isUtc ? DateTime.utc : DateTime.new)(
dateTime.year,
dateTime.month,
dateTime.day,
dateTime.hour,
dateTime.minute,
);
}
You can use date_time_fromat packages
from the docs
final timeOffset = dateTime.subtract(Duration(hours: 6, minutes: 45));
// 7 hours
print(DateTimeFormat.relative(timeOffset));
// 6 hours
print(DateTimeFormat.relative(timeOffset, round: false));
This is the URL

Parse military time to double in flutter

I am trying to convert a textfield input of military time into a double. Can anyone help me with this? goal would be if someone enters 13:45 then the output would be 13.75.
Divide your input into 2 halves around the :. Then parse each half, which results in separate hours and minutes ints. Add them together, dividing the minutes by 60 to get your intended double output.
String input = "13:45";
String firstHalf = input.substring(0, input.indexOf(':'));
String secHalf = input.substring(input.indexOf(':') + 1);
int hour = int.parse(firstHalf);
int min = int.parse(secHalf);
double output = hour + min/60;
print(output);//13.75

method for converting seconds from date to datetime

Is there a method in matlab to convert seconds from a known date to a standard date time format?
For example, if I have a vector of values shown as seconds from 1901/01/01, how would I convert them to a dateTime? In this case a value of 28125 would correspond to 1981/01/01. Is there an efficient method for doing this?
The numbers in your example do not make sense so it is not clear if your time is in seconds or days but since you asked for seconds I will use this.
What you want to achieve can be done using datenum function. This function returns the number of (fractional) days from 1/1/0000. So first you need to find your offset, e.g.:
offsetInDays = datenum(1901,1,1);
Next, you convert the date from seconds to days:
dateInDays = YourRequiredDateInSec * 3600 * 24;
Finally, you date is given by
RequiredDate = datestr(offsetInDays + dateInDays);

How do I convert a decimal number representing time to actual time in Crystal Reports 2008? Ex: "1.5" represents 1:30

I'm trying to edit an existing Crystal Report that shows time allowances for work orders. Budgeted Time / Actual Time / Remaining Time type deal.
These fields show up as not properly converting time from the data field for the report. The person who made the report has some formula for it already but I'm not sure what's it doing.
Formula: Standard Time
Stringvar array Std_Time := split(replace(cstr({WOMNT_CARD.STANDARD_HOURS_DURATION}),",",""),".");
val(Std_Time[1])*60+val(Std_Time[2])
The field used in the report is Sum of #Standard Time (Number).
How do I fix this so these numbers are properly converted?
The formula that you have posted does the following:
First it converts the datatype of the {WOMNT_CARD.STANDARD_HOURS_DURATION} field to string by using the cstr function, the result is being stripped of commas with the replace function and the resulted string is being split into an array by using the dot character as the delimiter.
So, for the value 1.5 the Std_Time variable will hold the following
Std_Time[1] → 1
Std_Time[2] → 5
Finally it calculates the result by multiplying the first value of the first index with 60 and adds to it the value of the second index. The value 1.5 becomes 1 * 60 + 5 = 65
If the 1.5 must represent 1:30 then the last line must become
val(Std_Time[1]) * 60 + 60 * val(Std_Time[2]) / 10
because 60 * 5 / 10 = 30
or you can use for simplicity just the following
60 * val(replace(cstr({WOMNT_CARD.STANDARD_HOURS_DURATION}),",",""))
since 60 * 1.5 = 90