Creating a java Clock. increasing time - java

I am creating a clock in Java. I have managed to do some very basic stuff and now i want to implement a function.
If i set the time to i.e. 12:04:59 and use my timeTick Method it will increase the time with 1 second but the problem is it will say the time is 12:04:60 and it doesn't change to 12:05:00.
I've been struggling a while now and i can't really find a solution to it.
My code is below, i hope you can help me,
public class Clock{
public int seconds;
public int minutes;
public int hours;
public Clock ( int InsertSeconds, int InsertMinutes, int InsertHours){
seconds = InsertSeconds;
minutes = InsertMinutes;
hours = InsertHours;
}
public void timeTick(){
seconds = seconds + 1;
}
public String toString(){
return hours + ":" + minutes + ":" + seconds;
}
}
I am not planning to use Imports because i am a beginner it would be great if we can keep it simple.

The problem here lays in the timeTick() function. In a real clock example we have some extra rules for counting. Every time we count to 60 seconds, we add a minute. Every time we count to 60 minutes, we add an hour. So you have to implement these rules.
// lets make some simple code
public void timeTick(){
seconds = seconds + 1; // you can also use seconds++; it means exactly the same thing
if(seconds == 60){
minutes++; // we reached a minute, we need to add a minute
seconds = 0; // we restart our seconds counter
if(minutes == 60){
hours++; // we reached an hour, we need to add an hour
minutes = 0; // we restart our minutes counter
// and so on, if you want to use days (24 h a day) , months ( a bit more difficult ), ...
}
}
}
I hope this will help you, for a starter it might be a good idea to split the second part of code into a function, which deals with this situation. Good luck!

How about this:
public void timeTick () {
seconds++;
while (seconds >= 60) {
minutes++;
seconds-=60;
}
while (minutes >= 60) {
hours++;
minutes-=60;
}
}

Try this :
public void timeTick () {
seconds++;
if (seconds == 60)
{
seconds = 0;
minutes++;
if (minutes == 60)
{
minutes = 0;
hours++;
}
}
}

try this:
public class Clock{
public int seconds;
public int minutes;
public int hours;
public Clock ( int InsertSeconds, int InsertMinutes, int InsertHours){
seconds = InsertSeconds;
minutes = InsertMinutes;
hours = InsertHours;
}
public void timeTick(){
seconds = seconds + 1;
if(seconds==60){
minutes++;
seconds=0;
if(minutes==60){
hours++;
minutes=0;
}
}
}
public String toString(){
return hours + ":" + minutes + ":" + seconds;
}
}

You could check for when you have 60 seconds, then reset seconds to zero, and increase minutes by 1. e.g.
if (the condition you want to check) {
//increase the number of minutes.
//reset number of seconds.
}
If you're entering seconds values of more than 60, you'll need to work out how many minutes that equals using division, and the remaining number of seconds using the modulus operator: % e.g.
seconds = 125;
minutes = seconds / 60; // 2 minutes
remaining_seconds = seconds % 60; // 5 seconds

Related

How should the moveForward(lostTime) give the correct output when the hour and minute variables go below zero?

