How to calculate the total hour worked between two dates? - java

I have two dates, hiring 11/19/2013 and endhiring 10/01/2014, both are converted to total hours, without considering the weekends, but they have different years and because of this the output says: the total hours worked was -1200:
private int calculateTimeInternship(Vacancy peoplevacancy){
int hourWorked = 0;
Calendar date1 = Calendar.getInstance();
Calendar date2 = Calendar.getInstance();
date1.setTime(peoplevacancy.getDthiring());
date2.setTime(peoplevacancy.getDtendhiring());
int initiation = date1.get(Calendar.DAY_OF_YEAR);
int end = date2.get(Calendar.DAY_OF_YEAR);
int amountDay = (initiation - end) + 1;
for (; initiation <= end; inicio++){
if (date1.get(Calendar.DAY_OF_WEEK) == 1 || date1.get(Calendar.DAY_OF_WEEK) == 7)
amountDay--;
date1.add(Calendar.DATE, 1);
}
hourWorked = amountDay * 4 //4 hour per day;
return hourWorked ;
}

Joda can help you, but I'm never able to use it because of its license.
If like me, Joda is not appropriate for you, you can solve this problem as follows:
initialize endDate object
initialize startDate object
initialize weeksBetween as
milliseconds between end&start/milliseconds per day, divided by seven (integer floor).
//may need to normalize dates and set them to be both midnight or noon or some common time
initialize daysBetween = weeksBetween*5 // in any continuous 7 days, 5 are weekdays.
initialize curDay=startDate + weeksBetween*7 days
while(curDay is not endDate)
add a day to curDay
if(curDay is not weekend)
daysBetween++
output daysBetween* 4
You can get the milliseconds between them by converting the calendars to Date (Calendar has such a method to do this)

You are already looping through every day of the internship, so why not simply count workdays?
int amountDay = 0;
while (date1.compareTo(date2) <= 0) {
if (date1.get(Calendar.DAY_OF_WEEK) != 1
&& date1.get(Calendar.DAY_OF_WEEK) != 7)
amountDay++;
date1.add(Calendar.DATE, 1);
}
By the way, your original code has a subtle "off by one" bug. The subtraction for the total amountDays excludes the end day, but the loop includes the end day when deducting weekends.

Why so complicated?
private int calculateTimeInternship(Vacancy vacancy) {
return 4 * ((int)(vacancy.getDtendhiring().getTime() / 86400000L - vacancy.getDthiring().getTime() / 86400000L) + 1);
}
By dividing by 86400000 first, then subtracting, it doesn't matter what time of day each date have.
FYI 86400000 is the number of milliseconds in a day.

Related

How to calculate relative time spans using Java (code converting problem)? [duplicate]

This question already has answers here:
Java 8: Difference between two LocalDateTime in multiple units
(11 answers)
Closed 2 years ago.
I decided to give myself a challenge on Java that implements this question's achievement.
The things I have to do is get LocalDateTime, convert the same code from the linked question's answers, then receiving a string from the function.
Here's what I've done so far:
public static String relTime(LocalDateTime now)
{
// accepted answer converted to Java
const int min = 60 * SECOND;
const int hour = 60 * MINUTE;
const int day = 24 * HOUR;
const int mon = 30 * DAY;
// still don't know how to convert this method
var ts = new TimeSpan(DateTime.UtcNow.Ticks - yourDate.Ticks);
double delta = Math.Abs(ts.TotalSeconds);
if (delta < 1 * MINUTE)
return ts.Seconds == 1 ? "one second ago" : ts.Seconds + " seconds ago";
if (delta < 2 * MINUTE)
return "a minute ago";
if (delta < 45 * MINUTE)
return ts.Minutes + " minutes ago";
if (delta < 90 * MINUTE)
return "an hour ago";
if (delta < 24 * HOUR)
return ts.Hours + " hours ago";
if (delta < 48 * HOUR)
return "yesterday";
if (delta < 30 * DAY)
return ts.Days + " days ago";
if (delta < 12 * MONTH)
{
int months = Convert.ToInt32(Math.Floor((double)ts.Days / 30));
return months <= 1 ? "one month ago" : months + " months ago";
}
else
{
int years = Convert.ToInt32(Math.Floor((double)ts.Days / 365));
return years <= 1 ? "one year ago" : years + " years ago";
}
}
The only problem that I should encounter is from var ts = new TimeSpan(DateTime.UtcNow.Ticks - yourDate.Ticks);.
Although I read 2 questions from Stack Overflow finding equivalents of TimeSpan and Ticks, I baely have any ideas how to properly convert the line of code. Also, I have to get a double which will need math.abs() to get TotalSeconds which I can't really find a proper way to deal with either, but I did find ZoneOffset.ofTotalSeconds and still don't know how to deal with it.
So how can I convert this properly?
var ts = new TimeSpan(DateTime.UtcNow.Ticks - yourDate.Ticks);
double delta = Math.Abs(ts.TotalSeconds);
You need to gain a deeper understanding of what this method actually does. Literally translating code from C# to Java won't give you a good solution and gets you stuck on language-specific details.
The two lines basically calculate the (absolute) difference in seconds of a timestamp to the current time. This can be written in Java as follows:
Duration duration = Duration.between(LocalDateTime.now(), timestamp);
long delta = duration.abs().getSeconds();
I'm just addressing your actual question here on how to transform these two lines. The provided snippet is not valid Java code and some parts are missing. delta is the difference in seconds which does not necessarily need to be a double. The argument you pass to your method should be named anything else than now because this is the timestamp you want to compare to the current time inside the method.
You could use SimpleDateFormat to create a nice display format (use something like "HH hours, mm minutes and ss seconds ago" for the format (not sure if this exact example works)). You could also use Instant to get the current time, and you can use Instant.now().minusSeconds(Instant.now().minusSeconds(seconds).getEpochSeconds()) for the time difference (or just use System.currentTimeMillis() and multiply by 1000).
Alternatively, you could use Duration and write a custom display format using getSeconds() and getHours() etc.

