how to get near time for the present time [Android Studio] - java

i have 5 times
example:
4:21 AM
12:1 PM
3:32 PM
6:30 PM
8:4 PM
and the current time is
10:4 AM
I want to do a comparison
What is the next time closest to the current time
the result will be:
NEXT TIME : 12:1 PM

You can turn a time to a date object and then into a long (milliseconds since Jan 1, 1970), and calculate the difference in milliseconds
long diffInMs = currentDate.getTime() - anotherDate.getTime();
And then check which has the smallest difference, but being also equal to or greater than zero. Negative difference means old date and you want the next closest date
To convert the times to dates check this: https://stackoverflow.com/a/8826392/2597775
Basically, it says:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
String inputString = "00:01:30.500";
Date date = sdf.parse("1970-01-01 " + inputString);

Update: Added logic to rollover at midnight, and added alternative using binary search.
First parse the inputs to a time in milliseconds of the day, by parsing the time string as if it's in UTC time zone.
Then find the smallest value on or after the "current" value, or just smallest value if no value is on or after the "current" value (rollover).
Example:
public static String findNext(String current, String... times) throws ParseException {
SimpleDateFormat fmt = new SimpleDateFormat("hh:mm a");
fmt.setTimeZone(TimeZone.getTimeZone("UTC"));
long currentMillis = fmt.parse(current).getTime();
long bestMillis = 0, minMillis = 0;
String bestTime = null, minTime = null;
for (String time : times) {
long millis = fmt.parse(time).getTime();
if (millis >= currentMillis && (bestTime == null || millis < bestMillis)) {
bestMillis = millis;
bestTime = time;
}
if (minTime == null || millis < minMillis) {
minMillis = millis;
minTime = time;
}
}
return (bestTime != null ? bestTime : minTime);
}
Test
System.out.println(findNext("10:4 AM",
"4:21 AM", "12:1 PM", "3:32 PM", "6:30 PM", "8:4 PM"));
System.out.println(findNext("10:4 PM",
"4:21 AM", "12:1 PM", "3:32 PM", "6:30 PM", "8:4 PM"));
Output
12:1 PM
4:21 AM
If the given times are guaranteed to already be sorted, then it can be done with a binary search:
public static String findNext(String current, String... times) {
SimpleDateFormat fmt = new SimpleDateFormat("hh:mm a");
fmt.setTimeZone(TimeZone.getTimeZone("UTC"));
int idx = Arrays.binarySearch(times, current, new Comparator<String>() {
#Override
public int compare(String s1, String s2) {
try {
return fmt.parse(s1).compareTo(fmt.parse(s2));
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
});
if (idx < 0)
idx = -idx - 1;
return times[idx < times.length ? idx : 0];
}

i specially design a function to solve your problem , use function as you needed.
it will works for you surely.
/**
*
* #author Niravdas
*/
public class TimeDiff {
String[] times = { "04:21 AM", "12:01 PM", "03:32 PM", "06:30 PM", "08:04 PM"};
String findingafter="10:04 AM";
public TimeDiff()
{
int time=nextTimeArrayIndex(findingafter,times);
if(time>=0)
System.out.println("NEXT TIME: "+times[time]);
}
public static void main(String argv[])
{
new TimeDiff();
}
int nextTimeArrayIndex(String Finding,String[] fromArray)
{
int shortest=-1,shortestsec=-1;
long minsecdif=(24*60*60+1),minsec=(24*60*60+1);
int hr=Integer.parseInt(Finding.substring(0, 2));
int min=Integer.parseInt(Finding.substring(3, 5));
long seconds = convertToSec(hr, min, 0, Finding.substring(Finding.length()-2));
System.out.println("seconds :" + seconds);
for(int i=0;i<fromArray.length;i++)
{
int temphr=Integer.parseInt(fromArray[i].substring(0, 2));
int tempmin = Integer.parseInt(fromArray[i].substring(3,5));
long tempsec = convertToSec(temphr, tempmin, 0, fromArray[i].substring(Finding.length()-2));
System.out.println("Compared to :" + tempsec);
if((tempsec - seconds) > 0 && minsecdif > (tempsec - seconds))
{
minsecdif = (tempsec - seconds);
shortest = i;
}
if(minsec > tempsec)
{
minsec = tempsec;
shortestsec=i;
}
}
if(shortest >=0)
{
return shortest;
}
else
{
return shortestsec;
}
}
long convertToSec(int hr,int min,int sec,String AMorPM)
{
if(hr==12)
{
hr=0;
}
long secs = (hr*60*60) + (min*60) + (sec*60);
if(AMorPM.equalsIgnoreCase("PM"))
{
secs += (12*60*60);
}
return secs;
}
}
i hope it will solve your problem.

Related

Split a date into equal intervals based on a given frequency

I'm trying to break a range of dates into equal intervals. Here is the code that I'm using. (Dates are in YYYY-MM-dd format)
Integer frequency= 4;
Date startDate = '2020-02-27';
Date endDate = '2022-02-26';
String[] startD = string.valueOf(behadelPlan.Start_datum__c).split('-');
String[] endD = string.valueOf(behadelPlan.Einddatum__c).split('-');
//String[] dates;
Integer x = 0;
Integer startYear = Integer.valueof(startD[0]);
Integer endYear = Integer.valueof(endD[0]);
//while (x < 4) {
for (Integer i = startYear; i <= endYear; i++) {
Integer endMonth = i != endYear ? 11 : Integer.valueof(endD[1]) - 1;
Integer startMon = i == startYear ? Integer.valueof(startD[1]) - 1 : 0;
for (Integer j = startMon; j <= endMonth && x < frequency; j = j + 1) {
Integer month = j + 1;
String displayMonth;
if (month < 10) {
displayMonth = '0' + month;
} else {
displayMonth = String.valueOf(month);
}
List<string> slist = new string[]{string.valueOf(i), displayMonth, '01'};
string allstring = string.join(sList,'-');
System.debug(slist);
x+=1;
}
}
when I run this I get the output as
2020-02-01
2020-03-01
2020-04-01
2020-05-01
Here In my case, I want to generate the dates at equal(monthly with the day being start dates day) intervals. In the above example, I should be getting the resultant dates as 4 equal intervals (as I've given my frequency in a number of months).
Please let me know on how can I achieve this.
Here is a simple example.
startdate = '2020-01-01'
endDate = '2020-12-01'
frequency = 4
output should be
2020-01-01
2020-03-01
2020-06-01
2020-09-01
Here is how I would do it. I will us class Calendar for this.
public class FrequencyTransform {
public static void main (String[] args) {
System.out.println("Split a date into equal intervals based on a given frequency");
Integer frequency= 4;
try {
Date startDate = new SimpleDateFormat("yyyy-mm-dd").parse("2020-02-27");
Date endDate = new SimpleDateFormat("yyyy-mm-dd").parse("2021-02-26");
Calendar startCalendar = Calendar.getInstance();
startCalendar.clear();
startCalendar.setTime(startDate);
Calendar endCalendar = Calendar.getInstance();
endCalendar.clear();
endCalendar.setTime(endDate);
// id you want the interval to be months
int monthsElapsed = elapsed(startCalendar, endCalendar, Calendar.MONTH);
System.out.println("Number of months between dates:" + monthsElapsed);
int interval = monthsElapsed % frequency;
System.out.println("For the frequency 4 the interval is: " + interval);
while (!startCalendar.after(endCalendar)){
startCalendar.add(Calendar.MONTH,interval);
Date auxDate= startCalendar.getTime();
System.out.println(auxDate);
}
}
catch (ParseException ex) {
ex.printStackTrace();
}
}
private static int elapsed(Calendar before, Calendar after, int field) {
Calendar clone = (Calendar) before.clone(); // Otherwise changes are been reflected.
int elapsed = -1;
while (!clone.after(after)) {
clone.add(field, 1);
elapsed++;
}
return elapsed;
}
}
This is just a quick example. You can take it from here. The thing is Calendar allow you to use different time units. Instead of Calendar.MONTH you can use Calendar.DATE for days, Calendar.YEAR for year. Wasn't very sure how you wanted to do the split.
Sample code ,
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class SOTest {
static DateFormat dateFormat = new SimpleDateFormat("yyy-MM-dd");
public static void main(String[] args) {
try {
String startDateString = "2020-01-01";
String endDateString = "2020-12-01";
int frequency = 4;
Date startDate = (Date)dateFormat.parse(startDateString);
Date endDate = (Date)dateFormat.parse(endDateString);
Long intervalSize = (endDate.getTime()-startDate.getTime())/frequency;
for(int i=0; i<= frequency && intervalSize > 0; i++) {
Date date = new Date(startDate.getTime()+intervalSize*i);
System.out.println("Date :: "+dateFormat.format(date));
}
} catch (ParseException e) {
e.printStackTrace();
}
}
}
output for above ::
Date :: 2020-01-01
Date :: 2020-03-24
Date :: 2020-06-16
Date :: 2020-09-08
Date :: 2020-12-01
For input :: startDate = '2020-02-27' , endDate = '2022-02-26', interval = 4
Date :: 2020-02-27
Date :: 2020-08-27
Date :: 2021-02-26
Date :: 2021-08-27
Date :: 2022-02-26

what is the best solution to split in chunk monthly given two dates startTime and EndTime in Java?

I have to create algorithm to compute the chunk monthly given two dates.
example (format date: yyyy-MM-dd hh:mm:ss) given two dates:
startTime: : 2020-01-10 13:00:25
endTime : 2020-03-19 15:00:30
I have to divide in chunk monthly the period above.
In a nutshell if I compute the chunks would be :
chunk_1 --> from: 2020-01-10 13:00:25 to: 2020-01-31 23:59:59
chunk_2 --> from: 2020-02-01 00:00:00 to: 2020-02-29 23:59:59
chunk_3 --> from: 2020-03-01 00:00:00 to: 2020-03-19 15:00:30
my first solution is the followed:
public static List<ExportDateSegment> datesBetweenWithCalendar(Date d1, Date d2) {
List<ExportDateSegment> dateSegments = new ArrayList<ExportDateSegment>();
Calendar c1 = Calendar.getInstance();
c1.setTime(d1);
int monthsDiff = mounthsDiffbetween(d1, d2);
LOGGER.debug("months between two dates: {} ",monthsDiff);
int i = 1;
while (c1.getTimeInMillis() < d2.getTime()) {
Calendar calendar;
ExportDateSegment exportDateSegment = new ExportDateSegment();
LOGGER.debug("last day of the month: " + c1.getActualMaximum(Calendar.DATE) + " last hour of the month: "
+ c1.getActualMaximum(Calendar.HOUR_OF_DAY) + " first day of the month: "
+ c1.getActualMinimum(Calendar.DAY_OF_MONTH) + " month: " + (c1.get(Calendar.MONTH) + 1));
// the logic is to separate the three cases: the start period, intermediate period and the end period
if (i == 1) {
calendar = new GregorianCalendar(c1.get(Calendar.YEAR), c1.get(Calendar.MONTH),
c1.getActualMaximum(Calendar.DATE), 23, 59, 59);
exportDateSegment.setStartDate(c1.getTime());
exportDateSegment.setEndDate(calendar.getTime());
} else if (i == monthsDiff) {
calendar = new GregorianCalendar(c1.get(Calendar.YEAR), c1.get(Calendar.MONTH),
c1.getActualMinimum(Calendar.DATE), 00, 00, 00);
exportDateSegment.setStartDate(calendar.getTime());
exportDateSegment.setEndDate(d2);
} else {
Calendar startCalendar = new GregorianCalendar(c1.get(Calendar.YEAR), c1.get(Calendar.MONTH),
c1.getActualMinimum(Calendar.DATE), 00, 00, 00);
Calendar endCalendar = new GregorianCalendar(c1.get(Calendar.YEAR), c1.get(Calendar.MONTH),
c1.getActualMaximum(Calendar.DATE), 23, 59, 59);
exportDateSegment.setStartDate(startCalendar.getTime());
exportDateSegment.setEndDate(endCalendar.getTime());
}
c1.add(Calendar.MONTH, 1);
dateSegments.add(exportDateSegment);
i = i + 1;
}
return dateSegments;
}
public static int mounthsDiffbetween(Date d1, Date d2) {
int monthsDiff = 0;
Calendar c1 = Calendar.getInstance();
Calendar c2 = Calendar.getInstance();
c1.setTime(d1);
c2.setTime(d2);
monthsDiff = (c2.get(Calendar.MONTH) - c1.get(Calendar.MONTH)) + 1;
return monthsDiff;
}
ExportDateSegment is the bean that contains
startDate and endDate as attributes, in other words are the chunk.
Is there a smarter solution ?
You should use the Java 8 Time API, e.g. like this:
static List<TemporalRange<LocalDateTime>> chunkMonthly(LocalDateTime start, LocalDateTime end) {
List<TemporalRange<LocalDateTime>> list = new ArrayList<>();
for (LocalDateTime chunkEnd = end, chunkStart; ! chunkEnd.isBefore(start); chunkEnd = chunkStart.minusSeconds(1)) {
chunkStart = chunkEnd.toLocalDate().withDayOfMonth(1).atStartOfDay();
if (chunkStart.isBefore(start))
chunkStart = start;
list.add(new TemporalRange<>(chunkStart, chunkEnd));
}
Collections.reverse(list);
return list;
}
class TemporalRange<T extends TemporalAccessor> {
private final T start;
private final T end;
public TemporalRange(T start, T end) {
this.start = start;
this.end = end;
}
public T getStart() {
return this.start;
}
public T getEnd() {
return this.end;
}
#Override
public String toString() {
return this.start + " to " + this.end;
}
public String toString(DateTimeFormatter fmt) {
return fmt.format(this.start) + " to " + fmt.format(this.end);
}
}
Test
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");
List<TemporalRange<LocalDateTime>> list = chunkMonthly(
LocalDateTime.parse("2020-01-10 13:00:25", fmt),
LocalDateTime.parse("2020-03-19 15:00:30", fmt));
list.forEach(r -> System.out.println(r.toString(fmt)));
Output
2020-01-10 13:00:25 to 2020-01-31 23:59:59
2020-02-01 00:00:00 to 2020-02-29 23:59:59
2020-03-01 00:00:00 to 2020-03-19 15:00:30
You should definitely use the java.time classes to do this. There are built in TemporalAdjusters that help you find the first and last day of a month.
public static List<ExportDateSegment> splitIntoMonths(LocalDateTime start, LocalDateTime end) {
LocalDate segmentEndDate =
start.with(TemporalAdjusters.lastDayOfMonth()).toLocalDate();
LocalTime segmentEndTime = LocalTime.of(23, 59, 59);
LocalDate lastSegmentStartDate = end.with(TemporalAdjusters.firstDayOfMonth()).toLocalDate();
LocalTime segmentStartTime = LocalTime.of(0, 0, 0);
if (lastSegmentStartDate.isBefore(segmentEndDate)) { // start & end are in the same month
return Collections.singletonList(new ExportDateSegment(start, end));
}
ArrayList<ExportDateSegment> list = new ArrayList<>();
// adds the first segment, which is not a whole month
list.add(new ExportDateSegment(start, LocalDateTime.of(segmentEndDate, segmentEndTime)));
// just like a typical for loop, but with LocalDate
for (LocalDate segmentStartDate = segmentEndDate.plusDays(1) ; segmentStartDate.isBefore(lastSegmentStartDate) ; segmentStartDate = segmentStartDate.plusMonths(1)) {
list.add(new ExportDateSegment(
LocalDateTime.of(segmentStartDate, segmentStartTime),
LocalDateTime.of(segmentStartDate.with(TemporalAdjusters.lastDayOfMonth()), segmentEndTime)
));
}
// adds the last segment, which is also not a whole month
list.add(new ExportDateSegment(LocalDateTime.of(lastSegmentStartDate, segmentStartTime), end));
return list;
}
Here is another one using streams:
public class SplitDateRange {
public static class Range {
private final LocalDateTime start;
private final LocalDateTime end;
public Range(LocalDateTime start, LocalDateTime end) {
this.start = start;
this.end = end;
}
#Override
public String toString() {
return "Range{" + "start=" + start + ", end=" + end + '}';
}
}
public static void main(String[] args) {
LocalDateTime start = LocalDateTime.parse("2020-01-10T13:00:25", DateTimeFormatter.ISO_LOCAL_DATE_TIME);
LocalDateTime end = LocalDateTime.parse("2020-03-19T15:00:30", DateTimeFormatter.ISO_LOCAL_DATE_TIME);
Stream.iterate(start, date -> date.isBefore(end), SplitDateRange::firstDateTimeOfNextMonth)
.map(date -> new Range(date, min(end, firstDateTimeOfNextMonth(date).minusSeconds(1))))
.collect(Collectors.toList())
.forEach(System.out::println);
}
public static LocalDateTime firstDateTimeOfNextMonth(LocalDateTime current) {
return current.plusMonths(1).with(TemporalAdjusters.firstDayOfMonth()).with(LocalTime.MIN);
}
public static LocalDateTime min(LocalDateTime a, LocalDateTime b) {
return a.isBefore(b) ? a : b;
}
}

Calculating time between datetimes

Let's say I have two datetimes, 30-11-2015 10:00 and 02-12-2015 15:00. I also have two times, 07:00 and 22:00. How could I calculate the amount of time passed between the two date/times that was within the second times? Using Calendar object? It seems simple but its boggling my mind.
Since none of the other answers include runnable code, I can't tell if they solve the problem or not.
To calculate the duration of a time range within a date range, you have to:
Split the date range into multiple date ranges, each spanning no more than one day.
Calculate the time range within each day date range
Taking the example date range from the question. 30-11-2015 10:00 and 02-12-2015 15:00, we generate the following split day date ranges:
30-11-2015 10:00 - 30-11-2015 24:00
01-12-2015 00:00 - 01-12-2015 24:00
02-12-2015 00:00 - 02-12-2015 15:00
Now, we can apply the time range of 7:00 - 22:00 to each of the split day date ranges.
30-11-2015 10:00 - 30-11-2015 24:00 -> 12 hours
01-12-2015 00:00 - 01-12-2015 24:00 -> 15 hours
02-12-2015 00:00 - 02-12-2015 15:00 -> 8 hours
For a total of 35 hours. The actual calculation would probably be in minutes instead of hours.
Edited to add: I created a Time and a TimeRange class to hold the time and a day time range, respectively. I used the java.util.Date, although I had to create my own increment a day method.
I put all of the classes together so I could post this easier. The classes should be put in separate files.
package com.ggl.testing;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class TimeRangeTest {
private static final SimpleDateFormat inputDateFormat = new SimpleDateFormat(
"dd-MM-yyyy");
public static void main(String[] args) {
TimeRangeTest test = new TimeRangeTest();
int minutes = test.calculateTotalMinutes("30-11-2015 10:00",
"02-12-2015 15:00", "07:00", "22:00");
System.out.println(minutes + " minutes, " + (minutes / 60) + " hours");
}
public int calculateTotalMinutes(String startDateTimeString,
String endDateTimeString, String startTimeString,
String endTimeString) {
try {
List<TimeRange> timeRanges = generateTimeRanges(
startDateTimeString, endDateTimeString);
return calculateTimeRange(timeRanges, startTimeString,
endTimeString);
} catch (ParseException e) {
e.printStackTrace();
return 0;
}
}
private List<TimeRange> generateTimeRanges(String startDateTimeString,
String endDateTimeString) throws ParseException {
Date startDate = inputDateFormat.parse(startDateTimeString.substring(0,
10));
Time startTime = new Time(startDateTimeString.substring(11));
Date endDate = inputDateFormat
.parse(endDateTimeString.substring(0, 10));
Time endTime = new Time(endDateTimeString.substring(11));
List<TimeRange> timeRanges = new ArrayList<>();
Date currentDate = new Date(startDate.getTime());
Time currentTime = new Time(startTime);
Time eodTime = new Time("24:00");
while (currentDate.compareTo(endDate) < 0) {
TimeRange timeRange = new TimeRange(currentDate, currentTime,
eodTime);
timeRanges.add(timeRange);
currentTime = new Time("00:00");
currentDate = new Date(currentDate.getTime() + 24L * 60L * 60L
* 1000L);
}
TimeRange timeRange = new TimeRange(currentDate, currentTime, endTime);
timeRanges.add(timeRange);
return timeRanges;
}
private int calculateTimeRange(List<TimeRange> timeRanges,
String startTimeString, String endTimeString) {
int count = 0;
Time startTime = new Time(startTimeString);
Time endTime = new Time(endTimeString);
for (TimeRange timeRange : timeRanges) {
Time sodTime = new Time(timeRange.getStartTime());
Time eodTime = new Time(timeRange.getEndTime());
Time sTime = startTime.max(sodTime);
Time eTime = endTime.min(eodTime);
count += eTime.difference(sTime);
}
return count;
}
public class TimeRange {
private final SimpleDateFormat inputDateFormat = new SimpleDateFormat(
"dd-MM-yyyy");
private final Date date;
private final Time startTime;
private final Time endTime;
public TimeRange(Date date, Time startTime, Time endTime) {
this.date = date;
this.startTime = startTime;
this.endTime = endTime;
}
public Date getDate() {
return date;
}
public Time getStartTime() {
return startTime;
}
public Time getEndTime() {
return endTime;
}
#Override
public String toString() {
return inputDateFormat.format(getDate()) + " "
+ startTime.toString() + " -> " + endTime.toString();
}
}
public class Time {
private final int minutesPastMidnight;
public Time(String timeString) {
int hours = Integer.valueOf(timeString.substring(0, 2));
int minutes = Integer.valueOf(timeString.substring(3, 5));
this.minutesPastMidnight = hours * 60 + minutes;
}
public Time(Time time) {
this.minutesPastMidnight = time.getMinutesPastMidnight();
}
private int getMinutesPastMidnight() {
return minutesPastMidnight;
}
public int difference(Time time) {
return this.getMinutesPastMidnight()
- time.getMinutesPastMidnight();
}
public Time min(Time time) {
return (difference(time) > 0) ? time : this;
}
public Time max(Time time) {
return (difference(time) > 0) ? this : time;
}
#Override
public String toString() {
int hours = minutesPastMidnight / 60;
int minutes = minutesPastMidnight - (hours * 60);
return String.format("%02d:%02d", hours, minutes);
}
}
}
If you use java8, you can use LocalDateTime. Then your code could looks like this:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
LocalDateTime dateTimeStart = LocalDateTime.parse("2015-10-01 10:00", formatter);
LocalDateTime dateTimeEnd = LocalDateTime.parse("2015-10-02 10:00", formatter);
long seconds = Duration.between(dateTimeStart, dateTimeEnd).getSeconds();
Or LocalTime if you have only time. Then it could looks like this:
LocalTime timeStart = LocalTime.parse("07:00");
LocalTime timeEnd = LocalTime.parse("22:00");
long seconds = Duration.between(timeStart, timeEnd).getSeconds();
If you can't use java8, you can get the number of milliseconds since 1970-01-01 00:00:00 to your date using getTime() method and do simple subtraction operation, like this:
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
Date dateStart = simpleDateFormat.parse("2015-10-01 10:00");
Date dateEnd = simpleDateFormat.parse("2015-10-02 10:00");
long milliseconds = dateEnd.getTime() - dateStart.getTime();
long seconds = resultInMillisecond / 1000;

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
}

Find the number of months and day between date range

I have a start date and end date in database like below.
start date:01/06/2014 end date:30/06/2014
start date:01/07/2014 end date:30/09/2014
start date:01/10/2014 end date:31/03/2015
if i enter the date range
start date 02/06/2014 end date 01/02/2015
the output has to be.
28 days, in 1st slab date range
2 months, 29 days, in 2nd slab date range
4 months in 3rd slab date range
how to achieve this in java.
Thanks in advance.
This question is difficult to answer accurately. I believe this is what you really want,
// get the minimum of any number of dates.
private static Date getMinimum(Date... dates) {
if (dates == null)
return null;
Date min = dates[0];
for (Date d : dates) {
if (d.compareTo(min) < 0) {
min = d;
}
}
return min;
}
// get the maximum of any number of dates.
private static Date getMaximum(Date... dates) {
if (dates == null)
return null;
Date max = dates[0];
for (Date d : dates) {
if (d.compareTo(max) > 0) {
max = d;
}
}
return max;
}
public static String getDateDiff(Date startDate,
Date endDate) {
StringBuilder sb = new StringBuilder();
Calendar start = Calendar.getInstance();
start.setTime(getMinimum(startDate, endDate));
Calendar end = Calendar.getInstance();
end.setTime(getMaximum(startDate, endDate));
if (start.compareTo(end) < 0) {
int monthCount = 0;
int dayCount = 0;
while (start.compareTo(end) < 0) {
start.add(Calendar.MONTH, 1);
if (start.compareTo(end) < 0) {
monthCount++;
}
}
start = Calendar.getInstance();
start.setTime(getMinimum(startDate, endDate));
start.add(Calendar.MONTH, monthCount);
while (start.compareTo(end) < 0) {
start.add(Calendar.DAY_OF_MONTH, 1);
if (start.compareTo(end) < 0) {
dayCount++;
}
}
if (monthCount > 0) {
sb.append(String.format("%d months",
monthCount));
}
if (dayCount > 0) {
if (sb.length() > 0) {
sb.append(", ");
}
sb.append(String.format("%d days", dayCount));
}
} else {
sb.append("0 days");
}
return sb.toString();
}
public static void main(String[] args) {
String[] input = { "01/06/2014-30/06/2014", //
"01/07/2014-30/09/2014", //
"01/10/2014-31/03/2015", //
"02/06/2014-01/02/2015", };
DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
for (String str : input) {
String sArr[] = str.split("-");
try {
Date start = df.parse(sArr[0]);
Date end = df.parse(sArr[1]);
System.out.printf("start: %s, end: %s - diff: %s\n", sArr[0],
sArr[1], getDateDiff(start, end));
} catch (ParseException e) {
e.printStackTrace();
}
}
}
The output is
start: 01/06/2014, end: 30/06/2014 - diff: 28 days
start: 01/07/2014, end: 30/09/2014 - diff: 2 months, 28 days
start: 01/10/2014, end: 31/03/2015 - diff: 5 months, 29 days
start: 02/06/2014, end: 01/02/2015 - diff: 7 months, 29 days
Please check whether below code is helpful. I am using this.
public String getDifference(Date date1, Date date2){
long difference = date2.getTime() - date1.getTime();
long diffDays = difference / (24 * 60 * 60 * 1000);
return (diffDays/30)+" months and "+(diffDays%30)+" days";
}
public int monthsBetweenDates(Date startDate, Date endDate){
Calendar start = Calendar.getInstance();
start.setTime(startDate);
Calendar end = Calendar.getInstance();
end.setTime(endDate);
int monthsBetween = 0;
int dateDiff = end.get(Calendar.DAY_OF_MONTH)-start.get(Calendar.DAY_OF_MONTH);
if(dateDiff<0) {
int borrrow = end.getActualMaximum(Calendar.DAY_OF_MONTH);
dateDiff = (end.get(Calendar.DAY_OF_MONTH)+borrrow)-start.get(Calendar.DAY_OF_MONTH);
monthsBetween--;
if(dateDiff>0) {
monthsBetween++;
}
}
else {
monthsBetween++;
}
monthsBetween += end.get(Calendar.MONTH)-start.get(Calendar.MONTH);
monthsBetween += (end.get(Calendar.YEAR)-start.get(Calendar.YEAR))*12;
return monthsBetween;
}

Categories

Resources