I knew the method of delaying by minutes, for instance, from 22:50 to 2:10. I inserted 200 in the parameter of delay method, I am concerned that the method of moving the time forward is not working as I attempted by setting the time 1:20 and moving 100 minutes (1 hour and 40 minutes) forward to 23:40. As I tried to run the code, the output displayed 1:40 after moving the time forward. Which line was wrong in the method of moveForward(int lostMinute)?
class Time
{
private int hour; // between 0 - 23
private int minute; // between 0 - 59
public Time()
{
this(0, 0);
}
public Time(int hr, int min)
{
hour = (hr >= 0 && hr < 24) ? hr : 0;
minute = (min >= 0 && min < 60) ? min : 0;
}
public int getHour()
{
return hour;
}
public int getMinute()
{
return minute;
}
public void setHour(int hour)
{
this.hour = (hour >= 0 && hour < 24) ? hour : 0;
public void setMinute(int minute)
{
this.minute = (minute >= 0 && minute < 60) ? minute : 0;
}
public String toString()
{
return String.format("%02d:%02d", hour, minute);
}
public void delay(int newMinute)
{
minute = minute + newMinute;
if(minute >= 60)
{
// (minute / 60) is an integer division and truncates the remainder, which refers to (minute % 60)
hour = hour + (minute / 60);
minute = minute % 60;
if(hour >= 24)
{
hour = hour % 24;
}
}
}
public void moveForward(int lostMinute)
{
if(minute < lostMinute)
{
hour = hour - ((60 + minute) / 60);
minute = (minute + 60) % 60;
if(hour < 0)
{
hour = (24 + hour) % 24;
}
}
else
{
minute = minute - lostMinute;
}
}
}
I saw that delay() is working correctly while moveForward() is not. To make the time notation clearer for sorting, I used String.format("%02d:%02d") to indicate the time between 00:00 and 23:59. Please note that I am not using import java.util.Calender; or 'import java.util.Date; because part of my project consists of sorting an array by just hours and then minutes. For instance, if we are trying to create the bus terminal project, we assume that the date and calendar do not matter in schedule.
public class MainTime
{
public static void main(String[] args)
{
Time t1 = new Time(23:50);
Time t2 = new Time(1:20);
Time t3 = new Time(4:50);
Time t4 = new Time(18:30);
Time t5 = new Time(14:15);
t1.delay(200);
t2.moveForward(100);
t3.delay(100);
t4.moveForward(20);
t5.moveForward(160);
System.out.println(t1.toString());
System.out.println(t2.toString());
System.out.println(t3.toString());
System.out.println(t4.toString());
System.out.println(t5.toString());
}
}
The constraints are when the change in time is greater than the minute in parameter and when the hour is going to zero. When I ran the code in NetBeans, t1 had 2:10 when I added 200 into 23:50 in delay(newMinute) method; t2 had 1:40 when I subtracted 100 from 1:20 in moveForward(lostMinute) method; t3 had 6:30 when I added 100 into 4:50 in delay(newMinute); t4 had 18:10 when I subtracted 20 from 18:30 in moveForward(lostMinute); t5 had 14:-25 when I subtracted 160 from 14:15 in moveForward(lostMinute). The variables t2 and t5 after execution should actually be 23:40 and 11:35, respectively.
Please determine which lines in public void moveForward(int lostMinute) make the improper output after subtracting the minutes from given time.
In case the minute goes to zero, 60 and modulo notation % could be useful; in case the hour goes to zero, 24 and modulo notation % could be useful. I hope for the moveForward(lostMinute) to work well in the cases when minute < 0 and when hour < 0.
java.time
LocalTime t1 = LocalTime.of(23, 50);
t1 = t1.plusMinutes(200);
System.out.println(t1.toString()); // 03:10
LocalTime t2 = LocalTime.of(1, 20);
t2 = t2.minusMinutes(100);
System.out.println(t2.toString()); // 23:40
LocalTime t3 = LocalTime.of(4, 50);
t3 = t3.plusMinutes(100);
System.out.println(t3.toString()); // 06:30
LocalTime t4 = LocalTime.of(18, 30);
t4 = t4.minusMinutes(20);
System.out.println(t4.toString()); // 18:10
LocalTime t5 = LocalTime.of(14, 15);
t5 = t5.minusMinutes(160);
System.out.println(t5.toString()); // 11:35
Output is given as comments. I think it is what you wanted. So don’t reinvent the wheel. Instead of rolling your own Time class, use LocalTime. It’s there for you to use, it has been developed and tested for you. LocalTime is a time of day in the interval from 00:00 to 23:59:59.999999999. Except that it include seconds and fraction of second it coincides with your interval. If you never set the seconds to something other than 0, they won’t be printed through the toString method. Also LocalTime implements Comparable, so sorting is straightforward.
Be aware that a LocalTime object is immutable, so instead of mutator methods it has methods that return a new LocalTime object with the new value. This is already demonstrated with plusMinutes and minusMinutes above. Also instead of myLocalTime.setHour(17); you need myLocalTime = myLocalTime.withHour(17);, etc.
What went wrong in your code?
Your moveForward method seems to be handling the hour correctly in the case where it is to be moved back to the previous hour, for example from 14:05 to 13:55 or from 14:55 to 13:05. In this case you are never subtracting lostMinutes, which I think you should somehow. When minute is 0–59, then ((60 + minute) / 60) will always be 1, so you are always subtracting exactly 1 hour, never 2 or more.
Genrally the expected ranges of the arguments to both delay and moveForward are unclear. I think they should have been documented and the arguments validated against the documented limits.
Link
Oracle tutorial: Date Time explaining how to use java.time.

Write code segment that prints out the sequence of all hour and minute combinations of the day starting with 4:00A.M. and ending with 12:59 AM

Use while loops only.
Can I get hints?
I don't know what "sequence of all hour and minute combinations of the day" means.
Does it mean a continuously printing timestamp with the hour and minute at each interval?
This is what I tried. Can you help me with my errors?
int hours = 4;
int minutes = 0;
TimePrinter(minutes, hours);
while (hours<=12)
{
while ( hours<=12 &&minutes<=59)
{
TimePrinter(minutes,hours);
minutes++;
while (hours<= 12 && minutes== 60)
{
minutes = 0;
hours++;
TimePrinter(minutes,hours);
}
}
}
}
private static void TimePrinter(int minutes, int hours) {
if (hours <12 && minutes<10)
{System.out.println(hours + ":0" + minutes );}
else
{System.out.println(hours + ":" + minutes);}
}
}
I think this mean sequence
00:00
00:01
...
00:59
01:00
....
23:58
23:59
I don't remember C syntax good, but I will try
int hours = 0;
int minutes = 0;
while(hours <= 23) {
while(minutes <= 59) {
printf("%02d:%02d\n", hours, minutes);
minutes++;
}
hours++;
minutes = 0
}
UPD: I'm sorry Only now view that you need Java. I think I can understand my idea and code.

