local time parser doesnt work [java] - java

Beneath the question I have put my code.For some reason it can't parse 6:00 and 17:30 to localtime and then put it as boolean in the ifstatetement, if it is before 6:00 put the values in the nachtMap, if it is after 17:30 , put it as well in the NachtMap, otherwise in Daymap (its basically all in the for loop).
Any one who knows whats wron with my code?
// for each license plate
for (int i = 1, n = licenseplateList.size(); i < n; i++) {
//first look at whether it is considered as day or night time
try {
String time1Str = begintimeList.get(i);
String time2Str = endingtimeList.get(i);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm");
LocalTime time1 = LocalTime.parse(time1Str, formatter);
LocalTime time2 = LocalTime.parse(time2Str, formatter);
// add date value: start with today
LocalDate today = LocalDate.now();
// lower value will be assigned to today
LocalDateTime dateTime1 = LocalDateTime.of(today, time1);
// upper value will be assigned same day if it is after lower value
// otherwise (we crossed date boundary) assign it to tomorrow
LocalDateTime dateTime2 = time2.isAfter(time1) ?
LocalDateTime.of(today, time2) : LocalDateTime.of(today.plusDays(1), time2);
Duration duration = Duration.between(dateTime1, dateTime2);
Duration halfDuration = duration.dividedBy(2);
LocalTime result = LocalTime.from(halfDuration.addTo(time1));
System.out.println(result.format(formatter));
LocalTime calc = LocalTime.parse("6:00");
LocalTime calc2 = LocalTime.parse("17:30");
boolean before = result.format(formatter).before(calc);
boolean after = result.format(formatter).after(calc2);
if (before == true) {
nachtMap.put(licenseplateList.get(i), kmperlineList.get(i));
}
else {
if(after == true) {
nachtMap.put(licenseplateList.get(i), kmperlineList.get(i));
}
else {
dagMap.put(licenseplateList.get(i), kmperlineList.get(i));
}
}
}catch (Exception e) {
}

Perhaps you should use H:mm instead of HH:mm, it can parse both 06:00 and 6:00
#Test
public void test() {
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("H:mm");
Assert.assertEquals(
LocalTime.parse("6:00", formatter),
LocalTime.parse("06:00", formatter)
);
}

Related

Counting number of days of a particular month when given a duration

A duration is given.
Ex: Jan 15-March 15
I want to count the number of days which belongs to each month, in that given duration.
In this example,
number of days of January in that duration; 15
number of days of February in that duration; 28
number of days of March in that duration; 15
I'm looking for a solution other that traversing through each date of the duration and checking if Date.getMonth() = "Month I want to check against"
Is there an easier way of doing this using methods in Java Date or Java SQL Date or using any other Date type?
Map < YearMonth , Long > with lambda syntax
Here is a solution using a bit of terse code using streams and lambdas. While this solution does traverse each date of the time range, the simplicity and clarity of the code may outweigh that inefficiency.
Use LocalDate for the starting and stopping date. Use YearMonth to track each month.
LocalDate start = LocalDate.of( 2019 , 1 , 15 );
LocalDate stop = LocalDate.of( 2019 , 3 , 16 );
Make a Map to keep a number of days for each month.
Map < YearMonth, Long > map =
start
.datesUntil( stop )
.collect(
Collectors.groupingBy(
( LocalDate localDate ) -> YearMonth.from( localDate ) ,
TreeMap::new ,
Collectors.counting()
)
);
Dump to console.
{2019-01=17, 2019-02=28, 2019-03=15}
System.out.println( map );
Given a starting date, LocalDate::datesUntil provides a Stream of LocalDate objects, incremented by days.
Then just do a grouping into a SortedMap (a TreeMap) to keep months in chronological order, classified by the YearMonth and counting the days for that month in the range.
If you want the total days you can just do
long totalDays = d.datesUntil(LocalDate.of(2019, 3, 16)).count();
This is just a simple example I threw together with some basic research.
LocalDate from = LocalDate.of(2019, Month.JANUARY, 15);
LocalDate to = LocalDate.of(2019, Month.MARCH, 15);
DateTimeFormatter monthFormatter = DateTimeFormatter.ofPattern("MMM");
LocalDate date = from;
while (date.isBefore(to)) {
LocalDate endOfMonth = date.withDayOfMonth(date.lengthOfMonth());
if (endOfMonth.isAfter(to)) {
endOfMonth = to;
}
// Inclusive to exclusive comparison
long days = ChronoUnit.DAYS.between(date, endOfMonth.plusDays(1));
System.out.println(days + " days in " + date.format(monthFormatter));
date = date.plusMonths(1).withDayOfMonth(1);
}
This will output
17 days in Jan.
28 days in Feb.
15 days in Mar.
There are probably better ways to achieve the same result, but as I said, I just threw it together with a little bit of Googling and trial and error.
As has already been stated, you should avoid using the older, out-of-date and effectively deprecated Date, Calendar and associated classes.
Try this. May be something like this you want. So it set a startdate and enddate, then loop for each moth till the end date and calculate the day count. I have not tested it thoroughly, but should be close to your concept.
public static void main(String[] args) throws ParseException {
String startDateS = "01/15/2019";
String endDateS = "03/15/2019";
SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
Date startDate = dateFormat.parse(startDateS);
Date endDate = dateFormat.parse(endDateS);
while (endDate.compareTo(startDate) > 0) {
Calendar c = Calendar.getInstance();
c.setTime(startDate);
c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
Date endOfMonth = c.getTime();
if( endDate.compareTo(endOfMonth) > 0 )
System.out.println("Count Month " + getMonthForInt(c.get(Calendar.MONTH)) + " " + getDifferenceDays(startDate, endOfMonth));
else
System.out.println("Count Month " + getMonthForInt(c.get(Calendar.MONTH)) + " " + getDifferenceDays(startDate, endDate));
c.add(Calendar.DAY_OF_MONTH, 1);
startDate = c.getTime();
}
}
static String getMonthForInt(int num) {
String month = "wrong";
DateFormatSymbols dfs = new DateFormatSymbols();
String[] months = dfs.getMonths();
if (num >= 0 && num <= 11) {
month = months[num];
}
return month;
}
public static int getDifferenceDays(Date d1, Date d2) {
int daysdiff = 0;
long diff = d2.getTime() - d1.getTime();
long diffDays = diff / (24 * 60 * 60 * 1000) + 1;
daysdiff = (int) diffDays;
return daysdiff;
}
You can do the same using Java.time in Java 8.
public static void main(String[] args) throws ParseException {
String startDateS = "01/15/2019";
String endDateS = "03/15/2019";
DateTimeFormatter format1 = DateTimeFormatter.ofPattern("MM/dd/yyyy");
LocalDate startDate = LocalDate.parse(startDateS, format1);
LocalDate endDate = LocalDate.parse(endDateS, format1);
while (endDate.compareTo(startDate) > 0) {
LocalDate endOfMonth = startDate.minusDays(startDate.getDayOfMonth()).plusMonths(1);
if( endDate.compareTo(endOfMonth) > 0 )
System.out.println("Count Month " + getMonthForInt(startDate) + " " + getDifferenceDays(startDate, endOfMonth));
else
System.out.println("Count Month " + getMonthForInt(startDate) + " " + getDifferenceDays(startDate, endDate));
startDate = endOfMonth.plusDays(1);
}
}
static String getMonthForInt(LocalDate startDate) {
return startDate.getMonth().getDisplayName(
TextStyle.FULL ,
Locale.US
);
}
public static long getDifferenceDays(LocalDate d1, LocalDate d2) {
// return Duration.between(d2.atStartOfDay(), d1.atStartOfDay()).toDays();
return ChronoUnit.DAYS.between(d1, d2) + 1;
}

How to generate list of dates taking into consideration the month of startDate and endDate when they fall in different month?

Assuming i have startDate, endDate,currentDate
1. I want to ignore instance where startDate and endDate fall outside of currentDate month.
2. When startDate and currentDate are of the same month but endDate has a month greater than currentDate, then create a list between startDate to end day of startDates month.
3. When endDate is of the same month as currentDate and startDate is less than currentDate month, then create a list between endDate and first day of currentDate
I would like some help with a method to handle this.
Thank You
First lets make a method that creates a sequence of dates given a start and stop date. This method makes use of plusDays in LocalDate to generate dates in a while loop.
public static List<LocalDate> makeDateInterval(LocalDate startDate, LocalDate endDate) {
List<LocalDate> list = new ArrayList<>();
if (startDate.isAfter(endDate)) {
return list;
}
LocalDate nextDate = startDate;
while (nextDate.isBefore(endDate)) {
list.add(nextDate);
nextDate = nextDate.plusDays(1);
}
list.add(endDate);
return list;
}
To sort out what the start and stop date is we need a simple logic to compare the months of the given dates and if we have a valid interval we call the above method
public static List<LocalDate> buildDateRange(LocalDate startDate, LocalDate endDate, LocalDate currentDate) {
LocalDate firstDate = null;
LocalDate secondDate = null;
if (startDate.getMonth() == currentDate.getMonth()) {
firstDate = startDate;
secondDate = currentDate;
}
if (endDate.getMonth() == currentDate.getMonth()) {
secondDate = endDate;
if (firstDate == null) {
firstDate = currentDate;
}
}
if (firstDate == null || secondDate == null) {
return new ArrayList<>(); //No valid interval, return empty list
}
return makeDateInterval(firstDate, secondDate);
}
A simple test today February 1st
public static void main(String[] args) {
LocalDate now = LocalDate.now();
LocalDate start = now.minusDays(5);
LocalDate end = now.plusDays(5);
System.out.println("Now: " + now + ", start: " + start + ", end: " +end);
List<LocalDate> list = buildDateRange(start, end, now);
for (LocalDate d : list) {
System.out.println(d);
}
}
generates the following output
Now: 2019-02-01, start: 2019-01-27, end: 2019-02-06
2019-02-01
2019-02-02
2019-02-03
2019-02-04
2019-02-05
2019-02-06

Determine how many time a Day occurs between two days in Java

I need to calculate how many times a Day occurs between two dates, which can be weekly or monthly.
Eg Monthly:
StartDate : 2019/01/29
EndDate: 2019/03/28
So considering the above example, the output should be 1, as this is not a leap year, Feb(28) days, also it ends on March 28.
int recordCountMonths = (int) ChronoUnit.MONTHS.between(scheduleStartDate, scheduleEndDate);
int recordCountWeeks = (int) ChronoUnit.WEEKS.between(scheduleStartDate, scheduleEndDate);
Exmaple 1
The Months implementation gives me 2 (it should return 3, considering leap year) if my date is between:
LocalDate startDate = LocalDate.of(2020, Month.JANUARY, 29);
LocalDate endDate = LocalDate.of(2020, Month.APRIL, 28);
Example2:
The Months implementation gives me 3 (it should return 2, considering 31 occurs in Jan and March only) if my date is between:
LocalDate startDate = LocalDate.of(2019, Month.JANUARY, 31);
LocalDate endDate = LocalDate.of(2019, Month.MAY, 28);
Also, the above count can be asked to calculate weekly too. In that case the count will be more. However, lets not focus on weekly for now.
I can't think of a simple way to do this.
I have tried different ways, but that gives me inaccurate results.
As promised, here's a method to solve your problem. It could be better but this should work well enough. You can make similar counting methods for other specific cases, like whatever you wanted to do with weeks.
/**
* Returns the count of the day of the start day of the month between start and end inclusively.
*/
public static int getCountOfDayOfMonthBetween(LocalDate start, LocalDate end) {
// the target day of the month to count
final int dom = start.getDayOfMonth();
// 'start' is counted as a valid day
int count = 1;
LocalDate currDate = start.plusMonths(1);
while (!currDate.isAfter(end)) {
try {
currDate = currDate.withDayOfMonth(dom);
// day of month changed, so check that the date is still valid
if (currDate.isAfter(end)) {
return count;
} else {
count++;
}
} catch (DateTimeException e) {
}
currDate = currDate.plusMonths(1);
}
return count;
}
public static void main(String[] args) {
LocalDate start1 = LocalDate.of(2020, Month.JANUARY, 29);
LocalDate end1 = LocalDate.of(2020, Month.APRIL, 28);
System.out.println(getCountOfDayOfMonthBetween(start1, end1)); // 3
LocalDate start2 = LocalDate.of(2019, Month.JANUARY, 31);
LocalDate end2 = LocalDate.of(2019, Month.MAY, 28);
System.out.println(getCountOfDayOfMonthBetween(start2, end2)); // 2
}
private int getCountOfDayOfMonthBetween(int dayOfMonth, LocalDate scheduleStartDate, LocalDate scheduleEndDate) {
if(scheduleEndDate == null) {
return -1;
}
LocalDate currDate = scheduleStartDate.withDayOfMonth(dayOfMonth);
LocalDate convertedDate = scheduleStartDate.withDayOfMonth(
scheduleStartDate.getMonth().length(scheduleStartDate.isLeapYear()));
int recordCount = 0;
while (currDate.isBefore(scheduleEndDate)) {
if(convertedDate.getDayOfMonth() >= scheduleStartDate.getDayOfMonth()) {
recordCount++;
}
currDate = currDate.plusMonths(1);
convertedDate = convertedDate.plusMonths(1);
convertedDate = convertedDate.withDayOfMonth(
convertedDate.getMonth().length(convertedDate.isLeapYear()));
}
return recordCount;
}

How can I check if it is between 2pm and 1am new york time?

I need to check if the time in new york time zone is between 2pm and 1 am but i am not sure how to select the timezone or what to do next
String string1 = "14:00:00";
Date time1 = new SimpleDateFormat("HH:mm:ss").parse(string1);
Calendar calendar1 = Calendar.getInstance();
calendar1.setTime(time1);
String string2 = "01:00:00";
Date time2 = new SimpleDateFormat("HH:mm:ss").parse(string2);
Calendar calendar2 = Calendar.getInstance();
calendar2.setTime(time2);
calendar2.add(Calendar.DATE, 1);
If you're interested in whether the current time is "after or equal to 2pm, or before 1am" then don't need to use string parsing at all. You could use:
TimeZone zone = TimeZone.getTimeZone("America/New_York");
Calendar calendar = new GregorianCalendar(zone);
int hour = calendar.get(Calendar.HOUR_OF_DAY);
if (hour < 1 || hour >= 14) {
...
}
That's assuming you do want it to match 3pm, but you don't want it to match 8am, for example. That's "between 2pm and 1am" in my view, as per your title.
If you're using Java 8, I'd suggest using LocalTime instead, via ZonedDateTime:
private static final LocalTime EARLY_CUTOFF = LocalTime.of(1, 0);
private static final LocalTime LATE_CUTOFF = LocalTime.of(14, 0);
ZoneId zone = ZoneId.of("America/New_York");
LocalTime time = ZonedDateTime.now(zone).toLocalTime();
if (time.compareTo(EARLY_CUTOFF) < 0 && time.compareTo(LATE_CUTOFF) >= 0) {
...
}
Calendar calNewYork = Calendar.getInstance();
calNewYork.setTimeZone(TimeZone.getTimeZone("America/New_York"));
int curr_hour = calNewYork.get(Calendar.HOUR_OF_DAY);
System.out.println(curr_hour < 1 || curr_hour >= 14);

How to get hour/minute difference in java

I have to get total minutes between two hour.
17:00 and 16.06 hrs
If I do like
17.00-16.06 =0.94
but correct answer is 54 minutes.
so logically how can I get difference minutes from two time.
without using Calender api or Joda Time.
Code:
private double getTimeDifference(Date startDate,Date endDate, boolean sameDay)
{
double startTimeF=Double.valueOf(startDate.getHours()+"."+startDate.getMinutes());
double endTimeF=Double.valueOf(endDate.getHours()+"."+endDate.getMinutes());
double totalTime=0;
boolean isCalculated=false;
for(double workTime:timeMap.keySet())
{
double endTimeC=timeMap.get(workTime);
if(startTimeF>=workTime && startTimeF<=endTimeC)
{
if(endTimeF<endTimeC && sameDay)
{
isCalculated=true;
totalTime+=endTimeF-startTimeF;
}
else
{
totalTime+=endTimeC-startTimeF;
}
break;
}
}
for(double workTime:timeMap.keySet())
{
double endTimeC=timeMap.get(workTime);
if(endTimeF>=workTime && endTimeF<=endTimeC)
{
if(!isCalculated)
{
if(workTime<startTimeF && sameDay)
{
totalTime+=endTimeF-startTimeF;
}
else
{
totalTime+=endTimeF-workTime;
}
}
}
else if(!sameDay)
{
totalTime+=endTimeC-workTime;
}
}
return totalTime;
}
Time map contains key and value of json string:
{"time":[{"startTime":"8:00", "endTime":"12:30", "type":"Working"},{"startTime":"12:31", "endTime":"13:00", "type":"Break"},{"startTime":"13:01", "endTime":"17:00", "type":"Working"}]}
long milliDifference = date1.getTime() - date2.getTime();
long minuteDifference = TimeUnit.MINUTES.convert(milliDifference, TimeUnit.MILLISECONDS);
where date1 and date2 are of type java.util.Date.
Try:
String from="17:00";
String to="16:06";
String fromTime[]=from.split(":");
String toTime[]=to.split(":");
int fromMin=Integer.parseInt(fromTime[0])*60+Integer.parseInt(fromTime[1]);
int toMin=Integer.parseInt(toTime[0])*60+Integer.parseInt(toTime[1]);
System.out.println("Difference "+(fromMin-toMin)+" minutes");
String firstTime = "17:00";
String secondTime = "16:09";
SimpleDateFormat format = new SimpleDateFormat("HH:mm");
try {
long diff = format.parse(firstTime).getTime() - format.parse(secondTime).getTime();
System.out.println("Difference is " + (diff / (60 * 1000)) + " minutes.");
} catch (ParseException e) {
//Parsing error
}
Output:
Difference is 51 minutes.
tl;dr
Duration.between( LocalTime.parse( "17:00" ) , LocalTime.parse( "16:06" ) )
java.time
The troublesome old legacy date-time classes are now supplanted by the java.time classes.
The LocalTime class represents a time-of-day without a date and without a time zone.
The Duration class tracks a span of time not attached to the timeline. Your example of 17:00 and 16:06 means a negative duration, going into the past.
LocalTime start = LocalTime.parse( "17:00" );
LocalTime stop = LocalTime.parse( "16:06" ); // Going backwards into the past for a negative duration.
Duration duration = Duration.between( start , stop );

Categories

Resources