Java -Get a Date between two Dates, Giving unexpected result - java

So i'm trying to get a random time between two set times. But the resulting date is not what I'm expecting.
I'm expecting a result that is within the two dates I give as the earliest and the latest, but I get a date thats on the next day, and it appears as though if I take the time i'm supposed to get and subtract 12 I get this answer.
This is the log get: http://prntscr.com/6205yh
private long nextLong(Random rng, long n) {
long bits, val;
do
{
bits = (rng.nextLong() << 1) >>> 1;
val = bits % n;
} while (bits - val + (n - 1) < 0L);
return val;
}
#SuppressWarnings("deprecation")
public Calendar getNextDate() {
try
{
Calendar now = Calendar.getInstance(Locale.getDefault());
String earliest = getConfig().getString("Date.Spawn Earliest");
String latest = getConfig().getString("Date.Spawn Latest");
// Format the hours and minutes into dates
SimpleDateFormat format = new SimpleDateFormat("HH:mm");
Date earliestDate = format.parse(earliest);
Date latestDate = format.parse(latest);
// Figure out the random time between the two
long e = earliestDate.getTime();
long l = latestDate.getTime();
long d = nextLong(new Random(), l - e) + e;
Date date = new Date(d);
// Update the hours and minutes into a new Calander with todays day,month and year.
Calendar then = Calendar.getInstance(Locale.getDefault());
System.out.println(date.getHours()+":"+date.getMinutes());
then.set(Calendar.HOUR, date.getHours());
then.set(Calendar.MINUTE, date.getMinutes());
// If it is later then the random time and nows hours are still higher then the latest time; add 7 days to get next week
if (now.after(then) && now.getTime().getHours() > latestDate.getHours())
then.add(Calendar.DAY_OF_MONTH, 7);
System.out.println("At the moment it is: " + now.getTime().toString());
System.out.println("Dragon will spawn at: " + then.getTime().toString());
return then;
}
catch (ParseException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}`
If someone could explain to me whats going on I would be very grateful.

This could be better :)
Date dateStart;
Date dateEnd;
int diff = (int) (dateEnd.getTime() - dateStart.getTime());
Date randomDate = new Date(dateStart.getTime()
+ new Random(System.currentTimeMillis()).nextInt(diff));
Calendar then = Calendar.getInstance();
then.setTime(randomDate);

Related

Schedule assignment, Java current time between to times that are parse from a schedule

I'm new here and I already have a question.
I'm making a assignment for school (in Processing with Java), we are loading a schedule from a txt file.
And I need to make a visualisation from it, it's going good but I'm stuck at one point.
I want to make a if statement, to see if the current time is between the Start time and end time. I did parse the start time and End time from the txt file and I can call the current time. But i can't find or know the if statement. can someone help?
Parts of my code ( i can't show everything because i have 6 tabs) :
**//From the main tab**
int s = second(); // Values from 0 - 59
int mi = minute(); // Values from 0 - 59
int h = hour(); // Values from 0 - 23
int d = day(); // Values from 1 - 31
int mo = month(); // values from 1 - 12
int y = year();
// searching all data from Table, comparing location with roomsTTH, if its the same check iff itint(random(20)), 20's free
for (TableRow singleRow : tableRooster.rows()) {
ParseInfo parse = new ParseInfo(singleRow);
for (Room roomToCheck : roomsTTH) {
if (parse.location == roomToCheck.id) {
if (roomToCheck.available) {
if ( y == parseInt(parse.year)) {
if (mo == parseInt(parse.month)) {
if ( d == parseInt(parse.day)) {
// if ( isBetween = currentTime.after(parse.startTime) && currantTime.before(parse.endTime)) {
// occupied = true;
// Floor.maxRooms ++;
}
}
}
}
}
}
}
// }
**//From tab Parse**
//StartTime
String startTime;
//EndTime
String endTime;
TableRow myTableRow;
ParseInfo(TableRow tableRow) {
parseRow(tableRow);
}
// Parse data into variables
void parseRow(TableRow row) {
// Divide the parse location to level and room
this.location = row.getString("Location");
this.level = this.location.substring(5, 6);
this.room = this.location.substring(8, 9);
// Divide the parse start date to year, month, day
this.date = row.getString("Start date");
this.day = this.date.substring(9, 10);
this.month = this.date.substring(6, 7);
this.year = this.date.substring(0, 3);
// Parse Start time & End time
this.startTime = row.getString("Start time");
this.endTime = row.getString("End time");
}
}
It looks like your dates are stored as String values. String values don't have a concept of whether they are before or after each other, so you have to do the comparison yourself. You have two options:
Option 1: Compare the String values alphabetically. Something like this:
String date1 = "2015/10/24";
String date2 = "2015/10/25";
if(date1.compareTo(date2) < 0){
//date 1 is before date2
}
else if(date1.compareTo(date2) > 0){
//date 1 is after date2
}
else{
//they are the same date
}
Option 2: If that won't work for some reason (if the dates are in different formats, for example), then you can use Java's SimpleDateFormat class to parse the date Strings into Date objects. Something like this:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
Date date1 = sdf.parse("2015/10/24");
Date date2 = sdf.parse("2015/10/25");
if(date1.before(date2)){
//date 1 is before date2
}
else if(date1.after(date2)){
//date 1 is after date2
}
else{
//they are the same date
}

How to get/compute total number of months using JDateChooser

I'm new to Java
How do I get the total number of months between two (2) jdatechooser? I've search already about this but the date was set to the code, In my case I want to put the dates via JDateChooser.
I can do this through this code but if the year change I was not able to compute the total number of months I want to do this without using JodaTime.
Here is my code
public void month(){
int TotalMonth;
Calendar toDate;
Calendar fromDate;
int increment;
Date dt1 = date1.getDate(); //datechooser 1
Date dt2 = date2.getDate(); //datechooser 2
fromDate = Calendar.getInstance();
toDate = Calendar.getInstance();
if(dt1.after(dt2))
{
fromDate.setTime(dt2);
toDate.setTime(dt1);
}
else
{
fromDate.setTime(dt1);
toDate.setTime(dt2);
}
increment = 0;
TotalMonth = toDate.get(Calendar.MONTH) - (fromDate.get(Calendar.MONTH + increment));
jLabel2.setText(Integer.toString(age));
}
JodaTime is simpler, however...
You need to loop from the start time to the end, incrementing the MONTH field on each loop while the date remains before the end time...
For example...
try {
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
Calendar cal1 = Calendar.getInstance();
cal1.setTime(sdf.parse("08/03/1972"));
Calendar cal2 = Calendar.getInstance();
cal2.setTime(sdf.parse("08/03/2014"));
// Yes, you can use cal1, but I you might want
// to preserve it for other reasons...
Calendar cal3 = Calendar.getInstance();
cal3.setTime(cal1.getTime());
int months = 0;
while (cal3.before(cal2)) {
cal3.add(Calendar.MONTH, 1);
months++;
}
System.out.println("Months = " + months);
} catch (ParseException exp) {
exp.printStackTrace();
}
Prints out Months = 505.
If you change cal2 to 08/04/1972, it will print Months = 1

find days difference between 2 dates and how many days in each month

I could use some help with this method I'm trying to make. I have a Problem Object, which has a target date and i need to find out how many days this problem is late divided/split by months, compared to today's date.
Image this situation:
Lets say that today's date is 05-02-2013.
ID Target date
P1 02-02-2013
P2 27-01-2013
P3 26-01-2013
P4 05-12-2012
This means that each problem is this many days late in the following months:
DEC JAN FEB
P1 3
P2 4 5
P3 5 5
P4 26 31 5
A problem can not be older than 12 months.
Now i need a method to sum these numbers storing the month name and a summed number of late days. If the target month and now month are the same, its an easy case, because i can just substract the days and store the month, but what to do when its not the case? I have the following code:
List<Problem> problems = problemQuery.getResultList(); //Problems list is already filtered and contain only late problems.
Calendar now = Calendar.getInstance();
Calendar before = Calendar.getInstance();
Map<Integer, Integer> newMap = new TreeMap<Integer, Integer>(); //map that contains month number and daysLateCount
for (Problem p : problems) {
before.setTime(p.getTarget_date());
int nowMonth = now.get(Calendar.MONTH);
int beforeMonth = before.get(Calendar.MONTH);
if (beforeMonth == nowMonth) { //easy case when both dates have same month
int result = now.get(Calendar.DAY_OF_MONTH) - before.get(Calendar.DAY_OF_MONTH);
if (newMap.containsKey(nowMonth)) {
int newLateDaysValue = newMap.get(nowMonth)+result; //get old result and add the new
newMap.put(nowMonth, newLateDaysValue);
}
else {
newMap.put(nowMonth, result);
}
}
else {
//What to do here???
}
}
Perhaps i could even skip the if-else clause and make an algorithm that could handle both cases? I don't know please help :)
The best way is to use Joda Time library: http://www.joda.org/joda-time/
Java Date/Time API is not very good and useful for such purposes.
I think there is a relatively simple solution to this, the algorithm is as follows:
import java.util.Calendar;
public class test {
public static void main(String[] args){
Calendar today = Calendar.getInstance();
Calendar problemDate = Calendar.getInstance();
today.set(2013, 01, 05);
problemDate.set(2012, 11, 05);
System.out.println(today.getTime());
System.out.println(problemDate.getTime());
// This might need further validation to make sure today >= problemDate
int diffYear = today.get(Calendar.YEAR) - problemDate.get(Calendar.YEAR);
int differenceInMonths = diffYear * 12 + today.get(Calendar.MONTH) - problemDate.get(Calendar.MONTH);
//int differenceInMonths = today.get(Calendar.MONTH) - problemDate.get(Calendar.MONTH);
for(int i = 0; i <= differenceInMonths; i++) {
int daysDifference;
if (differenceInMonths == 0) {
daysDifference = today.get(Calendar.DAY_OF_MONTH) - problemDate.get(Calendar.DAY_OF_MONTH);
} else {
if ( i == 0) { // first month
daysDifference = problemDate.getActualMaximum(Calendar.DAY_OF_MONTH) - problemDate.get(Calendar.DAY_OF_MONTH);
}
else if( i == differenceInMonths ) { // last month
daysDifference = today.get(Calendar.DAY_OF_MONTH);
}
else {
Calendar cal= Calendar.getInstance();
cal.set(Calendar.MONTH, problemDate.get(Calendar.MONTH) + i);
daysDifference = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
}
}
System.out.println(daysDifference);
}
}
}
Which outputs:
Tue Feb 05 14:35:43 GMT 2013
Wed Dec 05 14:35:43 GMT 2012
26
31
5
You should be able to wrap this up into your code, and in a loop fairly easily, and also remove the print statements to insert into whatever data structure you have.
A solution using Joda-Time:
LocalDate today = new LocalDate(2013, 2, 5);
LocalDate targetDate = new LocalDate(2012, 12, 5); // example with target date P4
LocalDate begin = targetDate;
LocalDate end = begin.dayOfMonth().withMaximumValue();
while (end.isBefore(today)) {
Days days = Days.daysBetween(begin, end);
if (days.getDays() > 0) {
System.out.println(end.monthOfYear().getAsText() + ": " + days.getDays());
}
begin = end;
end = begin.plusDays(1).dayOfMonth().withMaximumValue();
}
end = today;
Days days = Days.daysBetween(begin, end);
if (days.getDays() > 0) {
System.out.println(end.monthOfYear().getAsText() + ": " + days.getDays());
}
Prints the following result for e.g. target date P4:
December: 26
January: 31
February: 5
The year is needed, if only to know how many days are in February.
for (Problem p : problems) {
int nowYear = now.get(Calendar.YEAR);
int nowMonth = now.get(Calendar.MONTH);
int nowDay = now.get(Calendar.DAY_OF_MONTH);
before.setTime(p.getTarget_date());
int beforeYear = before.get(Calendar.YEAR);
int beforeMonth = before.get(Calendar.MONTH);
int beforeDay = before.get(Calendar.DAY_OF_MONTH);
while (beforeYear < nowYear || beforeMonth < nowMonth) {
int daysInMonth =
before.getActualMaximum(Calendar.DAY_OF_MONTH);
int result = daysInMonth - beforeDay;
Integer oldLateDaysValue = newMap.get(beforeMonth);
newMap.put(beforeMonth,
oldLateDaysValue == null ?
result : (oldLateDaysValue + result));
// For all subsequent months, calculate using entire month.
beforeDay = 0;
before.add(Calendar.MONTH, 1);
beforeYear = before.get(Calendar.YEAR);
beforeMonth = before.get(Calendar.MONTH);
}
int result = nowDay - beforeDay;
Integer oldLateDaysValue = newMap.get(beforeMonth);
newMap.put(beforeMonth,
oldLateDaysValue == null ?
result : (oldLateDaysValue + result));
}
System.out.println(newMap);
}

working with datetime to check which one is bigger

I have two datetime values and i dont knw how to compare them. I know if i had only date values then before() and after() methods would have worked but i have no idea about Datetime values. All i have done is below plz tell me if its correct ?? and plz do guide me if its not a good way and a better alternative is available.
Date now = new Date();
DateTime currenttime = new DateTime(now, TimeZone.getTimeZone("IST"));
DateTime edate = e.getEnd().getDateTime();
if(currenttime.getValue()>edate.getValue())
{
//here I want to do the logic to delete this event.
}
e refers to the event object that is of google calendar. All i want to do here is check if Event e is past todays date and time. and if it is then i wanna delete the event.
You can use jdk Calendar to get and check days:
public boolean isDatePass(Date date) {
Calendar calendar = Calendar.getInstance();
// Getting day of year and year of checked date:
calendar.setTime(date);
int checkedYear = calendar.get(Calendar.YEAR);
int checkedDay = calendar.get(Calendar.DAY_OF_YEAR);
// Getting day of year and year of current date:
calendar.setTime(new Date());
int currentYear = calendar.get(Calendar.YEAR);
int currentDay = calendar.get(Calendar.DAY_OF_YEAR);
if(checkedYear != currentYear) {
return checkedYear < currentYear;
}
return checkedDay < currentDay;
}
For yoda DateTime:
public boolean isDatePass(DateTime date) {
// Getting day of year and year of checked date:
int checkedYear = date.getYear();
int checkedDay = date.getDayOfYear();
// Getting day of year and year of current date:
DateTime currentTime = new DateTime(now, TimeZone.getTimeZone("IST"));
int currentYear = currentTime.getYear();
int currentDay = currentTime.getDayOfYear();
if(checkedYear != currentYear) {
return checkedYear < currentYear;
}
return checkedDay < currentDay;
}
Not days only but time:
public boolean isDatePass(DateTime date) {
DateTime currentTime = new DateTime(now, TimeZone.getTimeZone("IST"));
return date.isAfter(currentTime);
}
More simple solution (according to javadoc when pass null to isAfter/isBefore this mean current or now):
public boolean isDatePass(DateTime date) {
return date.isAfter(null); // but it does not take in account time zone
}
public String deleteEvents() throws ParseException {
try {
boolean evtDelMsg = false;
int iEvtCnt = 0;
int totalEvents = lstEvents.size();
System.out.println("events are :"+lstEvents.getItems().toString());
if(lstEvents.size()>0)
{
for(Event e : lstEvents.getItems())
{
System.out.println("startdate is "+e.getStart().toString());
Date now = new Date();
try
{
if((new Date()).getTime() < e.getEnd().getDateTime().getValue())
{
evtDelMsg = EventManager.deleteEvent(getGoogleCalObj(), selectedCalId, e.getId());
iEvtCnt++;
}
}
catch(NullPointerException npe)
{
System.out.println("edate is null so creating");
processImportedEventsData();
}
}
}
else
{
System.out.println("no events in this calendar");
}
setInfoMsg("Successfully deleted " + iEvtCnt + " Events out of total " + totalEvents);
createEventFlag = true;
processImportedEventsData();
}
catch (IOException ex)
{
Logger.getLogger(ManageCalendar.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
This one worked for me I simply used the long value of the event's i.e "e" date and time and compared with the todays date time.The getValue() method returns in long which is milliseconds. This made it a bit simple.
And then in the loop i deleted all the events calling deleteEvent() of EventManager.

How define the proper Day for Date variable

There are two times such as "startTime" = 23:57 and "endTime" = 00:50. How can I define that startTime belongs to the day that is before "endTime"?
Date min = date("23:57");
Date max = date("00:50");
private static Date date(final String time) {
final Calendar calendar = Calendar.getInstance();
String[] hm = time.split(":");
int hour = Integer.parseInt(hm[0]);
int minute = Integer.parseInt(hm[1]);
calendar.set(Calendar.HOUR,hour);
calendar.set(Calendar.MINUTE,minute);
final Date result = calendar.getTime();
return result;
}
you could append a token of some kind, like + to the end your time:
Date max = date("00:50+");
and when parsing the time:
if time.endsWith("+") {
calendar.add(Calendar.HOUR, 24);
}
if you needed to handle periods of longer than 24 hours you could use +1, +2 etc.

Categories