How to compute times for alarm clock app? - java

I have a list of alarms specified by the user like a typical alarm clock app as:
day-of-week
hour-of-day
minute-of-hour
I'm hand-writing a function to go through a list of times specified this way and determine which is the next up-coming alarm compared to current time. I'll use AlarmManager ultimately to scheduling the next upcoming alarm once I determine which alarm is next. I have considered Date, Time, and GregorianCalendar classes because they have before() and after() methods but they are all a pain to construct given my parameters. Is there a better way than writing all the date/time subtraction math myself?

You could use the Calendar class for aiding the construction of dates. Then with the getDate method you could get milliseconds and deal with them for finding the closest alarm. Check an example of usage of Calendar here http://www.tutorialspoint.com/java/util/calendar_add.htm

You can use date object.Here is video lesson I found in youtube.
create digital clock
while(time == 0){
Calendar calen = new GregorianCalendar();
int hr = calen.get(Calendar.HOUR);
int min = calen.get(Calendar.MINUTE);
int sec = calen.get(Calendar.SECOND);
int AP = calen.get(Calendar.AM_PM);
String d_n = "";
if(AP == 1){
d_n = "PM";
}else{
d_n = "AM";
}
}

Related

Add 30 minutes to the current time

I have written the code below but if the current date-time is 2022-07-03 09:48:05.448 and I add 30 minutes, my response returns 2022-07-03 09:79:05.448.
But minutes can never be 79, it is supposed to move to the hours instead...
public static String getExpiryDate(int additionalMinutesToCurrentMinute) {
LocalDateTime now = LocalDateTime.now();
int year = now.getYear();
int month = now.getMonthValue();
int day = now.getDayOfMonth();
int hour = now.getHour();
int minute = now.getMinute() + additionalMinutesToCurrentMinute;
int second = now.getSecond();
int millis = now.get(ChronoField.MILLI_OF_SECOND); // Note: no direct getter available.
String expiryDateAndTime = String.format("%d-%02d-%02d %02d:%02d:%02d.%03d", year, month, day, hour, minute, second, millis);
return expiryDateAndTime;
}
Explanation
The reason your code does not work as expected is because you are not involving javas Date/Time API at all in your "math".
Your adding the minutes with plain int-arithmetic
int minute = now.getMinute() + additionalMinutesToCurrentMinute;
and then you use plain string formatting
String.format("%d-%02d-%02d %02d:%02d:%02d.%03d", year, month, day, hour, minute, second, millis);
Nothing in this chain is "clever" and knows about date/time specifics.
Solution
You have to involve the Date/Time API for your math, then it will be clever and correctly adjust the hours as well. Fortunately, there is a method in LocalDateTime already that does what you want:
LocalDateTime expirationTime = LocalDateTime.now().plusMinutes(30);
and that is pretty much all you need.
For the formatting part, either roll with the default representation:
return expirationTime.toString();
or use a DateTimeFormatter:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy MM dd HH:mm:ss.AAA");
and then
return expirationTime.format(formatter);
Notes
Instant
You are actually using the incorrect type for an expiration time. Using LocalDateTime will result in your application failing under certain situations. For example if your computer moves across countries, or your government decides to change its timezone. Or when DST hits (summer vs winter time) or leap seconds are added and more...
The correct type would be Instant, which represents a single moment on the timeline, without interpretation of clock-time or calendar-dates.
The API is the same, so you can just use it the same way.
That said, your method should also return Instant and not a String. Keep the clever date/time type as long as possible, dont go to something as low level and raw as a string.
public static Instant getExpiryDate(int additionalMinutes) {
return Instant.now()
.plus(additionalMinutes, ChronoUnit.MINUTES);
}
Design
Design-wise it would be better if the method would not even take int additionalMinutes but also the unit. Otherwise the call-site is hard to read for users:
getExpiryDate(30) // 30 what? minutes? seconds? days?
with the unit, it would be easier to read and harder to misunderstand
getExpiryDate(30, ChronoUnit.MINUTES)
At which point one could argue that the method is kinda obsolete now.
Instead of editing the amount of minutes manually, try using the plusMinutes method on your LocalDateTime like so:
LocalDateTime now = LocalDateTime.now();
LocalDateTime then = now.plusMinutes(30);
This way, the class should increase the hour for you once it passes 60 minutes.

