# Time class, carry, don't understand how it works exactly

I need help understanding how the pre() function in this Time class works.

Edit: I think maybe I have it, does this seem sound? So far it seems to be working.

The thing I don’t like about this is that I made it work by just dividing `milli / 100` and then setting the value of `milli %= 100`. It does get the tenths, but then `milli` is no longer truly the value of milliseconds, so when I use this in my Time class, anywhere where `milli` is used, such as getting angles for smooth clock hand rotations, it’s no longer correct.

Where I am really stuck is how to add the ability to get 1/10sec in-line with this code without affecting the value of `milli` from one loop to the next.

I’ve updated the code with comments about my understanding of how this works, and which parts I don’t understand.

``````
int lastT, deltaT, carry, milli, hundredths, tenths, sec, min, hr;
String carry100msStr, carry10msStr, carry60secStr, carry60minStr;
void setup() {
size(400, 600);

lastT = millis();
milli = 0;
hundredths = 0;
tenths = 0;
sec = second();
min = minute();
hr = hour();
}

void draw() {
background(127);

int rightNow = millis();
deltaT = rightNow - lastT;
lastT = rightNow;
milli += deltaT; // get the baseUnit count i.e. "milli"
carry = 0;

// the baseUnit can be as high as 1000
// the next unit is tenths, and we need just 100 baseUnits for one "tenth"
// divide the baseUnit count by how many you need for the next unit: floor(milli / 100)
// if there is not enough yet, this will be '0'
// if there are enough baseUnits so far, carry 1
carry = floor(milli / 100);

// not sure how to describe this
// but I see if I don't use "milli %= 1000" then milli will not count properly on the next loop
// and if I do use "milli %= 1000" then it also fails but I don't know why.
milli %= 1000;

// add "1" or "0" to the next unit, "tenths"
tenths += carry;

// need 10 of these before incrementing the next unit, "sec"
carry = floor(tenths / 10);

// not sure how to describe this
tenths %= 10;

// add "1" or "0" to the next unit, "sec"
sec += carry;

// need 60 of these before incrementing the next unit, "min"
carry = floor(sec / 60);

// not sure how to describe this
sec %= 60;

// add "1" or "0" to the next unit, "min"
min += carry;

// need 60 of these before incrementing the next unit, "hr"
carry = floor(min / 60);

// not sure how to describe this
min %= 60;

// add "1" or "0" to the next unit, "hr"
hr += carry;

// not sure how to describe this
hr %= 24;

String milliStr = nf(milli, 2) + "  milli";
String tenthsStr = nf(tenths, 1) + " tenths";
String secStr = nf(sec, 2) + " seconds";
String minStr = nf(min, 2) + " minutes";
String hrStr = nf(hr, 2) + " hr";

String[] list = {

milliStr,
tenthsStr,
secStr,
minStr,
hrStr

};

showTextArrayLeft(list);
}

void showTextArrayLeft(String[] strings) {

float textH = 18;
//textFont(mono);
textSize(textH);
textAlign(LEFT, TOP);
fill(0);
for (int i=0; i<strings.length; i++) {
text(strings[i], 5, 5 + i * textH);
}
}
``````
Previous question

I feel like I can follow the logic and it makes sense, but I have been trying to interpolate a way to include a value for tenths of a second in line with the existing logic and I just don’t understand why it’s not working, so I guess I have to admit I do t really understand why it works.
Could someone please comment on the class pre() function and show me how I would add an extra step to get the tenths of a second in between milli and second, and tell me why my attempt is not working? I would really appreciate it.
In this sketch I’m not actually using the Time class, I pulled out the parts to just work in the draw() loop.

Previous code
``````int lastT, deltaT, carry, milli, tenths, sec;
void setup() {
size(400, 600);

lastT = millis();
milli = 0;
tenths = 0;
sec = second();
}

void draw() {
background(127);

int rightNow = millis();
deltaT = rightNow - lastT;
lastT = rightNow;
milli += deltaT;
carry = 0;

tenths = floor(milli / 100);
String tenthsStr1 = nf(tenths, 1);

carry = floor(tenths / 10);
String carryStr = nf(carry, 1);

tenths %= 10;
String tenthsStr2 = nf(tenths, 1);

sec += carry;
sec %= 60;

String secStr = nf(sec, 2);

String[] list = {

tenthsStr1,
tenthsStr2,
carryStr,
secStr

};

showTextArrayLeft(list);
}