JAVA convert minutes into default time [hh:mm:ss]

what is the easiest and fastest way to convert minutes (double) to default time hh:mm:ss
for example I used this code in python and it's working
time = timedelta(minutes=250.0)
print time
result:
4:10:00
is there a java library or a simple code can do it?
EDIT: To show the seconds as SS you can make an easy custom formatter variable to pass to the String.format() method
EDIT: Added logic to add one minute and recalculate seconds if the initial double value has the number value after the decimal separator greater than 59.
EDIT: Noticed loss of precision when doing math on the double (joy of working with doubles!) seconds, so every now and again it would not be the correct value. Changed code to properly calculate and round it. Also added logic to treat cases when minutes and hour overflow because of cascading from seconds.
Try this (no external libraries needed)
public static void main(String[] args) {
final double t = 1304.00d;
if (t > 1440.00d) //possible loss of precision again
return;
int hours = (int)t / 60;
int minutes = (int)t % 60;
BigDecimal secondsPrecision = new BigDecimal((t - Math.floor(t)) * 100).setScale(2, RoundingMode.HALF_UP);
int seconds = secondsPrecision.intValue();
boolean nextDay = false;
if (seconds > 59) {
minutes++; //increment minutes by one
seconds = seconds - 60; //recalculate seconds
}
if (minutes > 59) {
hours++;
minutes = minutes - 60;
}
//next day
if (hours > 23) {
hours = hours - 24;
nextDay = true;
}
//if seconds >=10 use the same format as before else pad one zero before the seconds
final String myFormat = seconds >= 10 ? "%d:%02d:%d" : "%d:%02d:0%d";
final String time = String.format(myFormat, hours, minutes, seconds);
System.out.print(time);
System.out.println(" " + (nextDay ? "The next day" : "Current day"));
}
Of course this can go on and on, expanding on this algorithm to generalize it. So far it will work until the next day but no further, so we could limit the initial double to that value.
if (t > 1440.00d)
return;
Using Joda you can do something like:
import org.joda.time.Period;
import org.joda.time.format.PeriodFormatter;
import org.joda.time.format.PeriodFormatterBuilder;
final Period a = Period.seconds(25635);
final PeriodFormatter hoursMinutes = new PeriodFormatterBuilder().appendHours().appendSuffix(" hour", " hours")
.appendSeparator(" and ").appendMinutes().appendSuffix(" minute", " minutes").appendSeparator(" and ")
.appendSeconds().appendSuffix(" second", " seconds").toFormatter();
System.out.println(hoursMinutes.print(a.normalizedStandard()));
//Accept minutes from user and return time in HH:MM:SS format
private String convertTime(long time)
{
String finalTime = "";
long hour = (time%(24*60)) / 60;
long minutes = (time%(24*60)) % 60;
long seconds = time / (24*3600);
finalTime = String.format("%02d:%02d:%02d",
TimeUnit.HOURS.toHours(hour) ,
TimeUnit.MINUTES.toMinutes(minutes),
TimeUnit.SECONDS.toSeconds(seconds));
return finalTime;
}

Clever ways to restrict integer from 100 based to 60 based for time values? (e.g.60 seconds in a minute)