Formatting time in Android Application

I've created an Android grading app to use within my classes. All the database connections and grading logic has been laid out and functions precisely as it should.
However, I am having a problem incorporating the Java Calendar class. I need to be able to limit each class to submit their answers "only" during their class time. As you can see, I will need to incorporate a series of "if statements" in order to do this.
The problem is that I don't know how to get this time that I need to verify that my student's answer submissions are only handled during their class time.
This is what I've tried:
Calendar cal = Calendar.getInstance();
int hour = cal.get(Calendar.HOUR);
int minute = cal.get(Calendar.MINUTE);
As you can see, I am only able to get hours and minutes separate from each other. How do I get the real time? Just Hours and minutes not seconds.
In my code my set up should look like this:
int period = will be selected from a spinner object
if(period == 1 && (time>= 7:20 AM && time<= 9:00AM)) Then, go ahead and
submit your answers to online database.
if(period == 8 && (time>= 12:50PM && time<= 2:20PM)) Then, go ahead and
submit your answers to online database.
I don't know how to format this "time" object with the Calendar class.
Any help would be appreciated.
You can set hours and minutes to the calendar:
Calendar start = Calendar.getInstance();
start.set(Calendar.HOUR, 7);
start.set(Calendar.MINUTE, 20);
The same for the endDate:
Calendar end = Calendar.getInstance();
end.set(Calendar.HOUR, 9);
end.set(Calendar.MINUTE, 0);
To check that the current datetime is in the interval:
Calendar cal = Calendar.getInstance();//now
boolean isInInterval = cal.getTime().after(start.getTime()) && cal.getTime().before(end.getTime());

Compare database time with current time

I need to compare current time with the time that i am getting from database. I am getting time from database in Java class in java.sql.Time format (16:12:00).
I just need to display a error message if current time matches with the time present in DB.
When dealing with dates and times, you can use one of the many libraries like Joda Time, or you can simply consider a time as a given millisecond since 1/1/1970 (unix epoch), expressed as a normal long.
To convert a java.util.Date, or a java.sql.Time,Date etc.. that extends from java.util.Date, to a simple long, you can call getTime() : http://docs.oracle.com/javase/6/docs/api/java/util/Date.html#getTime()
Current time, expressed as milliseconds from unix epoch so comparable with results of getTime(), can be obtained with System.currentTimeMillis();
Once you have that, comparing it is very easy :
Time dbTime = // the time you obtained from the db
long dbLong = dbTime.getTime();
long now = System.currentTimeMillis();
if (dbLong < now) // data in the db is in the past
if (dbLong > now) // data in the db is in the future
if (dbLong == now) // data in the db is exactly now
Take care of the dbLong == now, cause it's precise to the millisecond, so it will rarely happen in practice, unless you use a range or reduce the precision, say, to the second or minute :
long dbLongSeconds = dbLong / 1000;
long dbLongMinutes = dbLong / (60*1000);
long nowSeconds = now / 1000;
long nowMinutes = now / (60*1000);
if (dbLongSeconds == nowSeconds) // data in the db is in this second
if (dbLongMinutes == nowMinutes) // data in the db is in this minute
If you need more sophisticated comparisons, like day or month, you should use either a library like Joda Time, or built in classes like Calendar, cause the math is way more complex given how western calendar divides the year.
To compare your current time with the time from the database you could simply construct a sql.Time from System.currentTimeMillis() and compare the two toString()s like so:
java.sql.Time serverTime = getServerTime();
java.sql.Time currentTime = new java.sql.Time(System.currentTimeMillis());
if(serverTime.toString().compareTo(currentTime.toString()) == 0)
{
//yay
}
else //nay
You could also compare the two sql.Time's directly using it's compareTo method, but this is trickier.
This is because even though sql.Time's setDate/Year/Month is deprecated and will throw an exception if you use them( which makes sense because they're not a date, only a time) the sql.Time's compareTo uses its superclass implementation, which means it compares not only the time but also the date, which sucks 'cus your database sql.Time object will probably always have the date 1970.01.01 whereas any sql.Time you construct off of System.currentTimeMillis() will have the current date. You can get around this by using a Calendar object as shown.
Calendar tmp = new GregorianCalendar();
tmp.setTimeInMillis(System.currentTimeMillis());
tmp.set(Calendar.YEAR, 1970);
tmp.set(Calendar.MONTH, 0); // 0 == January
tmp.set(Calendar.DATE, 1);
tmp.set(Calendar.MILLISECOND, 0);
java.sql.Time currentTime = new java.sql.Time(c.toInstant().toEpochMilli());
java.sql.Time serverTime = getServerTime();
if(currentTime.compareTo(serverTime) == 0)
{
//yay
}
else //nay
Or you could compare the long times directly as in Simone Gianni's answer, which would probably be the more efficient solution.