How to transfer Date.getTime() to hours and calculating difference

I have a program that is intaking an "AM" "PM" time and calculating out the hours in the day equivalent (in 24 hour format). For some reason it parses and calculates the time I input to the incorrect 24 hour equivalent (ie 5:00 pm comes to equal 22)
System.out.print("Enter the end time (HH:MM am): ");
endTime = input.nextLine();
Date ETime = time_to_date.parse(endTime);
Class method
public int get_Family_A_Calulation(Date STime, Date ETime) {
Date startTimeCalc = STime, endTimeCalc = ETime;
int pay = 0, hoursWorked, StartHour, EndHour;
StartHour = ((((int) startTimeCalc.getTime()) / 1000) / 60) / 60;
EndHour = ((((int) endTimeCalc.getTime()) / 1000) / 60) / 60;
pay = hoursWorked * 15;
return pay;
}
I am not sure where my error is can anyone give me advice on how to correct this error?
Use the latest classes available fron java8
LocalDateTime now = LocalDateTime.now();
System.out.println(now.getHour());
The actual data behind Date is milliseconds since the epoch. Any hour or time representation is based on the calendar date portion and takes into account timezone and daylight savings.
Regardless of what you do, there will be calculation issues across days, etc.
As suggested by Scary Wombat, use the new classes in java.time package. For your specific case, you need a LocalTime as the code is trying to represent a time element (hours, minutes, seconds, etc) without consideration for Date, TimeZone, etc.
https://docs.oracle.com/javase/8/docs/api/java/time/LocalTime.html

Find Day of Week Without Using Calendar function in Java

I need to find the day of the week (i.e. Monday, Tuesday...) given MM-DD-YYYY. So basically what java calendar would do, but without using java calendar.
It is possible, though unusual, to compute a number that corresponds to the day of the week from a calendar date.
In brief, you will first need to calculate a serial date number from the calendar date, i.e. a number that is a continuous count of days that have elapsed since a certain fixed point in time (informally called 'the epoch'). The most commonly encountered serial date scheme encountered in modern computing is Posix Time, which has an epoch date of Jan 1, 1970 at midnight UTC.
You will need to decide what level of precision is needed for this calculation, eg. whether you will need to account for the Julian Calendar (used in most of Europe before the Gregorian Calendar reform by Pope Gregory in 1584), whether to correct for century days, etc.
Several algorithms are available to arithmetically convert a calendar date to a serial date number with a given epoch. Historically, the most commonly used epoch for these calculations has been the Julian Day number system (not to be confused with the Julian Calendar), which counts days from November 24, 4714 BC in the proleptic Gregorian calendar. Below is Java code which implements one such algorithm published by Jean Meeus in his book "Astronomical Algorithms, 2nd Ed." This algorithm computes a Julian Day number and assumes that days are exactly 86400 seconds in length, accounts for the general Gregorian Reform, and accounts for century and leap days:
public class JulianDay {
private static final int YEAR = 0;
private static final int MONTH = 1;
private static final int DAY = 2;
private static final int HOURS = 3;
private static final int MINUTES = 4;
private static final int SECONDS = 5;
private static final int MILLIS = 6;
:
:
// Converts a timestamp presented as an array of integers in the following
// order (from index 0 to 6): year,month,day,hours,minutes,seconds,millis
// month (1-12), day (1-28 or 29), hours (0-23), min/sec (0-59) to a
// Julian Day Number.
// For clarity and simplicity, the input values are assumed to be well-formed;
// error checking is not implemented in the snippet.
public static double toJD(int[] ymd_hms) {
int y = ymd_hms[YEAR];
int m = ymd_hms[MONTH];
double d = (double) ymd_hms[DAY];
d = d + ((ymd_hms[HOURS] / 24.0) +
(ymd_hms[MINUTES] / 1440.0) +
(ymd_hms[SECONDS] / 86400.0) +
(ymd_hms[MILLIS] / 86400000.0));
if (m == 1 || m == 2) {
y--;
m = m + 12;
}
double a = Math.floor(y / 100);
double b = 2 - a + Math.floor(a / 4);
return (Math.floor(365.25 * (y + 4716.0)) +
Math.floor(30.6001 * (m + 1)) +
d + b - 1524.5);
}
}
Once you have a serial date number, it is straightforward to compute the day of the week from the remainder when the date number is divided by 7 (the number of days in a week).
If you are talking about simply avoiding the Calendar Object then you could use the Date Object (deprecated) but still works and call setMonth, setYear, and setDate to get the desired date. You then have to use a DateFormatter to get your desired output. I used a SimpleDateFormat and the E specifier to get the day of the week.
Date dNow = new Date();
SimpleDateFormat ft = new SimpleDateFormat ("E");
System.out.println("Current Date: " + ft.format(dNow));
This outputs the current day of the week "Sun", "Sat", etc..
This link will help with the formatting https://www.tutorialspoint.com/java/java_date_time.htm
java.time
Using the java.time classes that supplant the troublesome old date-time classes. The LocalDate class represents a date without a time-of-day and without a time zone.
DayOfWeek dow =
LocalDate.parse(
"01-23-2016" ,
DateTimeFormatter.ofPattern( "MM-dd-uuuu" )
).getDayOfWeek()
That code returns a DayOfWeek enum object. From there you can interrogate for:
Integer number, 1-7 for Monday-Sunday
Localized name of the day.
Example code.
int dowNumber = dow.getValue() ;
String dowName = dow.getDisplayName(
TextStyle.FULL ,
Locale.CANADA_FRENCH ) ; // Or Locale.US, Locale.ITALY, etc.
TIP: Pass around the DayOfWeek objects themselves in your own code, rather than internally track the day-of-week as a number or string. This makes your code more self-documenting, ensures valid values, and provides for type-safety.
I was looking for the answer myself and found another answer based on Zeller's algorithm:
// d = day in month
// m = month (January = 1 : December = 12)
// y = 4 digit year
// Returns 0 = Sunday .. 6 = Saturday
public int dow(int d, int m, int y) {
if (m < 3) {
m += 12;
y--;
}
return (d + int((m+1)*2.6) + y + int(y/4) + 6*int(y/100) + int(y/400) + 6) % 7;
}
Source: here