void showTextArrayLeft(String[] strings) {

float textH = 18;
//textFont(mono);
textSize(textH);
textAlign(LEFT, TOP);
fill(0);
for (int i=0; i<strings.length; i++) {
text(strings[i], 5, 5 + i * textH);
}
}

public class Time {
private int lastT;
private int deltaT;
private int hour, minute, second, tenth, milli;

private final float ANGLE_OFFSET = - PI /2;

private final float ANGLE_HOUR = TWO_PI / 12;
private final float ANGLE_MINUTE = TWO_PI / 60;
private final float ANGLE_SECOND = TWO_PI / 60;

Time(int h, int m, int s) {
hour = h;
minute = m;
second = s;
tenth = 0;
milli = 0;
lastT = millis();
deltaT = 0;
}

public void pre() {
// Get the elapsed time since the last draw method
int carry = 0;
int now = millis();
deltaT = now - lastT;
lastT = now;
milli += deltaT;

carry = floor(milli / 1000); // integer division
milli %= 1000;

tenth = floor(milli / 100);

second += carry;
carry = floor(second / 60); // integer division
second %= 60;

minute += carry;
carry = floor(minute / 60); // integer division
minute %= 60;

hour += carry;
hour %= 24;
}

int getHour() {
return hour;
}

float getHourHandAngle() {
float t = (hour % 12) + (minute /  60f) + (second / 3600f) + (milli/ 3600000f);
return t * ANGLE_HOUR + ANGLE_OFFSET;
}

int getMinute() {
return minute;
}

float getMinuteHandAngle() {
float t = minute + (second / 60f) + (milli / 60000f);
return t * ANGLE_MINUTE + ANGLE_OFFSET;
}

int getSecond() {
return second;
}

float getSecondHandAngle() {
float t = second + (milli / 1000f);
return t * ANGLE_SECOND + ANGLE_OFFSET;
}

int getTenth() {
return tenth;
}

int getMilli() {
return milli;
}

public String toString() {
return getHour() + ":" + getMinute() + ":" + getSecond() + "." + milli;
}
}
``````
1 Like

generally you could do the date / time by

read: date time at start of program

and from then on use the millis() ( counting from start )
and there are many examples…

if you not need a very exact way / just a divider of the system seconds / into msec
you could use the millis Of This Second ( with a ERROR of possible 1/60= 17 msec )

``````long lastmillis; //______________________ memory of millis of last draw loop
int lastmillisOfSec; //__________________ memory of millis since last sec change
int lastsec; //__________________________ memory of last sec to get the change of sec. ( ERROR by 'dt' WITH 60 FPS / 17msec )

void setup(){
size(450,100);
textSize(20);
}

void draw(){
background(200,200,0);
fill(0);
text(nows(),10,20);
}

String nows() {
long tt = millis();
long dt = tt - lastmillis;
lastmillisOfSec +=dt;
int sec = second();
if ( sec != lastsec ) { //_____________ new second / reset sec millis
lastmillisOfSec = 0; //_____________ this can be 'dt' millis late
lastsec = sec;
}
lastmillis = tt; //____________________ last draw run
String thismillis = nf(lastmillisOfSec,3);
return ""+year()+"_"+nf(month(), 2)+"_"+nf(day(), 2)+" "+nf(hour(), 2)+":"+nf(minute(), 2)+":"+nf(second(), 2)+"."+thismillis+
"\n dt "+dt+" tt "+tt+" _ "+thismillis.charAt(0)+" _ "+thismillis.charAt(1)+" _ "+thismillis.charAt(2);
}

``````

1 Like

I’m mostly interested in learning how to make the algorithm do what I want it to do, or understanding it well enough to know if it can’t. The idea of taking parts away and carrying some to the next part looks like a tree of dividing a number into separate parts, and I want to understand how to add more branches without breaking the way it works.

1 Like