Test a date within a day intervall range

I have a date and a number and want to check if this date and this number occurs in a list of other dates within:
+-20 date intervall with the same number
so for example 1, 1.1.2013 and 1,3.1.2013 should reuturn false.
I tried to implement the method something like that:
private List<EventDate> dayIntervall(List<EventDate> eventList) throws Exception {
List<EventDate> resultList = new ArrayList<EventDate>();
for (int i = 0; i < eventList.size(); i++) {
String string = eventList.get(i).getDate();
Date equalDate = new SimpleDateFormat("dd.MM.yyyy", Locale.GERMAN).parse(string);
for (int j = 0; j < eventList.size(); j++) {
String string1 = eventList.get(i).getDate();
Date otherDate = new SimpleDateFormat("dd.MM.yyyy", Locale.GERMAN).parse(string1);
if (check number of i with number of j && check Date) {
//do magic
}
}
}
return resultList;
}
The construction of the iteration method is not that hard. What is hard for me is the date intervall checking part. I tried it like that:
boolean isWithinRange(Date testDate, Date days) {
return !(testDate.before(days) || testDate.after(days));
}
However that does not work because days are not takes as days. Any suggestions on how to fix that?
I really appreciate your answer!
You question is difficult to follow. But given its title, perhaps this will help…
Span Of Time In Joda-Time
The Joda-Time library provides a trio of classes to represent a span of time: Interval, Period, and Duration.
Interval
An Interval object has specific endpoints that lie on the timeline of the Universe. A handy contains method tells if a DateTime object occurs within those endpoints. The beginning endpoint in inclusive while the last endpoint is exclusive.
Time Zones
Note that time zones are important, for handling Daylight Saving Time and other anomalies, and for handling start-of-day. Keep in mind that while a java.util.Date seems like it has a time zone but does not, a DateTime truly does know its own time zone.
Sample Code
Some code off the top of my head (untested)…
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Berlin" );
DateTime dateTime = new DateTime( yourDateGoesHere, timeZone );
Interval interval = new Interval( dateTime.minusDays( 20 ), dateTime.plusDays( 20 ) );
boolean didEventOccurDuringInterval = interval.contains( someOtherDateTime );
Whole Days
If you want whole days, call the withTimeAtStartOfDay method to get first moment of the day. In this case, you probably need to add 21 rather than 20 days for the ending point. As I said above, the end point is exclusive. So if you want whole days, you need the first moment after the time period you care about. You need the moment after the stroke of midnight. If this does not make sense, see my answers to other questions here and here.
Note that Joda-Time includes some "midnight"-related methods and classes. Those are no longer recommended by the Joda team. The "withTimeAtStartOfDay" method takes their place.
DateTime start = dateTime.minusDays( 20 ).withTimeAtStartOfDay();
DateTime stop = dateTime.plusDays( 21 ).withTimeAtStartOfDay(); // 21, not 20, for whole days.
Interval interval = new Interval( start, stop );
You should avoid java.util.Date if at all possible. Using the backport of ThreeTen (the long awaited replacement date/time API coming in JDK8), you can get the number of days between two dates like so:
int daysBetween(LocalDate start, LocalDate end) {
return Math.abs(start.periodUntil(end).getDays());
}
Does that help?
You can get the number of dates in between the 2 dates and compare with your days parameter. Using Joda-Time API it is relatively an easy task: How do I calculate the difference between two dates?.
Code:
SimpleDateFormat format = new SimpleDateFormat("dd.MM.yyyy", Locale.GERMAN);
Date startDate = format.parse("1.1.2013");
Date endDate = format.parse("3.1.2013");
Days d = Days.daysBetween(new DateTime(startDate), new DateTime(endDate));
System.out.println(d.getDays());
Gives,
2
This is possible using Calendar class as well:
Calendar cal = Calendar.getInstance();
cal.setTime(startDate);
System.out.println(cal.fieldDifference(endDate, Calendar.DAY_OF_YEAR));
Gives,
2
This 2 can now be compared to your actual value (20).

