Java Calendar prints only zero - java

public class JavaCalender {
int hour, minute, second;
public void setCurrent() {
Calendar calendar = new GregorianCalendar();
this.hour = calendar.get(Calendar.HOUR_OF_DAY);
this.minute = calendar.get(Calendar.MINUTE);
this.second = calendar.get(Calendar.SECOND);
}
public int getHour() {
return hour;
}
public int getMinute() {
return minute;
}
public int getSecond() {
return minute;
}
}
class TestJavaCalender {
public static void main(String[] args) {
JavaCalender test = new JavaCalender();
System.out.print(test.getHour() + "\n" + test.getMinute() + "\n" + test.getSecond());
}
}
When I try to run this segment of codes, I could very disappointed, because the result does not equal my expectation. Why the result is all 0, could someone give me an incisive answer and how to use Calendar correctly?

Call the setCurrent(). Its unused for now.
JavaCalender test = new JavaCalender();
test.setCurrent();
System.out.print...
before you print. That's where the values would be set from as per your code.
Edit : Bringing up as mentioned in the comments by #Vikas
Adding to the part Why the result is all 0. Because the default value for primitive ints in Java is 0 and as this answer points test.setCurrent() is never called, so that default value never gets updated.

From your test flow in TestJavaCalender class, you can change your "setCurrent()" method into constructor of JavaCalender class.
orignial:
public void setCurrent() {
Calendar calendar = new GregorianCalendar();
this.hour = calendar.get(Calendar.HOUR_OF_DAY);
this.minute = calendar.get(Calendar.MINUTE);
this.second = calendar.get(Calendar.SECOND);
}
after:
public JavaCalender() {
Calendar calendar = new GregorianCalendar();
this.hour = calendar.get(Calendar.HOUR_OF_DAY);
this.minute = calendar.get(Calendar.MINUTE);
this.second = calendar.get(Calendar.SECOND);
}
Then, you can use JavaCalender smoothly.

Related

Set date in DatePickerDialog from String

How can I set date in a DatePicker from a string (eg: 02/10/19):
Following is the code:
iqp_editDate.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
new DatePickerDialog(ActivityClass.this, (DatePickerDialog.OnDateSetListener) date1, y, m, d).show();
}
});
DatePickerDialog.OnDateSetListener date1 = new DatePickerDialog.OnDateSetListener() {
#Override
public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
y = year;
m = month;
d = dayOfMonth;
dateMonth = month + 1;
dateYear = year;
}
};
Update: misunderstood the question:
Calendar cal = Calendar.getInstance()
cal.set(Calendar.HOUR_OF_DAY,18);
cal.set(Calendar.MINUTE,0);
cal.set(Calendar.DATE,2);
cal.set(Calendar.MONTH,9); //Month -1
//Or to set it from a String:
String string = "02/10/19";
DateFormat format = new SimpleDateFormat("dd/MM/yy", Locale.getDefault());
Date date = format.parse(string);
cal.setTimeInMillis(date.getTime());
new DatePickerDialog(getContext(),date1, cal
.get(Calendar.YEAR), cal .get(Calendar.MONTH),
cal .get(Calendar.DAY_OF_MONTH)).show();
A string is a character array. Meaning that you could just make a loop and set the different day, month and year values to different parts of the string.
String date = "02/19/19";
String year = "";
for(int i = 0; i < date.length; i++)
{
month += date.charAt(i);
...
}
Then you'd tell it when to switch from adding to month to day to year when it encounters '/'
if(date.charAt(i) == '/')
{
...
}
at the end of it all if you need to make it into an int then do
int month = Integer.parseInt("month");
sorry I've gotta be going somewhere so I couldn't just write the code out for ya but I'm sure you can figure it out from what I gave ya.
Following code works fine for me:
new DatePickerDialog(Activityclass.this, date1, cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH)).show();
DatePickerDialog.OnDateSetListener date1 = new DatePickerDialog.OnDateSetListener() {
#Override
public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
view.setMinDate(1559327400);
y = year;
m = month;
d = dayOfMonth;
dateMonth = month + 1;
dateYear = year;
iqp_editDate.setText(dayOfMonth + "/" + (month + 1) + "/" + year);
try {
epoch = new java.text.SimpleDateFormat("MM/dd/yyyy").parse(m + "/" + dayOfMonth + "/" + year).getTime() / 1000;
} catch (ParseException e) {
e.printStackTrace();
}
}
};