How to check if there is at least 1 day difference between 2 dates

So, I have to check if the difference between 2 dates is at least one day. Then the method should return true, otherwise it is false.
The format for dates that I´m using is GregorianCalendar(year, month, day).
So I already have a method that uses date1.before(date2), but that also checks the time, so ifdate1 is before date2 it returns true, even if they are the same day (but the time is different!).
What I need is a way to check if the difference between the dates is at least 1 day.
Any ideas?
You can use something like this:
public boolean dateDifference(Date d1, Date d2)
{
long currentDateMilliSec = d1.getTime();
long updateDateMilliSec = d2.getTime();
long diffDays = (currentDateMilliSec - updateDateMilliSec) / (24 * 60 * 60 * 1000);
if (diffDays >= 1) return true;
else return false;
}
Add 1 day to cal1 and test if it's not after cal2
cal1.add(Calendar.DATE, 1);
System.out.println(!cal1.after(cal2));

JodaTime Calculate total hours worked in a week

Currently I have a function which can take the start time and end time of one day, and calculate the difference between the two, giving me the hours worked in a day. What I would like to do is be able to get the hours worked for 7 days, and return a grand total, while remaining with the display format (HH:mm).
My function for a single day's total:
Period p = new Period(this.startTime[dayIndex], this.endTime[dayIndex]);
long hours = p.getHours();
long minutes = p.getMinutes();
String format = String.format("%%0%dd", 2);//Ensures that the minutes will always display as two digits.
return Long.toString(hours)+":"+String.format(format, minutes);
this.startTime[] & this.endTime[] are both arrays of DateTime objects.
Any suggestions?
You'll need something to hold a week's worth of days, and call your function once for each day.
But that means you'll want to refactor so that your calculator method doesn't format as a string, but instead returns a numeric value, so you can easily add them together.
Another simple solution:
Here is a method that receives separate the hours and minutes.The parameters are:
Start Hour
Start Minutes
End Hour
End Minutes
first, calculate the difference between hours and minutes separate:
int hours = pEndHour - pStartHour;
int minutes = ((60 - pStartMinutes) + pEndMinutes) - 60;
then, validates if the value of "minutes" variable is negative:
// If so, the "negative" value of minutes is our remnant to the next hour
if (minutes < 0) {
hours--;
minutes = 60 + minutes ;
}
Finally you can print the period of time in the hour format:
String format = String.format("%%0%dd", 2);
System.out.println( "*** " + hours + " : " + minutes);
That's all.
Solution I ended with for those interested
Period[] p=new Period[7];
long hours = 0;
long minutes =0;
for(int x=0; x<=this.daysEntered;x++)
{
p[x] = new Period(this.startTime[x], this.endTime[x]);
hours += p[x].getHours();
minutes += p[x].getMinutes();
}
hours += minutes/60;
minutes=minutes%60;
String format = String.format("%%0%dd", 2);
return Long.toString(hours)+":"+String.format(format, minutes);

Categories

Resources