How to separate the elements of an iterator? - java

I want to randomly generate times and numbers.. Here I used hashmap generate some records. Now I can generate the numbers but I cant separate them. I have to separate the values so that I can set those in database..
Here is my code...
public class DateTimePopulation {
private Random rand = new Random();
private Date theDay;
private String callDuration = null;
private String endDay = null;
SimpleDateFormat mytimeFormat = new SimpleDateFormat("HH:mm:ss");
public static void main(String[] args) throws ParseException {
DateTimePopulation d = new DateTimePopulation();
for (int i = 1; i <= 3; i++) {
Map rec = d.getRecord();
for (int j = 0; j < rec.size(); j++) {
Collection c = rec.values();
Iterator itr = c.iterator();
int count=0;
while (itr.hasNext()) {
Object element=itr.next();
System.out.println(element);
}
System.out.println();
}
}
}
private Map getRecord() {
Map<String, Object> rec = new LinkedHashMap<String, Object>();
Date startDate;
try {
startDate = getRandStartDate();
rec.put("StartTime", startDate);
int start = 7200000, end = 0;
int duration = getRandDuration(start, end);
rec.put("Duration", duration);
Date endDate = getRandEndDate(startDate, duration);
rec.put("EndTime", endDate);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return rec;
}
private Date getRandEndDate(Date startDate, int duration) {
Random r = new Random();
int ranSec = r.nextInt(duration - 0) + 0;
return new Date(startDate.getTime() + ranSec * 1000);
}
private int getRandDuration(int High, int Low) {
Random r = new Random();
return r.nextInt(High - Low) + Low;
}
private Date getRandStartDate() throws ParseException {
Date theDay = new SimpleDateFormat("yyyyMMdd hh:mm:ss")
.parse("20130101 00:00:00");
int High = 60 * 60 * 24 * 30 * 6;
Random r = new Random();
int Low = 10;
int R = r.nextInt(High - Low) + Low;
return new Date(theDay.getTime() + R * 1000);
}
}
Here is the output. I am showing 2 set of it. I have to separate the time, duration etc.
Tue Jan 08 11:01:57 IST 2013
6074479
Fri Jan 18 12:56:24 IST 2013

Firstly, your design is strange to start with - why are you calling getRecord() on an instance, when it doesn't do anything with the fields of the object you're calling it on?
Additionally, when you're iterating over a map, you're actually iterating over the same map 3 times:
for (int j = 0; j < rec.size(); j++) {
Collection c = rec.values();
Iterator itr = c.iterator();
int count=0;
while (itr.hasNext()) {
Object element=itr.next();
System.out.println(element);
}
System.out.println();
}
Your outer loop is pointless here - you're never using j, after all. I would probably iterate over the entries rather than the values, if you really want to - then you can print out the key which goes with each value.
Next, I would encourage you not to use a map for this at all - create a separate type with fields for start time, duration and end time. That will fix things very simply.
Next, if you still want to use a map, stop using the raw types - it'll make your life simpler.
Finally, if you really still want to use a map, you already know the keys, so there's no point in iterating over it:
System.out.println("Start: " + map.get("StartTime");
System.out.println("Duration: " + map.get("Duration");
System.out.println("End: " + map.get("EndTime");
Basically, I strongly suggest that you take a step back and revisit your whole design. You may well find it's better to start from scratch than to change your existing code.

Try to generify this code:
private Map getRecord() {
Map<String, Object> rec = new LinkedHashMap<String, Object>();
Date startDate;
try {
startDate = getRandStartDate();
rec.put("StartTime", startDate);
int start = 7200000, end = 0;
int duration = getRandDuration(start, end);
rec.put("Duration", duration);
Date endDate = getRandEndDate(startDate, duration);
rec.put("EndTime", endDate);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return rec;
}
Something like that:
private DateInterval getRecord() {
DateInterval interval = null;
try {
Date startDate = getRandStartDate();
int start = 7200000, end = 0;
int duration = getRandDuration(start, end);
Date endDate = getRandEndDate(startDate, duration);
interval = new DateInterval(startDate, endDate, duration);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return interval;
}
See also:
public class DateInterval {
private Date startDate;
private Date endDate;
private int duration;
public DateInterval(Date startDate, Date endDate, int duration) {
this.startDate = startDate;
this.endDate = endDate;
this.duration = duration;
}
public Date getStartDate() {
return startDate;
}
public Date getEndDate() {
return endDate;
}
public int getDuration() {
return duration;
}
}
I mean, you don't need Map for this purpose, use the your own entity. If you need to hold all your entities at Collection, use Map with DB UUIDs as a keys or List.

Related

Implement Java method for test data [duplicate]

I'm trying to generate a random date of birth for people in my database using a Java program. How would I do this?
import java.util.GregorianCalendar;
public class RandomDateOfBirth {
public static void main(String[] args) {
GregorianCalendar gc = new GregorianCalendar();
int year = randBetween(1900, 2010);
gc.set(gc.YEAR, year);
int dayOfYear = randBetween(1, gc.getActualMaximum(gc.DAY_OF_YEAR));
gc.set(gc.DAY_OF_YEAR, dayOfYear);
System.out.println(gc.get(gc.YEAR) + "-" + (gc.get(gc.MONTH) + 1) + "-" + gc.get(gc.DAY_OF_MONTH));
}
public static int randBetween(int start, int end) {
return start + (int)Math.round(Math.random() * (end - start));
}
}
java.util.Date has a constructor that accepts milliseconds since The Epoch, and java.util.Random has a method that can give you a random number of milliseconds. You'll want to set a range for the random value depending on the range of DOBs that you want, but those should do it.
Very roughly:
Random rnd;
Date dt;
long ms;
// Get a new random instance, seeded from the clock
rnd = new Random();
// Get an Epoch value roughly between 1940 and 2010
// -946771200000L = January 1, 1940
// Add up to 70 years to it (using modulus on the next long)
ms = -946771200000L + (Math.abs(rnd.nextLong()) % (70L * 365 * 24 * 60 * 60 * 1000));
// Construct a date
dt = new Date(ms);
Snippet for a Java 8 based solution:
Random random = new Random();
int minDay = (int) LocalDate.of(1900, 1, 1).toEpochDay();
int maxDay = (int) LocalDate.of(2015, 1, 1).toEpochDay();
long randomDay = minDay + random.nextInt(maxDay - minDay);
LocalDate randomBirthDate = LocalDate.ofEpochDay(randomDay);
System.out.println(randomBirthDate);
Note: This generates a random date between 1Jan1900 (inclusive) and 1Jan2015 (exclusive).
Note: It is based on epoch days, i.e. days relative to 1Jan1970 (EPOCH) - positive meaning after EPOCH, negative meaning before EPOCH
You can also create a small utility class:
public class RandomDate {
private final LocalDate minDate;
private final LocalDate maxDate;
private final Random random;
public RandomDate(LocalDate minDate, LocalDate maxDate) {
this.minDate = minDate;
this.maxDate = maxDate;
this.random = new Random();
}
public LocalDate nextDate() {
int minDay = (int) minDate.toEpochDay();
int maxDay = (int) maxDate.toEpochDay();
long randomDay = minDay + random.nextInt(maxDay - minDay);
return LocalDate.ofEpochDay(randomDay);
}
#Override
public String toString() {
return "RandomDate{" +
"maxDate=" + maxDate +
", minDate=" + minDate +
'}';
}
}
and use it like this:
RandomDate rd = new RandomDate(LocalDate.of(1900, 1, 1), LocalDate.of(2010, 1, 1));
System.out.println(rd.nextDate());
System.out.println(rd.nextDate()); // birthdays ad infinitum
You need to define a random date, right?
A simple way of doing that is to generate a new Date object, using a long (time in milliseconds since 1st January, 1970) and substract a random long:
new Date(Math.abs(System.currentTimeMillis() - RandomUtils.nextLong()));
(RandomUtils is taken from Apache Commons Lang).
Of course, this is far to be a real random date (for example you will not get date before 1970), but I think it will be enough for your needs.
Otherwise, you can create your own date by using Calendar class:
int year = // generate a year between 1900 and 2010;
int dayOfYear = // generate a number between 1 and 365 (or 366 if you need to handle leap year);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, randomYear);
calendar.set(Calendar.DAY_OF_YEAR, dayOfYear);
Date randomDoB = calendar.getTime();
For Java8 -> Assumming the data of birth must be before current day:
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.Period;
import java.time.temporal.ChronoUnit;
import java.util.Random;
public class RandomDate {
public static LocalDate randomBirthday() {
return LocalDate.now().minus(Period.ofDays((new Random().nextInt(365 * 70))));
}
public static void main(String[] args) {
System.out.println("randomDate: " + randomBirthday());
}
}
If you don't mind adding a new library to your code you can use MockNeat (disclaimer: I am one of the authors).
MockNeat mock = MockNeat.threadLocal();
// Generates a random date between [1970-1-1, NOW)
LocalDate localDate = mock.localDates().val();
System.out.println(localDate);
// Generates a random date in the past
// but beore 1987-1-30
LocalDate min = LocalDate.of(1987, 1, 30);
LocalDate past = mock.localDates().past(min).val();
System.out.println(past);
LocalDate max = LocalDate.of(2020, 1, 1);
LocalDate future = mock.localDates().future(max).val();
System.out.println(future);
// Generates a random date between 1989-1-1 and 1993-1-1
LocalDate start = LocalDate.of(1989, 1, 1);
LocalDate stop = LocalDate.of(1993, 1, 1);
LocalDate between = mock.localDates().between(start, stop).val();
System.out.println(between);
Generating random Date of Births:
import java.util.Calendar;
public class Main {
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
System.out.println(randomDOB());
}
}
public static String randomDOB() {
int yyyy = random(1900, 2013);
int mm = random(1, 12);
int dd = 0; // will set it later depending on year and month
switch(mm) {
case 2:
if (isLeapYear(yyyy)) {
dd = random(1, 29);
} else {
dd = random(1, 28);
}
break;
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
dd = random(1, 31);
break;
default:
dd = random(1, 30);
break;
}
String year = Integer.toString(yyyy);
String month = Integer.toString(mm);
String day = Integer.toString(dd);
if (mm < 10) {
month = "0" + mm;
}
if (dd < 10) {
day = "0" + dd;
}
return day + '/' + month + '/' + year;
}
public static int random(int lowerBound, int upperBound) {
return (lowerBound + (int) Math.round(Math.random()
* (upperBound - lowerBound)));
}
public static boolean isLeapYear(int year) {
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, year);
int noOfDays = calendar.getActualMaximum(Calendar.DAY_OF_YEAR);
if (noOfDays > 365) {
return true;
}
return false;
}
}
You can checkout randomizer for random data generation.This library helps to create random data from given Model class.Checkout below example code.
public class Person {
#DateValue( from = "01 Jan 1990",to = "31 Dec 2002" , customFormat = "dd MMM yyyy")
String dateOfBirth;
}
//Generate random 100 Person(Model Class) object
Generator<Person> generator = new Generator<>(Person.class);
List<Person> persons = generator.generate(100);
As there are many built in data generator is accessible using annotation,You also can build custom data generator.I suggest you to go through documentation provided on library page.
Look this method:
public static Date dateRandom(int initialYear, int lastYear) {
if (initialYear > lastYear) {
int year = lastYear;
lastYear = initialYear;
initialYear = year;
}
Calendar cInitialYear = Calendar.getInstance();
cInitialYear.set(Calendar.YEAR, 2015);
long offset = cInitialYear.getTimeInMillis();
Calendar cLastYear = Calendar.getInstance();
cLastYear.set(Calendar.YEAR, 2016);
long end = cLastYear.getTimeInMillis();
long diff = end - offset + 1;
Timestamp timestamp = new Timestamp(offset + (long) (Math.random() * diff));
return new Date(timestamp.getTime());
}
I think this will do the trick:
public static void main(String[] args) {
Date now = new Date();
long sixMonthsAgo = (now.getTime() - 15552000000l);
long today = now.getTime();
for(int i=0; i<10; i++) {
long ms = ThreadLocalRandom.current().nextLong(sixMonthsAgo, today);
Date date = new Date(ms);
System.out.println(date.toString());
}
}
If you don't mind a 3rd party library, the Utils library has a RandomDateUtils that generates random java.util.Dates and all the dates, times, instants, and durations from Java 8's date and time API
LocalDate birthDate = RandomDateUtils.randomPastLocalDate();
LocalDate today = LocalDate.now();
LocalDate under18YearsOld = RandomDateUtils.randomLocalDate(today.minus(18, YEARS), today);
LocalDate over18YearsOld = RandomDateUtils.randomLocalDateBefore(today.minus(18, YEARS));
It is in the Maven Central Repository at:
<dependency>
<groupId>com.github.rkumsher</groupId>
<artifactId>utils</artifactId>
<version>1.3</version>
</dependency>
simplest method:
public static LocalDate randomDateOfBirth() {
final int maxAge = 100 * 12 * 31;
return LocalDate.now().minusDays(new Random().nextInt(maxAge));
}
Using the original answer and adapting it to the new java.time.* api and adding ways to generate n random dates -- the function will return a List.
// RandomBirthday.java
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class RandomBirthday {
public static List<String> getRandomBirthday(int groupSize, int minYear, int maxYear) {
/** Given a group size, this method will return `n` random birthday
* between 1922-2022 where `n=groupSize`.
*
* #param groupSize the number of random birthday to return
* #param minYear the min year [lower bound]
* #param maxYear the max year [upper bound]
* #return a list of random birthday with format YYYY-MM-DD
*/
ArrayList<String> birthdays = new ArrayList<>();
DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd");
for (int i = 0; i < groupSize; i++) {
LocalDate baseDate = LocalDate.now();
LocalDate baseYear = baseDate.withYear(ThreadLocalRandom.current().nextInt(minYear, maxYear));
int dayOfYear = ThreadLocalRandom.current().nextInt(1, baseYear.lengthOfYear());
LocalDate baseRandBirthday = baseYear.withDayOfYear(dayOfYear);
LocalDate randDate = LocalDate.of(
baseRandBirthday.getYear(),
baseRandBirthday.getMonth(),
baseRandBirthday.getDayOfMonth()
);
String formattedDate = dateFormat.format(randDate);
birthdays.add(formattedDate);
}
return birthdays;
}
public static void main(String[] args) {
// main method
List<String> bDay = getRandomBirthday(40, 1960, 2022);
System.out.println(bDay);
}
}
I am studying Scala and ended up Googling Java solutions for choosing a random date between range. I found this post super helpful and this is my final solution. Hope it can help future Scala and Java programmers.
import java.sql.Timestamp
def date_rand(ts_start_str:String = "2012-01-01 00:00:00", ts_end_str:String = "2015-01-01 00:00:00"): String = {
val ts_start = Timestamp.valueOf(ts_start_str).getTime()
val ts_end = Timestamp.valueOf(ts_end_str).getTime()
val diff = ts_end - ts_start
println(diff)
val ts_rand = new Timestamp(ts_start + (Random.nextFloat() * diff).toLong)
return ts_rand.toString
} //> date_rand: (ts_start_str: String, ts_end_str: String)String
println(date_rand()) //> 94694400000
//| 2012-10-28 18:21:13.216
println(date_rand("2001-01-01 00:00:00", "2001-01-01 00:00:00"))
//> 0
//| 2001-01-01 00:00:00.0
println(date_rand("2001-01-01 00:00:00", "2010-01-01 00:00:00"))
//> 283996800000
//| 2008-02-16 23:15:48.864 //> 2013-12-21 08:32:16.384
int num = 0;
char[] a={'a','b','c','d','e','f'};
String error = null;
try {
num = Integer.parseInt(request.getParameter("num"));
Random r = new Random();
long currentDate = new Date().getTime();
ArrayList<Student> list = new ArrayList<>();
for (int i = 0; i < num; i++) {
String name = "";
for (int j = 0; j < 6; j++) {
name += a[r.nextInt(5)];
}
list.add(new Student(i + 1, name, r.nextBoolean(), new Date(Math.abs(r.nextLong() % currentDate))));
}
request.setAttribute("list", list);
request.setAttribute("num", num);
request.getRequestDispatcher("student.jsp").forward(request, response);
} catch (NumberFormatException e) {
error = "Please enter interger number";
request.setAttribute("error", error);
request.getRequestDispatcher("student.jsp").forward(request, response);
}

Androidplot chart is duplicating label values x-axis & y-axis

I am using androidplot to show a graph, the labels get repeated. i searched forums and stackoverflow haven't found any solution.
now i noticed, if arraysize for x-axis or y-axis is less than 10, the array values get duplicated.
The screenshots show the left axis repeating the value 0,1,2. x-axis values are getting repeated. What is your best suggestion on solving this repeating label issue? Any help would be grateful. If you need any further information let me know.
/**
* A simple XYPlot
*/
public class SimpleXYPlotActivity extends Activity {
private XYPlot plot;
String[] domainLabels;
String oldDateStr, newDateStr;
Date newDate;
int totalDays;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.graph_xy_plot_example);
// initialize our XYPlot reference:
plot = (XYPlot) findViewById(R.id.plot);
Intent intent = getIntent();
Bundle bd = intent.getExtras();
DateFormat format = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH);
if (bd != null) {
oldDateStr = (String) bd.get("START_DATE");
newDateStr = (String) bd.get("END_DATE");
plot.setTitle("From: "+oldDateStr+" To: "+newDateStr);
try {
Date date1 = format.parse(oldDateStr);
Date date2 = format.parse(newDateStr);
long diff = date2.getTime() - date1.getTime();
totalDays = Integer.parseInt(String.valueOf(TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS)));
System.out.println ("Days: " + TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS));
} catch (ParseException e) {
e.printStackTrace();
}
}
SimpleDateFormat formatterDateGraph = new SimpleDateFormat("MMM d");
SimpleDateFormat formatterDate = new SimpleDateFormat("yyyy-MM-dd");
try {
newDate = format.parse(newDateStr);
} catch (ParseException e) {
e.printStackTrace();
}
DatabaseHandler db = new DatabaseHandler(this);
Calendar cal = GregorianCalendar.getInstance();
cal.setTime(newDate);
domainLabels= new String[totalDays];
Number[] series1Numbers = new Number[totalDays];
//domain 0 set outside loop for oldDateStr
domainLabels[0]=String.valueOf(formatterDateGraph.format(newDate.getTime()));
List<Orders> reportForDayList = db.getReportByTranType(oldDateStr, oldDateStr,"1");
series1Numbers[0]=reportForDayList.size();
for (int i = 1; i <totalDays ; i++) {
cal.add(Calendar.DAY_OF_YEAR, -1);
domainLabels[i] = String.valueOf(formatterDateGraph.format(cal.getTime()));
//fetch ordercount for that day
reportForDayList = db.getReportByTranType(formatterDate.format(cal.getTime()),formatterDate.format(cal.getTime()),"1");
series1Numbers[i]=reportForDayList.size();
}
series1Numbers = reverseSeries(series1Numbers);
domainLabels = reverseDomain(domainLabels);
//reverseNumber array
// domainLabels = reverseNumber(domainLabels);
// turn the above arrays into XYSeries':
// (Y_VALS_ONLY means use the element index as the x value)
XYSeries series1 = new SimpleXYSeries(
Arrays.asList(series1Numbers), SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "Sales");
/* XYSeries series2 = new SimpleXYSeries(
Arrays.asList(series2Numbers), SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "Series2");*/
// create formatters to use for drawing a series using LineAndPointRenderer
// and configure them from xml:
LineAndPointFormatter series1Format = new LineAndPointFormatter(Color.RED, Color.GREEN, Color.BLUE, null);
LineAndPointFormatter series2Format = new LineAndPointFormatter(Color.RED, Color.GREEN, Color.BLUE, null);
// add an "dash" effect to the series2 line:
/* series2Format.getLinePaint().setPathEffect(new DashPathEffect(new float[] {
// always use DP when specifying pixel sizes, to keep things consistent across devices:
PixelUtils.dpToPix(20),
PixelUtils.dpToPix(15)}, 0));*/
// just for fun, add some smoothing to the lines:
// see: http://androidplot.com/smooth-curves-and-androidplot/
series1Format.setInterpolationParams(
new CatmullRomInterpolator.Params(10, CatmullRomInterpolator.Type.Centripetal));
series2Format.setInterpolationParams(
new CatmullRomInterpolator.Params(10, CatmullRomInterpolator.Type.Centripetal));
// add a new series' to the xyplot:
plot.addSeries(series1, series1Format);
// plot.addSeries(series2, series2Format);
plot.getGraph().getLineLabelStyle(XYGraphWidget.Edge.LEFT).setFormat(new DecimalFormat("#"));
plot.getGraph().getLineLabelStyle(XYGraphWidget.Edge.BOTTOM).setFormat(new Format() {
#Override
public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) {
int i = Math.round(((Number) obj).floatValue());
return toAppendTo.append(domainLabels[i]);
}
#Override
public Object parseObject(String source, ParsePosition pos) {
return null;
}
});
}
public static Number[] reverseSeries(Number[] a)
{
int l = a.length;
for (int j = 0; j < l / 2; j++)
{
Number temp = a[j];
a[j] = a[l - j - 1];
a[l - j - 1] = temp;
}
return a;
}
public static String[] reverseDomain(String[] a)
{
int l = a.length;
for (int j = 0; j < l / 2; j++)
{
String temp = a[j];
a[j] = a[l - j - 1];
a[l - j - 1] = temp;
}
return a;
}
}
You are creating the domain values by transforming a 6 day range into long values and then subdividing the total range within those values into 10 distinct segments: You can't get 10 day labels from a range of 6 days.
To solve this problem you can either reduce the number of domain segments you are displaying or show more days worth of data.