I am required to store a time value in an integer in the format of HHMMSS. this time value is incrementing every second (basically a custom clock). however, since integers are naturally 10 based, I must implement a large cumbersome logic that extracts each digits and checks for 60 seconds in a minutes, 60 minutes in an hour and 24 hours a day. I wonder if there is some clever ways to do it without a massive if/else if chunk.
You can use the modulus operator to pick out each of the components of a single seconds counter:
int totalSeconds;
...
int seconds = totalSeconds % 60;
int minutes = (totalSeconds / 60) % 60;
int hours = (totalSeconds / 3600);
Then you can just increment a single seconds counter and extract each of the components.
My suggestion would be to implement a CustomClock class, which could look something like:
public class CustomClock {
private int hour;
private int minute;
private int second;
public CustomClock(int hour, int minute, int second) {
this.hour = hour;
// ...
}
public void increment() {
second = second + 1)%60;
if (second == 0) minute = (minute + 1)%60;
if (minute == 0) hour = (hour + 1)%24;
}
}
Thus taking advantage of the mod operator (%) to compute arbitrary base numbers.

Format Stopwatch to display 00:00

I am experimenting with using a stopwatch in one of my apps and I have got it to where it will start counting seconds on start and stop counting on stop. My problem is that it will keep going on after 60 seconds. For example I get 120 seconds if I waited for two minutes.
So my question is how can I make it so once the seconds reached 60 the minutes would be increased by one and the seconds would start over?
So instead of :120 I would get 2:00. Here is the code I have:
final int MSG_START_TIMER = 0;
final int MSG_STOP_TIMER = 1;
final int MSG_UPDATE_TIMER = 2;
Stopwatch timer = new Stopwatch();
final int REFRESH_RATE = 100;
Handler mHandler = new Handler()
{
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case MSG_START_TIMER:
timer.start();
mHandler.sendEmptyMessage(MSG_UPDATE_TIMER);
break;
case MSG_UPDATE_TIMER:
tvTextView.setText(":"+ timer.getElapsedTimeSecs());
mHandler.sendEmptyMessageDelayed(MSG_UPDATE_TIMER,REFRESH_RATE);
break;
case MSG_STOP_TIMER:
mHandler.removeMessages(MSG_UPDATE_TIMER);
timer.stop();
tvTextView.setText("");
break;
default:
break;
}
}
};
Also are:
public void start(View v) {
mHandler.sendEmptyMessage(MSG_START_TIMER);
}
public void stop(View v) {
mHandler.sendEmptyMessage(MSG_STOP_TIMER);
}
By the way I looked at this question but his issue was with TimeSpan and if I understand correctly that is different from Stopwatch(correct me if I am wrong). Thanks for your time and effort.
If you start with the time in seconds:
display = String.format("%d:%02d", seconds / 60, seconds % 60);
If you don't want the minutes if they are 0:
if (seconds < 60)
display = String.format("%02d", seconds);
else
display = String.format("%d:%02d", seconds / 60, seconds % 60);
You are just going to have to make a function that creates a string for you. Stash this somewhere reachable.
public String NumToStr(long i){
if (i < 10 ) {
return ("0" + Long.toString(i));
}
return Long.toString(i);
}
this will take any number that is less than 10 and give you a string with a "0" infront of the number.
i.e. send it a 7 and get "07" then send it a 55 and get "55" because it was not less than 10. Finaly send it the seconds 5 and get "05". Now add the strings together,
Hour + ":" + Minute + ":" + Seconds;
and you will get "07:55:05"
next just put in a
if (seconds > 60) {
seconds = 0
minutes++;
}
if (minutes > 60) {
minutes = 0
hours++;
}
if (hours > 12) {
hours = 0
}
With all respect this is basic stuff.
In response to where should you put all of this? Where ever you like. But you need to redo some of your code.
case MSG_UPDATE_TIMER:
long TimePassed;
TimePassed = Seconds;
if (Minutes > 0) {
TimePassed = TimePassed + (60 * Minutes);
}
if (Hours > 0) {
TimePassed = TimePassed + (60 * 60 * Hours);
}
Seconds = (timer.getElapsedTimeSecs()- TimePassed );
if (Seconds > 60) {
Seconds = 0
Minutes++;
}
if (Minutes > 60) {
Minutes = 0
hours++;
}
String timeSecs = NumToStr(Seconds);
String timeMins = NumToStr(Minutes);
String timeHours = NumToStr(Hours);
String Time = timeHours + ":" + timeMins + ":" + timeSecs;
tvTextView.setText(Time);
mHandler.sendEmptyMessageDelayed(MSG_UPDATE_TIMER,REFRESH_RATE);
break;

Categories