Displaying time elapsed since epoch

I am working on creating a time app that calculates both the current time and the time elapsed since midnight, January 1, 1970, in milliseconds. I went ahead and used Calendar and was able to successfully return the current time but for some reason the elapsed time returns 0. Not sure why that would be.
Here is my current code:
import java.util.Calendar;
import java.util.TimeZone;
public class TimeApp {
public static void main(String[] args) {
Time time1 = new Time();
System.out.println("Hour: " + time1.getHour() + " Minute: " +
time1.getMinute() + " Second: " + time1.getSecond());
Time time2 = new Time();
System.out.println("Elapsed time since epoch: " + time2.getElapsedTime());
}
}
final class Time {
private int hour;
private int minute;
private int second;
private long secondsSinceEpoch;
public Time() {
Calendar calendar = Calendar.getInstance();
this.second = calendar.get(Calendar.SECOND);
this.minute = calendar.get(Calendar.MINUTE);
this.hour = calendar.get(Calendar.HOUR_OF_DAY);
}
public Time(long elapsedTime) {
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
calendar.clear();
calendar.set(2016, Calendar.SEPTEMBER, 9);
secondsSinceEpoch = calendar.getTimeInMillis() / 1000L;
}
#Override
public String toString() {
return hour + ":" + minute + ":" + second;
}
public int getHour() {
return hour;
}
public int getMinute() {
return minute;
}
public int getSecond() {
return second;
}
public long getElapsedTime() {
return secondsSinceEpoch;
}
}
You aren't setting elapsedTime for time2. I think you wanted
Time time2 = new Time(System.currentTimeMillis());
And as pointed out in the comments, you aren't using elapsedTime in your constructor. Something like
public Time(long elapsedTime) {
secondsSinceEpoch = elapsedTime / 1000;
}
I think you are using the wrong constructor for time2 since you called Time() and this version does not set secondsSinceEpoch. Try using your other constructor Time(long elapsedTime) with any long value and see if it works.
Like this ..
Time time2 = new Time(10000);
Then re-write this constructor since you never use elapsedTime anyway, or delete it completely and re-write the first constructor to assign a value to secondsSinceEpoch.
public Time() {
Calendar calendar = Calendar.getInstance();
this.second = calendar.get(Calendar.SECOND);
this.minute = calendar.get(Calendar.MINUTE);
this.hour = calendar.get(Calendar.HOUR_OF_DAY);
secondsSinceEpoch = calendar.getTimeInMillis() / 1000L;
}

JSpinner time constraint

I am trying to create a spinner that has hours and minutes. The minutes part needs to increment by 10 mins only and the time must range from the current time to an end time. I also need the minimum value (previously current time) to update to current time.
I tried playing around with it, but I just couldn't get it to work.
JSpinner spinner1 = new javax.swing.JSpinner();
SpinnerDateModel spinnermodel = new SpinnerDateModel();
spinnermodel.setCalendarField(Calendar.MINUTE);
spinner1.setModel(spinnermodel);
spinner1.setEditor(new JSpinner.DateEditor(spinner1, "hh:mm"));
SpinnerModel model = new SpinnerDateModel(currentDate, currentDate, latestDate, Calendar.MINUTE * 10 ?);
The SpinnerDateModel just uses 1 to increment the field you want to change.
I extended the SpinnerDateModel to add an addition property to the model to control the increment value instead of hard coding to 1:
import java.util.*;
import javax.swing.*;
public class MySpinnerDateModel extends SpinnerDateModel
{
private int increment = 1;
public MySpinnerDateModel(Date value, Comparable start, Comparable end, int calendarField)
{
super(value, start, end, calendarField);
}
public MySpinnerDateModel()
{
this(new Date(), null, null, Calendar.DAY_OF_MONTH);
}
public void setIncrement(int increment)
{
this.increment = increment;
}
public int getIncrement()
{
return increment;
}
#Override
public Object getNextValue()
{
Calendar cal = Calendar.getInstance();
Date value = (Date)getValue();
cal.setTime(value);
cal.add(getCalendarField(), increment);
Date next = cal.getTime();
Comparable end = getEnd();
return ((end == null) || (end.compareTo(next) >= 0)) ? next : null;
}
#Override
public Object getPreviousValue()
{
Calendar cal = Calendar.getInstance();
Date value = (Date)getValue();
cal.setTime(value);
cal.add(getCalendarField(), -increment);
Date prev = cal.getTime();
Comparable start = getStart();
return ((start == null) || (start.compareTo(prev) <= 0)) ? prev : null;
}
}
You should be able to use the model the way you did before but with one additional statement:
MySpinnerDateModel model = new MySpinnerDateModel(currentDate, currentDate, latestDate, Calendar.MINUTE);
model.setIncrement( 10 );
You can extend the SpinnerDateModel to specify the behavior. Below is an example in which the getNextValue and getPreviousValue are overridden to return values +/- 10 minutes:
Date now = new Date();
Date start = now;
final long tenMinutesInMillis = 1000 * 60 * 10;
Date end = new Date(now.getTime() + tenMinutesInMillis * 60);
SpinnerModel model = new SpinnerDateModel(now, start, end, Calendar.MINUTE){
#Override
public Object getNextValue(){
Date newDate = new Date(getDate().getTime() + tenMinutesInMillis);
Date endDate = (Date)getEnd();
return newDate.getTime() > endDate.getTime() ? endDate : newDate;
}
#Override
public Object getPreviousValue(){
Date newDate = new Date(getDate().getTime() - tenMinutesInMillis);
Date startDate = (Date)getStart();
return newDate.getTime() < startDate.getTime() ? startDate : newDate;
}
};

How does cal.setTime (new Date()); work?

I want to use the cal.setTime (new Date()); in my code to update the time, but it dosent work.
import javax.swing.JOptionPane;
public class Exercise2b {
public void demo() {
String message1, message2;
int hour, minute, second;
Time dt = new Time();
hour = dt.getHour();
minute = dt.getMinute();
second = dt.getSecond();
message1 = "The clock is " + minute + " minutes over " + hour + " (+"
+ second + " seconds)";
message2 = dt.toString();
JOptionPane.showMessageDialog(null, message1);
JOptionPane.showMessageDialog(null, message2);
dt.update();
message2 = dt.toString();
JOptionPane.showMessageDialog(null, message2);
}
public static void main(String[] args) {
Exercise2b prog = new Exercise2b();
prog.demo();
}
}
import java.util.Calendar;
import java.util.Date;
public class Time {
private Calendar cal;
private int hour;
private int minute;
private int second;
public Time() {
cal = Calendar.getInstance();
this.hour = cal.get(Calendar.HOUR_OF_DAY);
this.minute = cal.get(Calendar.MINUTE);
this.second = cal.get(Calendar.SECOND);
}
public int getHour() {
return this.hour;
}
public int getMinute() {
return this.minute;
}
public int getSecond() {
return this.second;
}
public String toString() {
return hour + ":" + minute + ":" + second;
}
public void update() {
cal.setTime (new Date());
}
}
I suspect the issue is that you set the cal variable but not the hour/minute/seconds variables that are set from the initial value of `cal in the constructor.
This is an example of DRY (don't repeat yourself). In this situation it's easy to get in an inconsistent state. I would simply have your accessor methods query the cal object directly (instead of using the intermediary variables). And perhaps investigate the Joda library for a better / more reliable date/time API.
The problem is that when you call the update() method you are not refreshing the values of the local variables (second/ minute / hour). Those are already initialized from the constructor.
How does cal.setTime (new Date()); work?
The javadoc states
Sets this Calendar's time with the given Date.
new Date() creates a new Date object with the millisecond value of System.currentTimeMillis().
So
cal.setTime (new Date());
will replace the internal millisecond value of cal to that of the new Date object.

Generics and Performance question

I was wondering if anyone could look over a class I wrote, I am receiving generic warnings in Eclipse and I am just wondering if it could be cleaned up at all. All of the warnings I received are surrounded in ** in my code below.
The class takes a list of strings in the form of (hh:mm AM/PM) and converts them into HourMinute objects in order to find the first time in the list that comes after the current time.
I am also curious about if there are more efficient ways to do this. This works fine but the student in me just wants to find out how I could do this better.
public class FindTime {
private String[] hourMinuteStringArray;
public FindTime(String[] hourMinuteStringArray){
this.hourMinuteStringArray = hourMinuteStringArray;
}
public int findTime(){
HourMinuteList hourMinuteList = convertHMStringArrayToHMArray(hourMinuteStringArray);
Calendar calendar = new GregorianCalendar();
int hour = calendar.get(Calendar.HOUR_OF_DAY);
int minute = calendar.get(Calendar.MINUTE);
HourMinute now = new HourMinute(hour,minute);
int nearestTimeIndex = findNearestTimeIndex(hourMinuteList, now);
return nearestTimeIndex;
}
private int findNearestTimeIndex(HourMinuteList hourMinuteList, HourMinute now){
HourMinute current;
int position = 0;
Iterator<HourMinute> iterator = **hourMinuteList.iterator()**;
while(iterator.hasNext()){
current = (HourMinute) iterator.next();
if(now.compareTo(current) == -1){
return position;
}
position++;
}
return position;
}
private static HourMinuteList convertHMStringArrayToHMArray(String[] times){
FindTime s = new FindTime(new String[1]);
HourMinuteList list = s.new HourMinuteList();
String[] splitTime = new String[3];
for(String time : times ){
String[] tempFirst = time.split(":");
String[] tempSecond = tempFirst[1].split(" ");
splitTime[0] = tempFirst[0];
splitTime[1] = tempSecond[0];
splitTime[2] = tempSecond[1];
int hour = Integer.parseInt(splitTime[0]);
int minute = Integer.parseInt(splitTime[1]);
HourMinute hm;
if(splitTime[2] == "AM"){
hm = s.new HourMinute(hour,minute);
}
else if((splitTime[2].equals("PM")) && (hour < 12)){
hm = s.new HourMinute(hour + 12,minute);
}
else{
hm = s.new HourMinute(hour,minute);
}
**list.add(hm);**
}
return list;
}
class **HourMinuteList** extends **ArrayList** implements RandomAccess{
}
class HourMinute implements **Comparable** {
int hour;
int minute;
public HourMinute(int hour, int minute) {
setHour(hour);
setMinute(minute);
}
int getMinute() {
return this.minute;
}
String getMinuteString(){
if(this.minute < 10){
return "0" + this.minute;
}else{
return "" + this.minute;
}
}
int getHour() {
return this.hour;
}
void setHour(int hour) {
this.hour = hour;
}
void setMinute(int minute) {
this.minute = minute;
}
#Override
public int compareTo(Object aThat) {
if (aThat instanceof HourMinute) {
HourMinute that = (HourMinute) aThat;
if (this.getHour() == that.getHour()) {
if (this.getMinute() > that.getMinute()) {
return 1;
} else if (this.getMinute() < that.getMinute()) {
return -1;
} else {
return 0;
}
} else if (this.getHour() > that.getHour()) {
return 1;
} else if (this.getHour() < that.getHour()) {
return -1;
} else {
return 0;
}
}
return 0;
}
}
If you have any questions let me know.
Thanks,
Rob
It's because you a not specify generics for your List and Comparable instances, that can support generics. You can rewrite your code with:
class HourMinuteList extends ArrayList<HourMinute> implements RandomAccess{
}
class HourMinute implements Comparable<HourMinute> {
public int compareTo(HourMinute aThat) {
....
}
}
Note: generics is not required, and not used at runtime, but it's better to use them because it helps you to avoid some bugs at your code.
I wouldn't use the HourMinute class, unless it has some other added value. If you only need to find the closest event time after a given point in time, convert your strings to Date (or to long values representing time), and store them in some sorted collection.
The conversion can be done with SimpleDateFormat.
If items are added dynamically, use TreeSet<Date>, together with ceiling(t) / higher(t) methods.
If the set of items is not dynamic, use an array Date[], together with Arrays.binarySearch(..).
Here is a (working) draft of the first approach:
public class TimedEventsMgr {
private TreeSet<Date> pointsInTime = new TreeSet<Date>();
private SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd hh:mm a");
//timeStr: hh:mm AM/PM
public void add(String timeStr) throws ParseException{
Date time = sdf.parse("20000101 "+timeStr);
pointsInTime.add(time);
}
public Date closestFutureTime(Date time){
Calendar c = Calendar.getInstance();
c.setTime(time);
c.set(Calendar.YEAR, 2000);
c.set(Calendar.MONTH, 0); //January
c.set(Calendar.DATE, 1);
return pointsInTime.higher(c.getTime());
}
}

Categories