Days difference between local date objects - android

LocalDate today=LocalDate.now();
And the event date is:
eventDate=LocalDate.of(year, monthOfYear,dayOfMonth); (from the date picker dialog)
I'm trying to calculate the days difference between them... The shortest thing I have found is this:
int DaysDifference = Period.between(eventToDisplay.getEventDate(),today).getDays();
While the first object is "today", and the second one is "eventToDisplay.getEventDate()." It didn't work for me, it showed the wrong number of days.
I have also tried to do it like this:
eventToDisplay.getEventDate().compareTo(today)
Also didn't work...
I have also tried to do it without joda-time, because I had troubles with it, because of what I'm trying to do with date and time...
The other things I have found are long and complicated, and I thought maybe there is a better way, without the joda-time.
EDIT:
I have just tried this:
Calendar now = Calendar.getInstance();
Calendar chosenDate=Calendar.getInstance();
chosenDate.set(eventToDisplay.getEventDate().getYear(),eventToDisplay.getEventDate().getMonth().getValue(),eventToDisplay.getEventDate().getDayOfMonth());
long def= chosenDate.getTimeInMillis() - now.getTimeInMillis();
long DaysDifference =TimeUnit.MILLISECONDS.toDays(def);
Didn't work for me
EDIT:
This has worked for me:
LocalDate today=LocalDate.now();
Calendar now = Calendar.getInstance();
now.set(today.getYear(),today.getMonthValue(),today.getDayOfMonth());
Calendar chosenDate=Calendar.getInstance();
chosenDate.set(eventToDisplay.getEventDate().getYear(),eventToDisplay.getEventDate().getMonthValue(),eventToDisplay.getEventDate().getDayOfMonth());
long def= chosenDate.getTimeInMillis() - now.getTimeInMillis();
long daysDifference =TimeUnit.MILLISECONDS.toDays(def);

you can use something like this:
Calendar now = Calendar.getInstance();
Calendar end=Calendar.getInstance();
end.set(<year>, <month>, <day>);
long def= end.getTimeInMillis() - now.getTimeInMillis();
long days =TimeUnit.MILLISECONDS.toDays(def);

java.time
Since you can use LocalDate from java.time, the modern Java date and time API, I warmly recommend that you stick to java.time. Calculating the difference is simple and straightforward when you know how:
LocalDate today = LocalDate.now(ZoneId.systemDefault());
LocalDate eventDate = LocalDate.of(2021, 5, 5);
long differenceDays = ChronoUnit.DAYS.between(today, eventDate);
System.out.println("Difference is " + differenceDays + " days.");
Output when I ran today (APril 18 in my tme zone):
Difference is 17 days.
If your date picker uses 0-based months (some date pickers insanely use 0 for January through 11 for December), remember to add 1 to the month number before passing it to LocalDate.
What went wrong in all your attempts?
int DaysDifference = Period.between(eventToDisplay.getEventDate(),today).getDays();
The Period class represents a period of years, months and days. Since months have different lengths, a Period does not correspond to any exact number of days, so it’s not the right class to use here. You tried to use its getDays method, which gives you the days component of the period, not the months or the years. So if the two days are less than a month apart, you will get the correct result, otherwise not. If for example the two dates are 1 month 3 days apart, you will only get the 3 days.
The Calendar class used in more than one of your attempts is poorly designed and long outdated. Counting days correctly with it would be truly cumbersome, so no wonder that your attempts gave the wrong results.
Both of your attempts are wrong for at least two reasons:
A Calendar has a date and a time of day. So by finding the difference in milliseconds and dividing by the number of milliseconds that you think are in a day, you will get different results depending on the time of day that happens to be in each of your Calendar objects. Your code calls Calendar.getInstance() twice. In an extreme situation your code may run across midnight so the time in the first Calendar will be close to 23:59:59 and in the second close to 00:00, which will almost certainly give you an error of 1 day.
A day is not always 24 hours. Summer time (DST) is the most frequent but not the only reason why a date is sometimes 23 hours, 25 hours or some other length. If for example you try to count days across the spring forward where a day is only 23 hours or 23 hours 30 minutes, your code will count 1 day too few.
Furthermore this line from the snippet that you say that works is definitely wrong:
now.set(today.getYear(),today.getMonthValue(),today.getDayOfMonth());
You are using the 1-based month number from LocalDate, for example 4 for April, as a 0-based month number in Calendar, for example 4 would mean May. So your Calendar is off by 1 month. Since I haven’t got your complete code, is may in some cases balance out by another error that causes the other Calendar to be 1 month off too, I cannot know. Since months have different lengths, you will still get an error of up to 3 days sometimes.

Related

How to convert a timestamp to years, month, days and hours in Android?

I want to convert a timestamp like 62207486144 to days(like 1 year 6 months 2 days 3 hours 33 minutes) in my Android App. How can I do that? I am able to get days and hours but not years or months with the following code-
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(62207486144);
GregorianCalendar gregorianCalendar = new GregorianCalendar();
gregorianCalendar.setTime(calendar.getTime());
long timestamp = 62207486144;
long days = TimeUnit.MILLISECONDS.toDays(timestamp );
timestamp -= TimeUnit.DAYS.toMillis(days);
long hours = TimeUnit.MILLISECONDS.toHours(timestamp );
Years- divide days by 365 (or 365.25 if you want to account for leap years). Months- well, months aren't exact because months aren't the same length, but dividing by 30 is going to be about right.
Your code above is a bit odd though. The first 4 lines are doing something totally different than the last 4. The first 4 would get you data about a specific time in a timestamp- you'd use that if you wanted to figure out for a timestamp what day/month/year it was. The last 4 treat it as a duration. You'd use that for figuring out how long something took. My suggestion above works for durations. If you want to know when a particular timestamp was instead, you'd just use the calendar object to tell you that.
check this out, as an easy way to convert to localDateTime.
From there, it should be way easier.
long millis = 62207486144L;
LocalDateTime date = Instant.ofEpochMilli(millis).atZone(ZoneId.systemDefault()).toLocalDateTime();
date.getDayOfMonth(); //Day
date.getMonthValue(); //Month
date.getYear(); //Year
More information here: https://howtoprogram.xyz/2017/02/11/convert-milliseconds-localdatetime-java/