How do I figure out whether the current time is in between two times? [duplicate]

This question already has answers here:
How can I determine if a date is between two dates in Java? [duplicate]
(11 answers)
Closed 9 years ago.
I'm trying to write a schedule program in Java and I need to figure out what time it is, and whether the current time is in between two set times. Figuring out the current time is pretty simple, but do you have any suggestions for figuring out whether it is between two times of day. For example, it is 9:33 AM on a Thursday. So I would need to figure out which scheduled section of the week that time corresponds to. How would I go about comparing the time to set periods during the week, for example an Array of sectioned times during a week such as {Monday from 9-10 AM, Tuesday from 3-4 PM, Thursday from 8-11 AM}, and seeing which section of time the current time falls between?
An efficient way to find which period any date lies within would be to have a class;
public class TimePeriod implements Comparable<TimePeriod>{
Date start;
Date end;
//Constructor, getters, setters
boolean isIn(Date date) {
return date.after(start) && date.before(end);
}
public int compareTo(TimePeriod other) {
return start.compareTo(other.start);
}
}
..and then create a sorted list of TimePeriod where you can perform a binary search.
edit:
This might make the binary search easier;
int check(Date date) {
if (isIn(date)) {
return 0;
} else if (start.after(date)) {
return -1;
} else if (end.before(date)) {
return 1;
} else {
throw new IllegalStateException("Time has gone badly wrong");
}
}
If you're using Date Class, you could do it like this
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy hh:mm");
Date before = sdf.parse("07/05/2012 08:00");
Date after = sdf.parse("07/05/2012 08:30");
Date toCheck = sdf.parse("07/05/2012 08:15");
//is toCheck between the two?
boolean isAvailable = (before.getTime() < toCheck.getTime()) && after.getTime() > toCheck.getTime();
EDITED
As suggested by Jonathan Drapeau you could also use compareTo.
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy hh:mm");
Date before = sdf.parse("07/05/2012 08:00");
Date after = sdf.parse("07/05/2012 08:30");
Date toCheck = sdf.parse("07/05/2012 08:15");
//is toCheck between the two?
if you want to include the "initial" and "final" date range
boolean isAvailable = before.compareTo(toCheck) >= 0 && after.compareTo(toCheck) <= 0
if you want to exclude the "initial" and "final" date range
boolean isAvailable = before.compareTo(toCheck) > 0 && after.compareTo(toCheck) < 0
You could use it too on Calendar class.
Anyway, i highly recommend you to use Calendar. It's a way precise class
you could check it like this:
Calendar cal1 = Calendar.getInstance(); // for example 12:00:00
Calendar cal2 = Calendar.getInstance(); // for exmaple 12:30:00
Calendar userTime = Calendar.getInstance(); // time to test: 12:15:00
if(user.after(cal1)&& user.before(cal2)){
//...
}
And to initialize and set times to Calendar, check this:
http://www.tutorialspoint.com/java/util/calendar_settime.htm
I would suggest using the Epoch time.
For a definition of Epoch time: http://en.wikipedia.org/wiki/Epoch_time
Basically, its a number of seconds after a specific date, i believe in 1989. If you translate the 3 times (the current time and the 2 times to compare to) in epoch time you can just use > < = etc.
For information on getting epoch time, Try here (has many languages): http://shafiqissani.wordpress.com/2010/09/30/how-to-get-the-current-epoch-time-unix-timestamp/
Unfortunately, my java is lacking or I'd give you some code :)
Edit:
Java epoch time code:
long epoch = System.currentTimeMillis()/1000;
Because my Java is bad and I don't have an interpreter where I am, I can only suggest using this site to help convert the other dates to epoch time: http://www.epochconverter.com/
There is before(Date) and after(Date) method in Date Class.
secondDate.before(firstDate)
If you use Calendar class, it has explicit before() and after() methods:
Calendar startDate = ...
Calendar endData = ...
isBetween = currentDate.after(startDate) && currentDate.before(endDate);

Categories