I set a timer to count 500us ticks
TIM_InitStruct.Prescaler = (uint16_t)40000-1; //SYSCLK = 80Mhz – 80Mhz/40000 = 500us
TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
TIM_InitStruct.Autoreload = 0xFFFFFFFF; //TIM2 – 32-bit counter
TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
TIM_InitStruct.RepetitionCounter = (uint8_t)0x00;
LL_TIM_Init(TIM2, &TIM_InitStruct);
I get the counter
uint32_t TIM_GetTimeStamp_ms(TIM_TypeDef * TIMx)
{
//timer 32-bit
volatile uint32_t time_stamp = TIMx->CNT;
//conter counts in 500us ticks so - us/2 = ms
timer_counter = time_stamp >> 1;
//global
return timer_counter;
}
I test it
while (1)
{
ts1 = TIM_GetTimeStamp_ms(TIM2);
Delay_ms(100);
ts2 = TIM_GetTimeStamp_ms(TIM2);
time_stamp = ts2 - ts1;
}
And I see time_stamp = 100 – so far so good.
Now I test it this way
while (1)
{
ts1 = TIM_GetTimeStamp_ms(TIM2);
if (ts1 >= script_cycle)
{
time_stamp = ts1 - script_cycle;
script_cycle = ts1 + 100;
}
}
And I see time_stamp is growing up. Do I miss something?
Related
I’m dealing with BigDecimal in Java and I need to make 2 check against BigDecimal fields in my DTO:
Number of digits of full part (before point) < 15
Total number of
digits < 32 including scale (zeros after point)
What is the best way to implement it? I extremely don’t want toBigInteger().toString() and .toString()
I think this will work.
BigDecimal d = new BigDecimal("921229392299229.2922929292920000");
int fractionCount = d.scale();
System.out.println(fractionCount);
int wholeCount = (int) (Math.ceil(Math.log10(d.longValue())));
System.out.println(wholeCount);
I did some testing of the above method vs using indexOf and subtracting lengths of strings. The above seems to be signficantly faster if my testing methodology is reasonable. Here is how I tested it.
Random r = new Random(29);
int nRuns = 1_000_000;
// create a list of 1 million BigDecimals
List<BigDecimal> testData = new ArrayList<>();
for (int j = 0; j < nRuns; j++) {
String wholePart = r.ints(r.nextInt(15) + 1, 0, 10).mapToObj(
String::valueOf).collect(Collectors.joining());
String fractionalPart = r.ints(r.nextInt(31) + 1, 0, 10).mapToObj(
String::valueOf).collect(Collectors.joining());
BigDecimal d = new BigDecimal(wholePart + "." + fractionalPart);
testData.add(d);
}
long start = System.nanoTime();
// Using math
for (BigDecimal d : testData) {
int fractionCount = d.scale();
int wholeCount = (int) (Math.ceil(Math.log10(d.longValue())));
}
long time = System.nanoTime() - start;
System.out.println(time / 1_000_000.);
start = System.nanoTime();
//Using strings
for (BigDecimal d : testData) {
String sd = d.toPlainString();
int n = sd.indexOf(".");
int m = sd.length() - n - 1;
}
time = System.nanoTime() - start;
System.out.println(time / 1_000_000.);
}
I have a Google Sheet with three columns:
- Date and time (timestamp)
- Duration
- Description
I have an script that when I write something in 'Description', inserts in 'Date' the date and time at this moment, and the 'Duration':
function onEdit(e) {
if(e.source.getActiveSheet().getName() == "Sheet2" ) {
var col = e.source.getActiveCell().getColumn();
if(col == 3 ) {
// I'm in column three
var cellTimeStamp = e.range.offset(0,-2); // First column of the same row
var cellTimeDiff = e.range.offset(0,-1); // Second column of the same row
var cellTimePrev = e.range.offset(-1,-2); // First column of the previous row
var timeTimeStamp = new Date();
var iniTime = cellTimePrev.getValue().getTime();
var finTime = timeTimeStamp.getTime() ;
var timeDiff = String(finTime - iniTime) ;
cellTimeStamp.setValue(timeTimeStamp);
cellTimeDiff.setValue(timeDiff); // [***]
}
}
}
When this executes (as an event) in the column of 'Duration' there is NOT something in the format of 'HH:mm:ss'.
But if I remove the last line in this script and adds this formulae in the sheet:
=A3-A2 (in row 3)
=A4-A3 (in row 4)
...
then it works ok.
I'd like to know how to meet the same result but with a script.
Thanks in advance.
timeDiff is the result of finTime - iniTime which are both native date object values, which means we have milliseconds .
converting that in hh:mm:ss is simple math... : 60 seconds in a minute and 60 minutes in an hour...
A simple code could be like this :
function msToTime(s) {
var ms = s % 1000;
s = (s - ms) / 1000;
var secs = s % 60;
s = (s - secs) / 60;
var mins = s % 60;
var hrs = (s - mins) / 60;
return hrs + ':' + mins + ':' + secs; // milliSecs are not shown but you can use ms if needed
}
If you prefer formating your string more conventionally (2 digits for each value) don't forget you can use Utilities.formatString() to do so.
example below :
return Utilities.formatString("%02d",hrs) + ':' + Utilities.formatString("%02d",mins) + ':' + Utilities.formatString("%02d",secs);
EDIT
Following your comment :
Spreadsheets are smarter than you think, you can try the code below and you will see that the result is actually a time value.(check by double clicking on it)
function test() {
var sh = SpreadsheetApp.getActiveSheet();
var t1 = sh.getRange('a1').getValue().getTime();
var t2 = sh.getRange('b1').getValue().getTime();
sh.getRange('c1').setValue(msToTime(t1-t2)).setNumberFormat('hh:mm:ss');
}
function msToTime(s) {
var ms = s % 1000;
s = (s - ms) / 1000;
var secs = s % 60;
s = (s - secs) / 60;
var mins = s % 60;
var hrs = (s - mins) / 60;
return hrs + ':' + mins + ':' + secs; // milliSecs are not shown but you can use ms if needed
}
note that setNumberFormat('hh:mm:ss') is optional, it's only there to force the spreadsheet to display hour:min:sec format but automatic mode works as well.
I am trying to calculate the time difference between 2 date time strings.
I have 2 inputs where the input string is something like this "1:00 PM" and the second one "3:15 PM". I want to know the time difference. So for the above example I want to display 3.15
What I have done:
Converted the time to a 24 hours format. So "1:00 PM" becomes "13:00:00"
Appended the new time to a date like so: new Date("1970-1-1 13:00:00")
Calculated the difference like so:
Code:
var total = Math.round(((new Date("1970-1-1 " + end_time) -
new Date("1970-1-1 " + start_time) ) / 1000 / 3600) , 2 )
But the total is always returning integers and not decimals, so the difference between "1:00 PM" and "3:15 PM" is 2 not 2.15.
I have also tried this (using jQuery, but that is irrelevant):
$('#to_ad,#from_ad').change(function(){
$('#total_ad').val( getDiffTime() );
});
function fixTimeString(time){
var hours = Number(time.match(/^(\d+)/)[1]);
var minutes = Number(time.match(/:(\d+)/)[1]);
var AMPM = time.match(/\s(.*)$/)[1];
if(AMPM == "PM" && hours<12) hours = hours+12;
if(AMPM == "AM" && hours==12) hours = hours-12;
var sHours = hours.toString();
var sMinutes = minutes.toString();
if(hours<10) sHours = "0" + sHours;
if(minutes<10) sMinutes = "0" + sMinutes;
return sHours + ':' + sMinutes + ':00';
}
function getDiffTime(){
var start_time = fixTimeString($('#from_ad').val());
var end_time = fixTimeString($('#to_ad').val());
var start = new Date("1970-1-1 " + end_time).getTime(),
end = new Date("1970-1-1 " + start_time).getTime();
return parseInt(((start - end) / 1000 / 3600, 10)*100) / 100;
}
But the total_ad input is displaying only integer values.
How can I fix this problem?
Math.round rounds to the nearest integer, multiply and divide instead
var start = new Date("1970-1-1 " + start_time).getTime(),
end = new Date("1970-1-1 " + end_time).getTime();
var total = (parseInt(((start-end) / 1000 / 3600)*100, 10)) / 100;
FIDDLE
When you take the time 15:15:00 and subtract 13:00:00, you're left with 2.15 hours, not 3.15, and this example would return 2.15 even without making sure there is only two decimals, but for other times that might not be the case.
You could also use toFixed(2), but that would leave you with 3.00 and not 3 etc.
This is how I calculate it:
calculateDiff();
function calculateDiff(){
_start = "7:00 AM";
_end = "1:00 PM";
_start_time = parseAMDate(_start);
_end_time = parseAMDate(_end);
if (_end_time < _start_time){
_end_time = parseAMDate(_end,1);
}
var difference= _end_time - _start_time;
var hours = Math.floor(difference / 36e5),
minutes = Math.floor(difference % 36e5 / 60000);
if (parseInt(hours) >= 0 ){
if (minutes == 0){
minutes = "00";
}
alert(hours+":"+minutes);
}
}
function parseAMDate(input, next_day) {
var dateReg = /(\d{1,2}):(\d{2})\s*(AM|PM)/;
var hour, minute, result = dateReg.exec(input);
if (result) {
hour = +result[1];
minute = +result[2];
if (result[3] === 'PM' && hour !== 12) {
hour += 12;
}
}
if (!next_day) {
return new Date(1970, 01, 01, hour, minute).getTime();
}else{
return new Date(1970, 01, 02, hour, minute).getTime();
}
}
I want to roundoff my number to greater value. for example if i have 234 i want to make it 300 and 4436 to 5000. I have tried it but i can roundoff my value not in hundred and thousants but in tens. like i have a value 7771 it roundoff to 7900 or 7800 but i want it in 8000.
int temp = lroundf([[arrayPercentage objectAtIndex:i]floatValue]);
maxPer = (((temp + 10)/10))*10;
How about this:
-(void)roundUpNumber:(NSInteger) num {
NSInteger numLength = [[NSString stringWithFormat:#"%ld",num] length];
NSInteger newNum = ceil(num/pow(10,numLength-1)) * pow(10,numLength -1);
NSLog(#"%ld",newNum);
}
int num, count = 0;
int originalNumber = 7771;
num = originalNumber;
while (num) {
num = num/10;
count ++;
}
int power = pow(10,(count -1));
int firstDigit = originalNumber / power;
int finalNumber = (firstDigit + 1)* power;
NSLog(#"final result : %d",finalNumber);
I am trying to figure out how to create an 'if' statement that uses a time value as a condition. For example:
if (time <= 10:00) {
score = 3;
} else if (time <= 20:00) {
score = 5;
} else {
score = 9;
}
I know that a string of "5:23" cannot be compared this way but I don't think I can just turn a string value like that directly into an integer. Any thoughts?
Try this:
NSString *realTimeString = #"10:00";
NSString *someTimeString = [realTimeString stringByReplacingOccurrencesOfString:#":"
withString:#"."];
float time = [someTimeString floatValue];
if (time <= 10.00) {
score = 3;
} else if (time <= 20.00) {
score = 5;
} else {
score = 9;
}