i have set of date ranges, i need to get the combined date range ,if any of the date overlaps in java [duplicate]

This question already has answers here:
Determine Whether Two Date Ranges Overlap
(39 answers)
Closed 5 years ago.
I have set of date ranges, I need to get the combined date range if any of the dates overlap in Java.
Given three sets of date ranges, if any of the dates overlap with another range of dates need to be combined.
Example:
20170101-20170331
20170101-20170430
20170430-20170501
Expected result is:
20170101-20170430
20170430-20170501
I have all the dates in String Variable. Can please any one help me to how to write the code for that. I have pasted below my code.
I want to achieve the expected results. I couldn't find out how I need to modify this code. I am a beginner, please help me to do that. I have got this sample program from StackOverflow.
package com.kkkkk.Combine;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
public class Ideone {
public static void main(String[] args) throws java.lang.Exception {
ArrayList<Interval> x = new ArrayList<>();
x.add(new Interval("20170430", "20170501")); // "20170101", "20170430"
x.add(new Interval("20170101", "20170430"));// 20170101-20170430
x.add(new Interval("20170101", "20170331"));
x = merge(x);
for (Interval i1 : x) {
System.out.println(i1.getStartDate() + " " + i1.getEndDate());
}
}
public static ArrayList<Interval> merge(ArrayList<Interval> intervals) {
if (intervals.size() == 0 || intervals.size() == 1)
return intervals;
ArrayList<Interval> result = new ArrayList<Interval>();
Collections.sort(intervals, new IntervalComparator());
System.out.println("intervals ggggg\n" + intervals + "\n");
Interval first = intervals.get(0);
String start = first.getStartDate();
String end = first.getEndDate();
Date startDateF = null;
Date endDateF = null;
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
startDateF = sdf.parse(start);
endDateF = sdf.parse(end);
// ArrayList<Interval> result = new ArrayList<Interval>();
for (int i = 1; i < intervals.size(); i++) {
Interval current = intervals.get(i);
Date currentEndDate = sdf.parse(current.getEndDate());
Date currentStartDate = sdf.parse(current.getStartDate());
// if ((current.getStartDate().after(endDateF)) ||
Date d1 = minDate(endDateF, currentStartDate);
if ((currentStartDate).compareTo(endDateF) <= 0) {
endDateF = maxDate(currentEndDate, endDateF);
} else {
result.add(new Interval(start, (sdf.format(endDateF))));
// start = current.start;
// end = current.end;
start = sdf.format(currentStartDate);
endDateF = (currentEndDate);
enter code here
}
}
result.add(new Interval(start, end));
// result.add(new Interval(start, (sdf.format(endDateF))));
}
catch (ParseException ex) {
ex.printStackTrace();
}
// result.add(new Interval(start, end));
return result;
// return intervals;
}
public static Date minDate(Date date1, Date date2) {
// if date1 before date2 then return date1 else return date2
return date1.before(date2) ? date1 : date2;
}
/**
* find Max Dates
*
* #param date1
* #param date2
* #return
*/
public static Date maxDate(Date date1, Date date2) {
// if date1 after date2 then return date1 else return date2
System.out.println("date max");
return date1.after(date2) ? date1 : date2;
}
}
ISO 8601
Use standard ISO 8601 formats when serializing date-time values to text. Your format complies with the “basic” version of the standard, but better to use the full format when possible:
YYYY-MM-DD
Use the standard format for a date range, using a slash character as separator:
YYYY-MM-DD/YYYY-MM-DD
If you cannot alter the input strings, split the string on the hyphen. Parse each piece as a LocalDate. Use those objects to instantiate a LocalDateRange.
LocalDate ld = LocalDate.parse( "20170101" , DateTimeFormatter.BASIC_ISO_DATE ) ;
LocalDateRange
Use the LocalDateRange class from the ThreeTen-Extra project which extends java.time class functionality. Uses the standard format when parsing and generating text.
LocalDateRange range = LocalDateRange.parse( "2017-01-01/2017-03-31" ) ;
Collect in a List<LocalDateRange>.
To sort, write a comparator that calls LocalDateRange::getStart.
Compare to another range to see if they overlap. If so, combine with a call to union.
if ( range.overlaps( otherRange ) ) {
range = range.union( otherRange ) ;
}
If they do not overlap, you have finished that round. Store this result in another List<LocalDateRange>. Start another round with the next range.
Lather, rinse, repeat.
I assume your Interval is something like this:
private static class Interval {
private String begin;
private String end;
public Interval(String begin, String end) {
this.begin = begin;
this.end = end;
}
public String getStartDate() {
return begin;
}
public String getEndDate() {
return end;
}
}
What you need to do is to merge a Interval list. A solution is sort list with start date then end date. And then store the earliest start time and latest end time in a cursor variable. A example:
public List<Interval> merge(List<Interval> intervals) {
Collections.sort(intervals, new Comparator<Interval>() {
#Override
public int compare(Interval o1, Interval o2) {
if (o1.getStartDate().equals(o2.getStartDate())) {
return o1.getEndDate().compareTo(o2.getEndDate());
}
return o1.getStartDate().compareTo(o2.getStartDate());
}
});
List<Interval> ret = new ArrayList<>();
String MAX_VAL = "99999999";
String MIN_VAL = "00000000";
String start = MAX_VAL, end = MIN_VAL;
for (Interval interval : intervals) {
if (interval.getStartDate().compareTo(end) > 0) {
if (start.compareTo(MAX_VAL) < 0) {
ret.add(new Interval(start, end));
}
start = interval.getStartDate();
end = interval.getEndDate();
} else {
if (start.compareTo(interval.getStartDate()) < 0) {
start = interval.getStartDate();
}
if (end.compareTo(interval.getEndDate()) > 0) {
end = interval.getEndDate();
}
}
}
if (start.compareTo(MAX_VAL) < 0) {
ret.add(new Interval(start, end));
}
return ret;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
ArrayList<MainLab.Interval> list = new ArrayList<MainLab.Interval>();
list.add(new MainLab.Interval("20170430", "20170501"));
list.add(new MainLab.Interval("20170101", "20170430"));
list.add(new MainLab.Interval("20170101", "20170331"));
for (Iterator iterator = mergeInterval(list).iterator(); iterator.hasNext();) {
Interval interval = (Interval) iterator.next();
System.out.println(interval.getStart()+ "==="+interval.getEnd());
}
}
public static List<Interval> mergeInterval(ArrayList<MainLab.Interval> list){
/*
* Sort the list , Interval class have implemented Comparable Interface.
* So we will get sorted intervals. Intervals sorted based on start of interval
*/
Collections.sort(list);
Set<MainLab.Interval> resultlist = new TreeSet<MainLab.Interval>();
List<MainLab.Interval> mergedIntervals = new ArrayList<MainLab.Interval>();
//declare date formate to parse and format date from string to and from
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
if(list.size() == 1){
//resultlist = list
return list;
}
if(list.size() > 1){
// get first interval Object. conside it as first interval
Interval mergeInterval = list.get(0);
// loop other intervals from second in the list
for(int i=1; i< list.size() ; i++){
Interval interval2 = list.get(i);
try{
Date startDate1 = sdf.parse(mergeInterval.getStart());
Date endDate1 = sdf.parse(mergeInterval.getEnd());
Date startDate2 = sdf.parse(interval2.getStart());
Date endDate2 = sdf.parse(interval2.getEnd());
// compare if current interval's start date is before merging interval's end date
// then the two intervals are overlaping
if(startDate2.compareTo(endDate1) < 0 ){
// check whether end date of current loop interval is after the merging interval.
// then we need to update the end date of merging interval with looping interval's end date
if(endDate2.compareTo(endDate1) > 0 ){
mergeInterval.setEnd(interval2.getEnd());
}
}else{
// compare if current interval's start date is after merging interval's end date
// then it must be a new interval start so swap mergInterval variable with current looping interval
mergeInterval = interval2;
}
//add merge interval to set.
resultlist.add(mergeInterval);
}catch(Exception ex){
ex.printStackTrace();
}
}
}
mergedIntervals.addAll(resultlist);
return mergedIntervals;
}
public static class Interval implements Comparable<Interval>{
private String start;
private String end;
public String getStart() {
return start;
}
public void setStart(String start) {
this.start = start;
}
public String getEnd() {
return end;
}
public void setEnd(String end) {
this.end = end;
}
public Interval(){
}
public Interval(String start,String end){
this.start = start;
this.end = end;
}
#Override
public boolean equals(Object obj) {
// TODO Auto-generated method stub
Interval inteval = (Interval)obj;
return this.getStart().equals(inteval.getStart()) && this.getEnd().equals(inteval.getEnd()) ;
}
#Override
public int compareTo(Interval o) {
// TODO Auto-generated method stub
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
try{
Date startDate = sdf.parse(start);
Date endDate = sdf.parse(end);
Date pstartDate = sdf.parse(o.start);
Date pendDate = sdf.parse(o.end);
return startDate.compareTo(pstartDate);
}catch(Exception ex){
ex.printStackTrace();
}
return 0;
}
}

