So I am currently working on a project and I have a method which is suppose to help me calculate the working hours of employees based on a simple formula which is work hours = logout - login - break.
For some reason best known to my computer, the value of my break time gets reduced by 1 all the time. Can anyone please let me know why this is happening and how I can resolve it? Thanks
public String calculateHoursWorked() throws ParseException {
Scanner sc = new Scanner(System.in);
System.out.println("Please enter your login time:");
loginTime = sc.nextLine();
System.out.println("Please enter your break duration:");
breakTime = sc.nextLine();
System.out.println("Please enter your logout time:");
logoutTime = sc.nextLine();
SimpleDateFormat format = new SimpleDateFormat("HH:mm");
Date login = format.parse(loginTime);
Date logout = format.parse(logoutTime);
Date breakPeriod = format.parse(breakTime);
//calculate the total number of hours worked in a day
long totalHoursWorked = logout.getTime() - login.getTime() - breakPeriod.getTime();
//get the breaktime in milliseconds to make sure we have the right value here
long breakTimeinMilliseconds = breakPeriod.getTime();
System.out.println("So our break time is ms is: "+ breakTimeinMilliseconds);
String test = DurationFormatUtils.formatDuration(breakTimeinMilliseconds,"HH:mm");
System.out.println("Your break time is: " + test);
return DurationFormatUtils.formatDuration(totalHoursWorked, "HH:mm");
//return String.valueOf(logout.getTime() - (login.getTime() + break_Period.getTime()));
}
This is the output I get on my console:
Please enter your login time:
02:00
Please enter your break duration:
**02:00**
Please enter your logout time:
10:00
So our break time is ms is: 3600000
**Your break time is: 01:00** (entered 02:00 above but I get 01:00 here)
Your working time is: 07:00 ***(This has to be 6)***
The Javadoc of Date
says:
The class
Date
represents a specific instant in time, with millisecond precision.
and
public long getTime()
Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT represented by this Date object.
Hm, so which Timezone is the SimpleDateFormatter using? It's Javadoc says:
public SimpleDateFormat(String pattern)
Constructs a SimpleDateFormat using the given pattern and the default date format symbols for the default FORMAT locale.
(emphasis mine)
The default locale is the default locale set in your computer's operating system.
So your program:
SimpleDateFormat format = new SimpleDateFormat("HH:mm");
Date breakPeriod = format.parse(breakTime);
long breakTimeinMilliseconds = breakPeriod.getTime();
asks the computer to interpret the text as an instant in time using the default time zone of your computer. Your computer therefore interprets "02:00" as two hours after midnight, Central European Time. Then, you ask how long after midnight, GMT, that was. The computer knows that 02:00 CET is 01:00 GMT, so answers 3600000. That is, in using a class intended to represent instants in time with respect to some timezone, and using methods that default to different time zones, your code managed to accidentally convert between time zones :-)
Because the Date
class is prone to such programming mistakes, it has been superseeded by a new date and time api, which you can find in the package java.time
. Using that package, you can write:
var login = LocalTime.parse("08:00");
var breakDuration = Duration.between(LocalTime.MIDNIGHT, LocalTime.parse("02:00"));
var logout = LocalTime.parse("18:00");
var workDuration = Duration.between(login, logout).minus(breakDuration);
var workDurationString = LocalTime.MIDNIGHT.plus(workDuration).toString();
(if you wish to be more lenient in parsing / formatting, or use a different format, you may want to use a DateTimeFormatter
, possibly obtained from a DateTimeFormatterBuilder
, instead)
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments