how to create time array - java

I have an arraylist arr which contains a series of number, like 07, 52, 25, 10, 19, 55, 15, 18, 41. In this list first item is hour, second is minute and third is second, like 07:52:25.
Now I want to create a time array in which i can insert these values and do some arithmetic operation like difference between first index and second index, which gives me the time difference. So how can i do that?
ArrayList arr = new ArrayList();
StringTokenizer st = new StringTokenizer(line, ":Mode set - Out of Service In Service");
while(st.hasMoreTokens()){
arr.add(st.nextToken());
}

Ok i think i understand what you want your code to do. Heres how i would do it.
public class DateHandler
{
public DateHandler(int seconds, int minutes, int hours)
{
this.seconds = seconds;
this.minutes = minutes;
this.hours = hours;
}
public String toString()
{
return "Seconds: "+seconds+" Minutes: "+minutes+" Hours: "+hours;
}
public int seconds;
public int minutes;
public int hours;
}
public class Main
{
public static void main(String args[])
{
int[] data = {07, 52, 25, 10, 19, 55, 15, 18, 41}
int numberOfDates = data.length/3//Divide by 3 because there are 3 numbers per date
ArrayList<DateHandler> dates = new ArrayList<DateHandler>(numberOfDates);
for(int x=0;x<numberOfDates;x++)
{
int index = x*3;
DateHandler date = new DateHandler(data[index],data[index+1],data[index+2]);
System.out.println("added date: "+date.toString());
dates.add(date);
}
//here you can do your calculations.
}
}
I hope this helped!

I would use split to tokenise. You can read any amount of times from multi-line data
BufferedReader br =
String line;
List<Integer> times = new ArrayList<Integer>();
while((line = br.readLine()) != null) {
String[] timesArr = line.split(", ?");
for(int i=0;i<timesArr.length-2;i+=3)
times.add(Integer.parseInt(times[i]) * 3600 +
Integer.parseInt(times[i+1]) * 60 +
Integer.parseInt(times[i+2]));
}
br.close();
System.out.println(times); // prints three times in seconds.
// difference between times
for(int i=0;i<times.size()-1;i++)
System.out.println("Between "+i+" and "+(i+1)+
" was "+(times.get(i+1)-times.get(i))+" seconds.");

If this array (you said "arraylist arr" right?)
07, 52, 25, 10, 19, 55, 15, 18, 41
means
7:52:25, 10:19:55 and 15:18:41
Then you can use SimpleDateformat to "convert" a string to a date.
SimpleDateFormat can parse ("convert") a String to a Date, and to format a Date to a String (actually a StringBuffer).
In your case, you loop through your ArrayList group the hours, minutes and seconds, and use SimpleDateFormat to parse them:
int index = 0;
String tempTime = "";
ArrayList<Date> dateList = new ArrayList<Date>();
//assuming hour in format 0-23, if 1-24 use k in place of h
SimpleDateFormat dateFormat = new SimpleDateFormat("h-m-s-");
for(String timeeElement : timeArrayList)
{
tempTime += timeeElement;
tempTime += "-"; //To handle situations when there is only one digit.
index++;
if(index % 3 == 0)
{
Date d = dateFormat.parse(tempTime, new ParsePosition(0));
dateList.add(d);
tempTime = "";
}
}
You have a list of dates to play with now

Related

A more elegant way to iterate through a list to compare 2 elements next to one another

I have a method which works in this way:
Take as an argument 3 params - a list with dates (sorted in ascending order) , interval unit and interval value
Check whether the next element doesn't exceed the previous date (interval). In other words, given the interval of 30 min, prev - 10:00, next 10:29 - iterate further. if next is 10:31 - break it and return the counter of dates in a row.
The code for it is below:
public static void main(String[] args)
{
Date d1 = new Date();
Date d2 = addOrSubtractTimeUnitFromDate(d1, Calendar.MINUTE, 10, true);
Date d3 = addOrSubtractTimeUnitFromDate(d2, Calendar.MINUTE, 10, true);
Date d4 = addOrSubtractTimeUnitFromDate(d3, Calendar.MINUTE, 10, true);
Date d5 = addOrSubtractTimeUnitFromDate(d4, Calendar.MINUTE, 10, true);
Date d6 = addOrSubtractTimeUnitFromDate(d5, Calendar.MINUTE, 10, true);
List<Date> threeDates = new ArrayList<>();
threeDates.add(d1);
threeDates.add(d2);
threeDates.add(d3);
threeDates.add(d4);
threeDates.add(d5);
threeDates.add(d6);
System.out.println(returnDatesInARowCounter(threeDates, Calendar.MINUTE, 30));
}
private static int returnDatesInARowCounter(List<Date> allDates, int intervalBetween2DatesTimeUnit, int intervalValue)
{
int datesInARowCounter = allDates.size() > 0 ? 1 : 0; // esp. this line (in case allDates is empty)
Date lastDate = null;
Date nextDate;
Iterator<Date> iter = allDates.iterator();
while (iter.hasNext())
{
nextDate = iter.next();
if (lastDate != null) // both lastDate и nextDate are initialized now
{
if(isNextIncidentInIntervalWithLastOneOrNot(lastDate, nextDate, intervalBetween2DatesTimeUnit, intervalValue, true))
{
datesInARowCounter += 1;
}
else break;
}
lastDate = nextDate;
}
return datesInARowCounter;
}
public static Date addOrSubtractTimeUnitFromDate(Date dateToAddToOrSubtractFrom, int calendarTimeUnit, int value, boolean isAdd)
{
if(!isAdd)
{
value = -value;
}
Calendar cal = Calendar.getInstance();
cal.setTime(dateToAddToOrSubtractFrom);
cal.add(calendarTimeUnit, value);
return cal.getTime();
}
private static boolean isNextIncidentInIntervalWithLastOneOrNot(Date lastIncidentRegDate, Date nextIncidentRegDate, int intervalTimeUnit, int intervalValue, boolean isBetween)
{
Date currentIncidentPlusInterval = addOrSubtractTimeUnitFromDate(lastIncidentRegDate, intervalTimeUnit, intervalValue, true);
boolean betweenBool = isDateBetween(nextIncidentRegDate, lastIncidentRegDate, currentIncidentPlusInterval);
return isBetween == betweenBool;
}
private static boolean isDateBetween(Date targetDate, Date startDate, Date endDate)
{
return targetDate.compareTo(startDate) >= 0 && targetDate.compareTo(endDate) <= 0;
}
However, the code looks peculiar to me. Is the any way to make it look more readable?
If you are using Java 8 or newer, you can use the java.time-API instead. It's built-in support for "periods of time" makes the actual implementation much simpler.
static int daysInARow(List<Instant> allInstants, Duration maxDifference) {
int counter = allInstants.size() > 0 ? 1 : 0;
Instant previous = allInstants.get(0);
for (int i = 1; i < allInstants.size(); i++) {
Instant current = allInstants.get(i);
if (Duration.between(previous, current).compareTo(maxDifference) > 0)
break;
counter++;
previous = current;
}
return counter;
}
If you're using java.util.Date in other parts of your project, you can easily convert between Instants by using
Date#from(Instant)
and
Date#toInstant()

(Java) An Array of a class

I have a class here which gives me back a date in a certain order
what i want to do is make an array of this class with four type of Dates.
May 16, 1984
November 14, 1978
September 21, 1980
July 3, 1987
How can I fit these dates in the Array ????
public class DateArray {
private String month;
private int day;
private int year;
public DateArray(String n, int d, int y){
month = n;
day = d;
year = y;
}
public String toString(){
return month + "/" + day + "/" + year;
}
This is what my Main looks like right now:
DateArray date = new DateArray("jan", 5, 20);
String s = date.toString();
System.out.println(s);
DateArray [] dates = new DateArray[3];
for(int i =0; i<dates.length; i++)
{
System.out.println(dates[i]);
}
You haven't set any values for the array elements in your code example. You need something similar to
dates[0] = new DateArray(month, day, year);
for each element. Also, I suggest that naming a type 'Array' that isn't an array might be confusing.
First, based on your expected results, your DateArray.toString() should look something like1
#Override
public String toString() {
return month + " " + day + ", " + year;
}
Then you can create and display your array with something like
public static void main(String[] args) {
DateArray[] dates = new DateArray[] { new DateArray("May", 16, 1984),
new DateArray("November", 14, 1978),
new DateArray("September", 21, 1980), new DateArray("July", 3, 1987) };
for (DateArray da : dates) {
System.out.println(da);
}
}
And I get (as requested)
May 16, 1984
November 14, 1978
September 21, 1980
July 3, 1987
1The Override annotation can help you if you think you're correctly overriding a super-type method but you aren't. I suggest you always use it.

Java - Comparing Strings which are numbers

How to compare String which are numbers?
I have Strings saved in file:
"2000 12 7 0 2 -3.0"
"2000 7 7 0 2 -4.0"
"2013 7 23 20 59 25.5"
First five values are date (year, month, day, hour, minute). I need to sort them chronologically.
Here is my code:
class Task3 {
BufferedWriter writer;
BufferedReader reader;
int licznik = 0;
Task3() throws IOException {
this.writer = new BufferedWriter(new FileWriter("c:\\zadanie.txt"));
this.reader = new BufferedReader(new FileReader("c:\\zadanie.txt"));
}
public void WriteMeasur(Measur measur) throws IOException{
//licznik++;
writer.write(measur.toString());
writer.newLine();
}
public void WriteChrono(Measur measur) throws IOException{
List<String> lista = new ArrayList<>();
String line;
while((line = reader.readLine()) != null){
lista.add(line);
}
}
}
class Time implements Serializable{
int year, month, day, hour, minute;
Time(int r, int m, int d, int h, int min){
if(r <= 2014 && r > 1990)
this.year = r;
if(m <= 12)
this.month = m;
if(d <= 30 || (m == 2 && d < 29))
this.day = d;
if(h <= 24)
this.hour = h;
if(min <= 60)
this.minute = min;
}
#Override
public String toString(){
return String.valueOf(year) + " " + String.valueOf(month) + " " +String.valueOf(day) + " " +String.valueOf(hour) + " " +String.valueOf(minute);
}
}
class Measur implements Serializable{
Time time;
double temp;
Measur(Time czas, double temp){
this.time = czas;
this.temp = temp;
}
#Override
public String toString(){
return time.toString() + " " +String.valueOf(temp);
}
}
public class Main{
public static void main(String args[]) throws IOException{
//Argumenty klasy czas: rok, miesiac, dzien, godzina, minuty
// Metody inicjujace klase czas
Time czas_1 = new Time(2013,7,23,20,59);
Time czas_3 = new Time(2000,07,7,25,2);
Time czas_2 = new Time(2000,12,7,25,2);
// Metody inicjujace klase pomiar
Measur pomiar_1 = new Measur(czas_1, 25.5);
Measur pomiar_2 = new Measur(czas_2, -3);
Measur pomiar_3 = new Measur(czas_3, -4);
Task3 zad3 = new Task3();
zad3.WriteMeasur(pomiar_1);
zad3.WriteMeasur(pomiar_2);
zad3.WriteMeasur(pomiar_3);
zad3.writer.close();
}
}
I have no idea how to sort it. I wanted use Collections.sort(), but in Strings 2000 12 is smaller then 2000 7.
Any advice?
Thanks!
I'm not sure this is a good idea or not. But you could use Collections.sort support of Comparator to customise the way in which values are compared while they are been sorted and SimpleDateFormat to convert the value to a Date value which can then be compared directly...for example...
List<String> values = new ArrayList<String>(25);
values.add("2013 7 23 20 59 25.5");
values.add("2000 12 7 0 2 -3.0");
values.add("2000 7 7 0 2 -4.0");
Collections.sort(values, new Comparator<String>() {
private SimpleDateFormat sdf = new SimpleDateFormat("yyyy MM dd");
#Override
public int compare(String o1, String o2) {
int result = -1;
try {
Date d1 = sdf.parse(o1);
Date d2 = sdf.parse(o2);
result = d1.compareTo(d2);
} catch (ParseException exp) {
exp.printStackTrace();
}
return result;
}
});
for (String value : values) {
System.out.println(value);
}
Create yourself a personal MyDate Object that is passed a String in its constructor and parses that string to initialize your year, month, day, hour, min, sec fields.
Then write a custom Comparator for your class MyDateComparator and code your logic for sorting.
Store your MyDate objects not String in your List and use `Collections.sort(myDateList, new MyDateComparator())
See The Ordering Collections Java Tutorials for tips on how to use Comparators
Split the string with space as delimiter, convert into integer array and then sort?

Stuck in a while loop; calc days between two dates

I've actually been browsing for quite a while on this site, sadly without much progress. Thanks to a lot of extremely useful answers, I've learned quite a bunch of stuff though!
I'm learning Java since ... about 4 days (I guess?) so I'm not very experienced in the methods I can use.
There's this assignment we got at our univ. We shall write a program that returns how many days have passed between two dates. The only restriction is to keep the program as simple as possible, we're not allowed to use "complicated methods".
Sadly, my program is kind of stuck. If I try it out e.g. the dates 23 01 1994 and 07 04 1997, it counts only up to 01 01 1997 and suddenly stops. I have no idea why that happens, I even doubt if I fully understood what I wrote there.
Anyways, here's my code:
import java.util.Arrays;
import java.util.Scanner;
public class Datecalc {
public static int yearcounter,monthcounter,daycounter,days;
public static int[] input() {
Scanner input = new Scanner(System.in);
//Eingabe der Daten
String day1 = input.next();
String month1 = input.next();
String year1 = input.next();
String day2 = input.next();
String month2 = input.next();
String year2 = input.next();
int day1int = Integer.parseInt(day1);
int month1int = Integer.parseInt(month1);
int year1int = Integer.parseInt(year1);
int day2int = Integer.parseInt(day2);
int month2int = Integer.parseInt(month2);
int year2int = Integer.parseInt(year2);
int [] eingabe = new int [6];
eingabe[0] = day1int;
eingabe[1] = month1int;
eingabe[2] = year1int;
eingabe[3] = day2int;
eingabe[4] = month2int;
eingabe[5] = year2int;
return eingabe;
// put everything into an array to be able to use it in the main method
}
public static void main(String[] args) {
int[] eingabe = input();
days=0;
daycounter = eingabe[0];
monthcounter = eingabe[1];
yearcounter = eingabe[2];
Integer[] einunddreissig = {1,3,5,7,8,10,12}; //months with 31 days
Integer[] dreissig = {4,6,9,11}; // months with 30 days
while (daycounter != eingabe[3] && monthcounter != eingabe[4] && yearcounter != eingabe[5] ) {
// if its a month that has 31 days
if ( Arrays.asList(einunddreissig).contains(monthcounter) ) {
for (int i = daycounter; i <= 31; i++) {
days++;
}
daycounter=1;
monthcounter++;
}
// if its a month with 30 days
if ( Arrays.asList(dreissig).contains(monthcounter) ) {
for (int i = daycounter; i <= 30; i++) {
days++;
daycounter++;
}
daycounter=1;
monthcounter++;
// february
} else if ( monthcounter == 2) {
for (int i = daycounter; i <= 28; i++) {
days++;
}
daycounter=1;
monthcounter++;
} else if (monthcounter==13) {
monthcounter=1;
yearcounter++;
}
}
// checking how many days were counted and comparing the input (eingabe[something]) to how far the daycounter reached
System.out.println(" "+days);
System.out.println(" "+daycounter+" "+monthcounter+" "+yearcounter);
System.out.println(eingabe[3]+" "+eingabe[4]+" "+eingabe[5]);
}
}
I hope there is somebody who might be so kind to give me a hint how to fix that.
I would separate this out into two different functions, one that counts the days until the end of the current year and another which counts the days since the beginning of the current year. Then you can put the total days in terms of those values.
First write a generic sum() function:
public static int sum(int[] a, int start, int end){
int sum = 0;
for(int i = start; i < end; i++) sum += a[i];
return sum;
}
Then use the sum() function to easily compute daysToEnd and daysFromStart:
static int[] daysInMonth = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
public static int daysToEnd(int day, int month){
return sum(daysInMonth, month - 1, 12) - day;
}
public static int daysFromStart(int day, int month){
return sum(daysInMonth, 0, month - 1) + day;
}
public static void main(String... args){
int[] date1 = {23, 1, 1994};
int[] date2 = {1, 1, 1997};
// This actually works for same or different years
int days = daysToEnd(date1[0], date1[1]) +
365*(date2[2] - date1[2] - 1) +
daysFromStart(date2[0], date2[1]);
System.out.println(days);
}
Do you have to use loops? Here's some food for thought -- imagine this as a simple algebra problem. In your program, each date is modeled as a collection of quantities, each of a different unit. Once you obtain uniform units, you can just do the arithmetic.
In the UNIX world we use an agreed-upon reference date called the "epoch", 12:00 AM on 01 January, 1970 as a reference date. Kind of like "tare" on a balance. All other dates can be represented as some number of seconds relative to that time.
I would construct the passed in user input to java.util.Date type. But I am assuming line by line input. You can construct a string using StringBuilder if you want to get day,mth,year separately.
try{
BufferedReader br = new BufferedReader(
new InputStreamReader(System.in));
DateFormat df = new SimpleDateFormat ("dd/MM/yyyy");
System.out.println("Enter Date1");
String dateSt1= br.readLine(); // Accepts date1 as string
System.out.println("Enter Date2");
String dateSt2= br.readLine(); // Accepts date2 as string
Date date1=df.parse(dateSt1); // Date String to Date
Date date2=df.parse(dateSt2);
}catch(IOException ex)
}catch(ParseExceptionOfSomesort pex)
}
then use this to get the difference in days -
int diffInDays = (int)( (date2.getTime() - date1.getTime())
/ (1000 * 60 * 60 * 24) )
If you get this in negative, that means the second date is before first date.
Think: Do I have to do it using a loop or hasn't java already added some utility method to do date compare?
What makes something "complicated" though? Writing too many lines of code or using existing java library?

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);
}

Categories