Convert given time in String format to seconds in Android

Suppose time is given in MM:SS(ex- 02:30) OR HH:MM:SS in String format.how can we convert this time to second.
In your case, using your example you could use something like the following:
String time = "02:30"; //mm:ss
String[] units = time.split(":"); //will break the string up into an array
int minutes = Integer.parseInt(units[0]); //first element
int seconds = Integer.parseInt(units[1]); //second element
int duration = 60 * minutes + seconds; //add up our values
If you want to include hours just modify the code above and multiply hours by 3600 which is the number of seconds in an hour.
public class TimeToSeconds {
// given: mm:ss or hh:mm:ss or hhh:mm:ss, return number of seconds.
// bad input throws NumberFormatException.
// bad includes: "", null, :50, 5:-4
public static long parseTime(String str) throws NumberFormatException {
if (str == null)
throw new NumberFormatException("parseTimeString null str");
if (str.isEmpty())
throw new NumberFormatException("parseTimeString empty str");
int h = 0;
int m, s;
String units[] = str.split(":");
assert (units.length == 2 || units.length == 3);
switch (units.length) {
case 2:
// mm:ss
m = Integer.parseInt(units[0]);
s = Integer.parseInt(units[1]);
break;
case 3:
// hh:mm:ss
h = Integer.parseInt(units[0]);
m = Integer.parseInt(units[1]);
s = Integer.parseInt(units[2]);
break;
default:
throw new NumberFormatException("parseTimeString failed:" + str);
}
if (m<0 || m>60 || s<0 || s>60 || h<0)
throw new NumberFormatException("parseTimeString range error:" + str);
return h * 3600 + m * 60 + s;
}
// given time string (hours:minutes:seconds, or mm:ss, return number of seconds.
public static long parseTimeStringToSeconds(String str) {
try {
return parseTime(str);
} catch (NumberFormatException nfe) {
return 0;
}
}
}
import org.junit.Test;
import static org.junit.Assert.*;
public class TimeToSecondsTest {
#Test
public void parseTimeStringToSeconds() {
assertEquals(TimeToSeconds.parseTimeStringToSeconds("1:00"), 60);
assertEquals(TimeToSeconds.parseTimeStringToSeconds("00:55"), 55);
assertEquals(TimeToSeconds.parseTimeStringToSeconds("5:55"), 5 * 60 + 55);
assertEquals(TimeToSeconds.parseTimeStringToSeconds(""), 0);
assertEquals(TimeToSeconds.parseTimeStringToSeconds("6:01:05"), 6 * 3600 + 1*60 + 5);
}
#Test
public void parseTime() {
// make sure all these tests fail.
String fails[] = {null, "", "abc", ":::", "A:B:C", "1:2:3:4", "1:99", "1:99:05", ":50", "-4:32", "-99:-2:4", "2.2:30"};
for (String t: fails)
{
try {
long seconds = TimeToSeconds.parseTime(t);
assertFalse("FAIL: Expected failure:"+t+" got "+seconds, true);
} catch (NumberFormatException nfe)
{
assertNotNull(nfe);
assertTrue(nfe instanceof NumberFormatException);
// expected this nfe.
}
}
}
}
int v = 0;
for (var x: t.split(":")) {
v = v * 60 + new Byte(x);
}
This snippet should support HH:MM:SS (v would result in seconds) or HH:MM (v would be in minutes)
try this
hours = totalSecs / 3600;
minutes = (totalSecs % 3600) / 60;
seconds = totalSecs % 60;
timeString = String.format("%02d",seconds);
private static final String TIME_FORMAT = "hh:mm a";//give whatever format you want.
//Function calling
long timeInMillis = TimeUtils.getCurrentTimeInMillis("04:21 PM");
long seconds = timeInMillis/1000;
//Util Function
public static long getCurrentTimeInMillis(String time) {
SimpleDateFormat sdf = new SimpleDateFormat(TIME_FORMAT, Locale.getDefault());
// sdf.setTimeZone(TimeZone.getTimeZone("GMT")); //getting exact milliseconds at GMT
// sdf.setTimeZone(TimeZone.getDefault());
Date date = null;
try {
date = sdf.parse(time);
} catch (ParseException e) {
e.printStackTrace();
}
return date.getTime();
}
I have written an extension function in Kotlin for converting String to seconds
fun String?.converTimeToSeconds(): Int {
if (this.isNullOrEmpty().not()) {
val units = this?.split(":")?.toTypedArray()
if (units?.isNotEmpty() == true && units.size >= 3) {
val hours = units[0].toInt()
val minutes = units[1].toInt()
val seconds = units[2].toInt()
return (3660 * hours) + (60 * minutes) + seconds
}
}
return 0
}