getRelativeTimeSpanString() is returning the start date, instead of time ago

I am trying to calculate the time between two dates and show the difference in time in the UI as x mins ago, x days ago, x weeks ago etc (depending on the length of time).
The first date is a published date which is given to me by the api. I then format this date to yyyy-MM-dd HH:mm:ss. Second date is the current time.
val sdf = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
sdf.setTimeZone(TimeZone.getTimeZone("GMT"))
val time = sdf.parse("$year-$month-$day $hours").time // 2019-03-14 13:00:55
val now = System.currentTimeMillis()
val relative = DateUtils.getRelativeTimeSpanString(time, now, 0L, DateUtils.FORMAT_ABBREV_ALL)
However, when I print relative, I get Mar 14 when I would expect x months ago.
Can't tell what I'm missing apart from I have read somewhere that getRelativeTimeSpanString() only works for 7 days, but the documentation doesn't state this so not sure if that's the case?
Any help to solve this would be appreciated!
It's a feature.
You have minimum resolution of 0 milliseconds and hence the time is printed exactly. It doesn't make sense to have output like "16 weeks ago 13:00:55".
You could change the minimum resolution to DateUtils.WEEK_IN_MILLIS to get output like "16 weeks ago".
There's also another DateUtils method that allows you to specify the transition resolution:
the elapsed time (in milliseconds) at which to stop reporting relative measurements. Elapsed times greater than this resolution will default to normal date formatting. For example, will transition from "7 days ago" to "Dec 12" when using WEEK_IN_MILLIS
In theory that would work, but in practice it is capped at WEEK_IN_MILLIS.
Under the hood, it's RelativeDateTimeFormatter doing the work and you can learn more by inspecting its source.
If you really need "months ago" resolution, forget about DateUtils and roll your own implementation. For example with java.time / ThreeTenBP APIs: https://stackoverflow.com/a/56450659/101361

Wrong data return from calender

I am trying to retrieve the number of week in a month.. actually today is the second week in november but I am getting it as 3
The code I am using is
Log.e("dfhkdjfk", Calendar.getInstance().get(Calendar.WEEK_OF_MONTH)+"");
please help me to figure it out.
Reference Time:
3:45 AM
Monday, November 9, 2015
Coordinated Universal Time (UTC)
Wrong.
For some country like France where Monday is the first day of the week, today is really the first day of the third week of November, as the first of november was a Sunday ( so the first week of november had one day... ).
You might use DAY_OF_WEEK_IN_MONTH which give you the number of time a day already happened starting from the beginning of the current month.
Otherwise check which day is considered as the first of the week and implement some logic to adapt it to your need.
You need to try below code with TimeZone which give correct Calendar.WEEK_OF_MONTH
Calendar calUs = Calendar.getInstance(TimeZone.getTimeZone("US/Eastern"), Locale.US);
int weekOfMonthUs = calUs.get(Calendar.WEEK_OF_MONTH);
System.out.println("Week of month is " + weekOfMonthUs);
O/P
Week of month is the week within the current month starting from Sunday to how many weeks have there been.
WEEK_OF_MONTH depends on the first day of the week. Not all calendars have Sunday has beginning of the week. For ex: France has Monday as first day of the week. So Before getting into this check the locale of the phone.

Convert jodatime period to days

Actually I'm trying to use the joda time library to manipulate dates. It seems preety good, but I've found a non-plus-ultra wall.
I have a jodatime period that I want to converto to days.
So, if my period has 1 year, 1 month, 1 week and 1 day, total should be:
365 + 30 (or 30 or 28 or 29) + 7 + 1 = 403 days aprox.
But, If I try
int total= myPeriod.edadHombre.toStandardDays().getDays();
...it throws an exception. What I'm doing wrong? Is "toStandardDays" the right way to obtain the total amount of days in a jodatime period?
While I try to understand why doesn't work, I've found another way to do it:
//I take a date (myDate) to create a start point and an end date:
DateTime startDate =new DateTime(myDate);
DateTime endDate = new DateTime(); //now()
Days someDays= Days.daysBetween(startDate, endDate);
int result=someDays.getDays();
That's all. Anyway, I hope that somebody give me an answer about toStandardDays...

Android how to map every next monday and thursday, 6 pm for the next four weeks to actual dates?

My app's user enters a few days from the week, and a few times a day when they need to get notified about something.
So in the SQLite DB I have the following information:
days of the week the alarm should go off
hours and minutes of the day the alarm should go off (might be a few times a day)
number of weeks
Now, how do I get this information and map it to a list of real dates, like June 2nd, 2014 15:30 for example?
Also, for the current week, all the reminders that are already passed, should be moved to the end of the queue.
Then you have to calculate date by yourself.
Assume 7 day a week.
For example : Tuesday in next 3 weeks
--> target day should be 7 x 2 + 2
Use Calendar object, they have method called add(field , value)
Prototype code for above sample:
Calendar c = Calendar.getInstance();
c.add(Calendar.DAY, 7x2 + 2);
Date date = c.getTime();
then your need object is date
Save this in miliseconds to db and use it later. Done :)

Categories

Resources