Coder ACJHP Coder ACJHP - 1 month ago 16
Java Question

How to stop date changing at 00:00 o'clock?

I'm working on Hotel management application [desktop] and I noticed, the date changing time hotels system is not 00:00 am , it's between 1AM and 6AM so reservations and room status etc. should be stay until audit time.When the user make audit the new day will start.

That's why I need to create a method that stop date change at midnight and return new date when audit button clicked. Briefly I have to create central system for date.

As a result; when I use this date in all classes every methods will work synchronously[blockade, reservations, check in, check out etc.] but I couldn't find good way to do this.

I'm thinking around some code like this :

package com.coder.hms.utils;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;


public class CustomDateFactory {

private Date date;
private Calendar calendar;
private SimpleDateFormat sdf;

public CustomDateFactory() {

//for formatting date as desired
sdf = new SimpleDateFormat("yyyy-MM-dd");
}

public void setValidDateUntilAudit(int counter) {

final Timer timer = new Timer();
final TimerTask task = new TimerTask() {

@Override
public void run() {
//get hour and minute from calendar
calendar = Calendar.getInstance();
int hour = calendar.get(Calendar.HOUR);
int min = calendar.get(Calendar.MINUTE);
int sec = calendar.get(Calendar.SECOND);

//check if the field value equals -1
if (counter == -1) {
//and the time at 00:00
if (hour == 0 && min == 0 && sec == 2) {
//bring the date one day back
calendar.add(Calendar.DATE, counter);
date = calendar.getTime();
}
} else {
date = new Date();
}

}
};
timer.schedule(task, 0, 100);
}

public Date getDate() {
final String today = sdf.format(date);
final LocalDate ld = LocalDate.parse(today);
date = java.sql.Date.valueOf(ld);
return date;
}
}


After comments and helps I changed my code like this :

public class DateFactoryTest {

private LocalDate currentDate;
private LocalDateTime localDateTime;

public DateFactoryTest() {
currentDate = LocalDate.now();
localDateTime = LocalDateTime.now();
}

private void setTheDate(boolean isAuditted) {

if (localDateTime.getHour() <= 6 && isAuditted == false) {

currentDate.minusDays(1);

} else if (localDateTime.getHour() > 6 && isAuditted == true) {

ImageIcon icon = new ImageIcon(getClass().getResource("/com/coder/hms/icons/dialogPane_question.png"));

int choosedVal = JOptionPane.showOptionDialog(null, "You're doing early audit, are you sure about this?",
"Approving question", 0, JOptionPane.YES_NO_OPTION, icon, null, null);

if (choosedVal == JOptionPane.YES_OPTION) {
isAuditted = false;
}

}

}

private LocalDate getDate() {
return currentDate;
}

}


All answers, different ideas acceptable.

Answer Source

Avoid the troublesome old date-time classes such as java.util.Date. Now supplanted by the java.time classes. Among those obsolete classes is java.sql.Date – you may have to use it if your JDBC driver is not yet updated for JDBC 4.2 and later, but if so, minimize its use and do not use these objects in your business logic.

As other people commented, do not hack the meaning of a date. If a “Hotel Day” really runs from 6 AM to 6 AM, then create a class to represent that. Define a member for the official date, of type LocalDate. Define also members for the start and stop, of type LocalDateTime, where the stop is plusDays( 1 ).

Define a pair of getter methods each taking a ZoneId argument, and returning a ZonedDateTime, each for the true exact moment when the hotel-day starts and stops. A LocalDateTime is not an actual moment, and has no meaning until you specify a time zone. Anomalies such as Daylight Saving Time (DST) mean the 6 AM start or stop time might really be 5 AM or 7 AM or 6:15 AM on a particular date.

public startAtZone( ZoneId z ) {
    ZonedDateTime zdt = this.startLocalDateTime.atZone( z ) ;
    return zdt ; 
}

Calculate the span of time as a Duration. Call the to… methods to get a total number of seconds, milliseconds, or nanoseconds.

Duration d = Duration.between( ZonedDateTime.now( z ) , myHotelDay.stopAtZone( z ) ) ;

Note that the best approach to defining spans of time is generally the Half-Open approach where the beginning is inclusive and the ending is exclusive. This means your hotel-day starting at 6 AM runs up to, but does not include, the following 6 AM. That means 6 AM to 6 AM, so no bothering to determine 05:59:59.999 or 05:59:59.999999 or 05:59:59.999999999. Search with >= && < logic, and do not use SQL BETWEEN.

By the way, Timer is legacy now. Read about the Executors framework, and search Stack Overflow.

By the way, the format you used, yyyy-MM-dd, is defined by the ISO 8601 standard. The java.time classes use those standard formats by default when parsing/generating strings.