Android Listview countdown timer is causing strange results

I have a listview and want to countdown each item. My issue is when I scroll the countdown times jump around to incorrect items (so it shows another items countdown time) and there is no rhyme or reason to it? here is the code
private final Map<String, TextView> mcounterlist= new HashMap<String, TextView>();
Then in my getview on my adapater I do
String gmtFormat = "yyyy-MM-dd HH:mm:ss";
TimeZone tz = TimeZone.getDefault();
SimpleDateFormat sdf = new SimpleDateFormat(gmtFormat);
sdf.setTimeZone(tz);
Date dd = null;
try {
dd = sdf.parse(o.endAt);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Date now = new Date();
String sss = timeCalculate((dd.getTime() /1000)- (now.getTime() /1000) );
ea.setText("Time Left: " + sss);
TextView cdi = new TextView();
mcounterlist.put(o.id , cdi);
So at this point I I just run a repeating thread to update.
private final Runnable mRunnable = new Runnable() {
public void run() {
// TextView textView;
String gmtFormat = "yyyy-MM-dd HH:mm:ss";
TimeZone tz = TimeZone.getDefault() ;
SimpleDateFormat sdf = new SimpleDateFormat(gmtFormat);
sdf.setTimeZone(tz);
// if counters are active
if(mcounterlist.size() > 0)
{
for (int i = 0; i < m_orders.size() && i < mcounterlist.size() ;i++) {
Order o = m_orders.get(i);
TextView c = mcounterlist.get(o.id);
Date dd = null;
try {
dd = sdf.parse(o.endAt);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Date now = new Date();
long l = (dd.getTime() /1000)- (now.getTime() /1000);
String sss;
if (l < 0)
{
sss = "ENDED";
}
else
{
sss = timeCalculate(l);
}
if(l < 60 * 60 * 24)
{
c.setBackgroundColor(Color.parseColor("#E3170D"));
}
else
{
c.setBackgroundColor(Color.parseColor("#00000000"));
}
c.setText("Time Left: " + sss);
}
}
mHandler.postDelayed(this, 1000);
}
};
But when I scroll through my list, the textviews jump all over the place. I believe part of my issue is related to how I sort the list every 30 seconds, but the ID's of the items don't change. Is there anything obvious that is wrong?
Thanks.
So the issue is that the views in a listview get reused, the solution was to implement the following change the id to the position in my hashmap and put it in GETVIEW
mcounterlist.remove(position);
mcounterlist.put(position , ea);
You probably don't need to remove the position, but I left it in there since I spent a hour on this, and it works so I don't wnat to change anything:)
Then in my repeat task I need to exclude anyitem not visibe, so here is my handler code
int fp = lv.getFirstVisiblePosition() -1 < 0 ? 0 :lv.getFirstVisiblePosition() -1;
int lp = lv.getLastVisiblePosition();
for (int i = fp; i < mcounterlist.size() && i < lp;i++) {
//Log.i("TEST231231",String.valueOf(i));
if (i < lv.getFirstVisiblePosition() -1 )
{
continue;
}
if (i >= lv.getLastVisiblePosition())
{
continue;
}
//my adapter list
Order o = m_orders.get(i);
//since I set the position as the refereance, I can use that for the hashmap
TextView c = mcounterlist.get(i);
...
So in essance since the same textviews were getting recycled, I could not update all of them because items that were not on the list were sharing the active text boxes. To eliminate this issue, I check and only edit the textboxes for items that are visible.

Categories

Resources