Calculate Years and Months between Two Dates in Android - java

I am trying to display a custom text result between two dates. Here is the code in my Fragment, which return two dates:
public class HomeFragment extends BaseFragment {
...
dashboardViewModel.productCategory.observe(this, data - > {
if (data != null && data.getData() != null) {
int totalLos = Integer.parseInt(data.getData().getLos());
Log.e("totalLOS", String.valueOf(totalLos));
explainDays(totalLos);
mBinding.los.setText("");
}
});
}
And here the code in BaseFragment which generate two dates:
public abstract class BaseFragment extends Fragment {
...
public void explainDays(int totalDays) {
Calendar calendar = Calendar.getInstance();
Date start = calendar.getTime();
calendar.add(Calendar.DATE, -totalDays);
Date end = calendar.getTime();
Log.e("startDate", String.valueOf(start));
Log.e("endDate", String.valueOf(end));
}
}
From the code above, I am getting these three logs:
E/totalLOS: 1233
E/startDate: Mon Jun 08 19:45:08 GMT+07:00 2020
E/endDate: Sun Jan 22 19:45:08 GMT+07:00 2017
How do I generate a response like for example 1 Year and 5 Months since 2007 between these two date results? the since 2007 needs to be extracted from endDate from Log above.
Any help will be much appreciated.
Thank you.

java.time
You can do it as follows:
import java.time.OffsetDateTime;
import java.time.Period;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
// Define format
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss O yyyy");
// Date/time strings
String strEndDate = "Mon Jun 08 19:45:08 GMT+07:00 2020";
String strStartDate = "Sun Jan 22 19:45:08 GMT+07:00 2017";
// Define ZoneOffset
ZoneOffset zoneOffset = ZoneOffset.ofHours(6);
// Parse date/time strings into OffsetDateTime
OffsetDateTime startDate = OffsetDateTime.parse(strStartDate, formatter).withOffsetSameLocal(zoneOffset);
OffsetDateTime endDate = OffsetDateTime.parse(strEndDate, formatter).withOffsetSameLocal(zoneOffset);
// Calculate period between `startDate` and `endDate`
Period period = Period.between(startDate.toLocalDate(), endDate.toLocalDate());
// Display result
System.out.println(
period.getYears() + " years and " + period.getMonths() + " months since " + startDate.getYear());
}
}
Output:
3 years and 4 months since 2017
Note: Instead of using the outdated java.util.Date and SimpleDateFormat, use the modern date/time API. Check this to learn more about it.
Note: The following content has been copied from How to get start time and end time of a day in another timezone in Android
Question: Doesn’t java.time require Android API level 26?
java.time works nicely on both older and newer Android devices. It just requires at least Java 6.
In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
In non-Android Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from org.threeten.bp with subpackages.
But don't we have any other option apart from switching to ThreeTenBP
Library?
If you insisted, I suppose that a way through using Calendar, Date and SimpleDateFormat could be found. Those classes are poorly designed and long outdated, so with what I know and don’t know I would prefer ThreeTenABP.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Java Specification Request (JSR) 310, where java.time was first described.
ThreeTen Backport project, the backport of java.time to Java 6 and 7 (ThreeTen for JSR-310).
ThreeTenABP, Android edition of ThreeTen Backport
Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
Wikipedia article: ISO 8601

If you can extract the month,day and year from both dates you can use following solution to calculate the exact difference between two dates.
int sday=22 //int day of month here
int smonth=1 //int month here
int syear=2017 //int year here
int eday=5 //int day of month here
int emonth=6 //int month here
int eyear=2020 //int year here
resyear = eyear - syear;
if (emonth >= smonth) {
resmonth = emonth - smonth;
} else {
resmonth = emonth - smonth;
resmonth = 12 + resmonth;
resyear--;
}
if (eday >= sday) {
resday = eday - sday;
} else {
resday = eday - sday;
resday = 31 + resday;
if (resmonth == 0) {
resmonth = 11;
resyear--;
} else {
resmonth--;
}
}
if (resday <0 || resmonth<0 || resyear<0) {
Toast.makeText(getApplicationContext(), "starting date must greater than ending date", Toast.LENGTH_LONG).show();
}
else {
Toast.makeText(getApplicationContext(), "difference: " + resyear + " years /" + resmonth + " months/" + resday + " days", Toast.LENGTH_LONG).show();
}
}

Related

How to Compare UTC format converted date in java [duplicate]

I have two Date objects with the below format.
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
String matchDateTime = sdf.parse("2014-01-16T10:25:00");
Date matchDateTime = null;
try {
matchDateTime = sdf.parse(newMatchDateTimeString);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// get the current date
Date currenthDateTime = null;
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
Date dt = new Date();
String currentDateTimeString = dateFormat.format(dt);
Log.v("CCCCCurrent DDDate String is:", "" + currentDateTimeString);
try {
currenthDateTime = sdf.parse(currentDateTimeString);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Now I want to compare the above two dates along with time.
How should I compare in Java.
Thanks
Since Date implements Comparable<Date>, it is as easy as:
date1.compareTo(date2);
As the Comparable contract stipulates, it will return a negative integer/zero/positive integer if date1 is considered less than/the same as/greater than date2 respectively (ie, before/same/after in this case).
Note that Date has also .after() and .before() methods which will return booleans instead.
An Alternative is....
Convert both dates into milliseconds as below
Date d = new Date();
long l = d.getTime();
Now compare both long values
Use compareTo()
Return Values
0 if the argument Date is equal to this Date; a value less than 0 if this Date is before the Date argument; and a value greater than 0 if this Date is after the Date argument.
Like
if(date1.compareTo(date2)>0)
An alternative is Joda-Time.
Use DateTime
DateTime date = new DateTime(new Date());
date.isBeforeNow();
or
date.isAfterNow();
// Get calendar set to the current date and time
Calendar cal = Calendar.getInstance();
// Set time of calendar to 18:00
cal.set(Calendar.HOUR_OF_DAY, 18);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
// Check if current time is after 18:00 today
boolean afterSix = Calendar.getInstance().after(cal);
if (afterSix) {
System.out.println("Go home, it's after 6 PM!");
}
else {
System.out.println("Hello!");
}
The other answers are generally correct and all outdated. Do use java.time, the modern Java date and time API, for your date and time work. With java.time your job has also become a lot easier compared to the situation when this question was asked in February 2014.
String dateTimeString = "2014-01-16T10:25:00";
LocalDateTime dateTime = LocalDateTime.parse(dateTimeString);
LocalDateTime now = LocalDateTime.now(ZoneId.systemDefault());
if (dateTime.isBefore(now)) {
System.out.println(dateTimeString + " is in the past");
} else if (dateTime.isAfter(now)) {
System.out.println(dateTimeString + " is in the future");
} else {
System.out.println(dateTimeString + " is now");
}
When running in 2020 output from this snippet is:
2014-01-16T10:25:00 is in the past
Since your string doesn’t inform of us any time zone or UTC offset, we need to know what was understood. The code above uses the device’ time zone setting. For a known time zone use like for example ZoneId.of("Asia/Ulaanbaatar"). For UTC specify ZoneOffset.UTC.
I am exploiting the fact that your string is in ISO 8601 format. The classes of java.time parse the most common ISO 8601 variants without us having to give any formatter.
Question: For Android development doesn’t java.time require Android API level 26?
java.time works nicely on both older and newer Android devices. It just requires at least Java 6.
In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
In non-Android Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from org.threeten.bp with subpackages.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Java Specification Request (JSR) 310, where java.time was first described.
ThreeTen Backport project, the backport of java.time to Java 6 and 7 (ThreeTen for JSR-310).
ThreeTenABP, Android edition of ThreeTen Backport
Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
Wikipedia article: ISO 8601

Returning Calendar with SimpleDateFormat

I want to return the value of the calendar + 14 months using the SimpleDateFormat but am getting the below error.
private fun bestBeforeDate(cal: Calendar = Calendar.getInstance()): String
{
cal.add(Calendar.MONTH, 14)
val format1 = SimpleDateFormat("dd-MM-yyy", Locale.getDefault()).format(this)
return getString(R.string.best_before_date) + format1.format(cal)
}
java.lang.IllegalArgumentException: Cannot format given Object as a Date
java.time and ThreeTenABP
Sorry, I can write this in Java only. Please translate yourself. Your task is best solved using java.time, the modern Java date and time API.
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("dd-MM-uuuu");
LocalDate date = LocalDate.now(ZoneId.of("Europe/London")).plusMonths(14);
String result = date.format(dateFormatter);
System.out.println("Result: " + result);
Output when running today:
Result: 22-12-2020
Fixing your code
If you insist on using the notoriously troublesome and long outdated SimpleDateFormat class, just remove .format(this) from your code. I bet the exception is coming from there, and it’s wrong since you have an almost correct call to the format method in the following line.
private fun bestBeforeDate(cal: Calendar = Calendar.getInstance()): String
{
cal.add(Calendar.MONTH, 14)
val format1 = SimpleDateFormat("dd-MM-yyyy")
return getString(R.string.best_before_date) + format1.format(cal.time)
}
The format method expects either a Date (another poorly designed and long outdated class) or a Long. Since this was neither of those, you got the exception.
Question: Doesn’t java.time require Android API level 26?
java.time works nicely on both older and newer Android devices. It just requires at least Java 6.
In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
In non-Android Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from org.threeten.bp with subpackages.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Java Specification Request (JSR) 310, where java.time was first described.
ThreeTen Backport project, the backport of java.time to Java 6 and 7 (ThreeTen for JSR-310).
ThreeTenABP, Android edition of ThreeTen Backport
Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
import java.util.Calendar;
import java.util.TimeZone;
/**
* Java program to add, subtract dates, month and year using Calendar in Java.
* Apart from date, Calendar class also provide time related information and can
* be used to add and subtract hours, minutes and seconds from time in Java.
*
* #author Shahzad Ali
*/
public class DateAndTimeArithmetic {
public static void main(String args[]){
//Java calendar in default timezone and default locale
Calendar cal = Calendar.getInstance();
cal.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println("current date: " + getDate(cal));
//adding days into Date in Java
cal.add(Calendar.DATE, 2);
System.out.println("date after 2 days : " + getDate(cal));
//subtracting days from Date in Java
cal.add(Calendar.DATE, -2);
System.out.println("date before 2 days : " + getDate(cal));
//adding moths into Date
cal.add(Calendar.MONTH, 5);
System.out.println("date after 5 months : " + getDate(cal));
//subtracting months from Date
cal.add(Calendar.MONTH, -5);
System.out.println("date before 5 months : " + getDate(cal));
//adding year into Date
cal.add(Calendar.YEAR, 5);
System.out.println("date after 5 years : " + getDate(cal));
//subtracting year from Date
cal.add(Calendar.YEAR, -5);
System.out.println("date before 5 years : " + getDate(cal));
//date after 200 days from now, takes care of how many days are in month
//for years calendar takes care of leap year as well
cal.add(Calendar.DATE, 200);
System.out.println("date after 200 days from today : " + getDate(cal));
System.out.println("current time in GMT: " + getTime(cal));
//adding hours into Date
cal.add(Calendar.HOUR_OF_DAY, 3);
System.out.println("Time after 3 hours : " + getTime(cal));
//subtracting hours from Date time
cal.add(Calendar.HOUR_OF_DAY, -3);
System.out.println("Time before 3 hours : " + getTime(cal));
//adding minutes into Date time
cal.add(Calendar.MINUTE, 3);
System.out.println("Time after 3 minutes : " + getTime(cal));
//subtracting minutes from Date time
cal.add(Calendar.HOUR_OF_DAY, -3);
System.out.println("Time before 3 minuets : " + getTime(cal));
}
/**
*
* #return current Date from Calendar in dd/MM/yyyy format
* adding 1 into month because Calendar month starts from zero
*/
public static String getDate(Calendar cal){
return "" + cal.get(Calendar.DATE) +"/" +
(cal.get(Calendar.MONTH)+1) + "/" + cal.get(Calendar.YEAR);
}
/**
*
* #return current Date from Calendar in HH:mm:SS format
*
* adding 1 into month because Calendar month starts from zero
*/
public static String getTime(Calendar cal){
return "" + cal.get(Calendar.HOUR_OF_DAY) +":" +
(cal.get(Calendar.MINUTE)) + ":" + cal.get(Calendar.SECOND);
}
}
Sample Output Should be like this:
current date: 22/10/2019
date after 2 days : 22/10/2019
date before 2 days : 24/10/2019
date after 5 months : 22/3/2020
etc...

Changing the date format for a date range programmatically

I have an application where I want to change the date format in 'From' and 'To'.
Lets assume, I have a date range like 2018-06-11 - 2018-06-14. Now, I want to change it in some other format as 11 June, 2018 - 14 June, 2018.
Please refer the code below, I have tried:
String strDate = "2018-06-11 - 2018-06-14";
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
try {
Date date = format.parse(strDate);
format = new SimpleDateFormat("dd MMMM, yyyy");
String strFinalDate = format.format(date);
tv4.setText(strFinalDate);
} catch (ParseException e) {
e.printStackTrace();
}
Also, I tried the below code as well:
String strDate = "2018-06-11 - 2018-06-14";
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd - yyyy-MM-dd");
try {
Date date = format.parse(strDate);
format = new SimpleDateFormat("dd MMMM, yyyy - dd MMMM, yyyy");
String strFinalDate = format.format(date);
tv4.setText(strFinalDate);
} catch (ParseException e) {
e.printStackTrace();
}
First, set of code runs smoothly, but converts only the 'From' and doesn't even checks for 'To' date.
And, second set of code returns an error which says, java.text.ParseException: Unparseable date: "2017-01-11 - 2017-01-14
Have I skipped anything in this code?
Please notify me if I have.
Thanks!
I suggest
DateTimeFormatter dateFormatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG);
String strDate = "2018-06-11 - 2018-06-14";
String[] strDates = strDate.split(" - ");
if (strDates.length != 2) {
throw new IllegalStateException("Wrong range format " + strDate
+ ", must be yyyy-MM-dd - yyyy-MM-dd");
}
String strFinalDate = LocalDate.parse(strDates[0]).format(dateFormatter)
+ " - " + LocalDate.parse(strDates[1]).format(dateFormatter);
System.out.println(strFinalDate);
Output on my Java with US English locale:
11 June 2018 - 14 June 2018
You don’t get the comma after “June” because this is not considered standard, so consider if this isn’t really an advantage. The output will depend on locale setting, which may be an advantage too. Or specify explicit locale for example:
DateTimeFormatter dateFormatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG)
.withLocale(Locale.UK);
I am using and recommending java.time, the modern Java date and time API.
What went wrong in your code?
No matter if you use an old-fashiuoned Date or a modern LocalDate, such an object can only hold one date, not a date range. In your first attempt SimpleDateFormat parsed the first date (since it matched your pattern) and then ignored the remainder of the string. So when you formatted the parsed date, you got
11 June, 2018
In your seconds attempt both dates were parsed, but into the same Date object, so only the values of the second date were kept. When printing the date its values were also printed twice since the format pattern for formatting contains the format twice:
14 June, 2018 - 14 June, 2018
Question: Can I use java.time on Android?
Yes, java.time works nicely on older and newer Android devices. It just requires at least Java 6.
In Java 8 and later and on newer Android devices (from API level 26, I’m told) the modern API comes built-in.
In Java 6 and 7 get the ThreeTen Backport, the backport of the new classes (ThreeTen for JSR 310; see the links at the bottom).
On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from org.threeten.bp with subpackages.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Java Specification Request (JSR) 310, where java.time was first described.
ThreeTen Backport project, the backport of java.timeto Java 6 and 7 (ThreeTen for JSR-310).
ThreeTenABP, Android edition of ThreeTen Backport
Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
As I stated in my comment above, you have to split your strDate String into two different String variables. Have a look at the code below
String strDate = "2018-06-11 - 2018-06-14";
String[] fromToDatesStr = strDate.split(" - ");
String fromDateStr = fromToDatesStr[0];
String toDateStr = fromToDatesStr[1];
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
Date fromDate = null;
Date toDate = null;
try {
fromDate = format.parse(fromDateStr);
toDate = format.parse(toDateStr);
format = new SimpleDateFormat("dd MMMM, yyyy");
String strFromFinalDate = format.format(fromDate);
String strToFinalDate = format.format(toDate);
} catch (ParseException e) {
e.printStackTrace();
}
String strFromFinalDate and String strToFinalDate now contain the dates formatted as you desire.

Retrieve current week's Monday's date

We have a utility that will run any day between Monday - Friday. It will update some number of files inside a Content Management Tool. The last modified date associated with that file should be, that week's monday's date. I wrote the following program to retrieve current week's monday's date. But I am still not sure whether this would work for all scenarios. Has anyone got a better solution ?
Calendar c = Calendar.getInstance();
c.setTime(new Date());
System.out.println(c.get(Calendar.DAY_OF_MONTH));
System.out.println(c.get(Calendar.DAY_OF_WEEK));
int mondayNo = c.get(Calendar.DAY_OF_MONTH)-c.get(Calendar.DAY_OF_WEEK)+2;
c.set(Calendar.DAY_OF_MONTH,mondayNo);
System.out.println("Date "+c.getTime());
I would strongly recommend using Joda Time instead (for all your date/time work, not just this):
// TODO: Consider time zones, calendars etc
LocalDate now = new LocalDate();
LocalDate monday = now.withDayOfWeek(DateTimeConstants.MONDAY);
System.out.println(monday);
Note that as you've used Monday here, which is the first day of the week in Joda Time, this will always return an earlier day (or the same day). If you chosen Wednesday (for example), then it would advance to Wednesday from Monday or Tuesday. You can always add or subtract a week if you need "the next Wednesday" or "the previous Wednesday".
EDIT: If you really want to use java.util.Date/Calendar, you can use:
Calendar c = Calendar.getInstance();
c.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
System.out.println("Date " + c.getTime());
You can use Calendar.setFirstDayOfWeek to indicate whether a week is Monday-Sunday or Sunday-Saturday; I believe setting the day of the week will stay within the current week - but test it.
tl;dr
LocalDate previousMonday =
LocalDate.now( ZoneId.of( "America/Montreal" ) )
.with( TemporalAdjusters.previous( DayOfWeek.MONDAY ) );
java.time
Both the java.util.Calendar class and the Joda-Time library have been supplanted by the java.time framework built into Java 8 and later. See Oracle Tutorial. Much of the java.time functionality has been back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP. With modern Android tooling and its "API desugaring", you need not add any library.
The java.time.LocalDate class represents a date-only value without time-of-day and without time zone.
Determining today's date requires a time zone, a ZoneId.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( zoneId );
The TemporalAdjuster interface (see Tutorial) is a powerful but simple way to manipulate date-time values. The TemporalAdjusters class (note the plural) implements some very useful adjustments. Here we use previous( DayOfWeek).
The handy DayOfWeek enum makes it easy to specify a day-of-week.
LocalDate previousMonday = today.with( TemporalAdjusters.previous( DayOfWeek.MONDAY ) );
If today is Monday, and you want to use today rather than a week ago, call previousOrSame.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes. Hibernate 5 & JPA 2.2 support java.time.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 brought some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android (26+) bundle implementations of the java.time classes.
For earlier Android (<26), the process of API desugaring brings a subset of the java.time functionality not originally built into Android.
If the desugaring does not offer what you need, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above) to Android. See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
The following will work, including wrapping months:
Calendar c = Calendar.getInstance();
c.setFirstDayOfWeek(Calendar.MONDAY);
c.setTime(new Date());
int today = c.get(Calendar.DAY_OF_WEEK);
c.add(Calendar.DAY_OF_WEEK, -today+Calendar.MONDAY);
System.out.println("Date "+c.getTime());
If, however, you edit your application on a Sunday (eg. Sunday 12 Feb), the date will be for the following Monday. Based on your requirements (the app will only run Monday thru Friday), this should not pose a problem.
As Jon suggested, the calendar.set method works...
I've tested it both in the case of a monday in same month and in another month using following snippet :
Calendar c = Calendar.getInstance();
//ensure the method works within current month
c.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
System.out.println("Date " + c.getTime());
//go to the 1st week of february, in which monday was in january
c.set(Calendar.DAY_OF_MONTH, 1);
System.out.println("Date " + c.getTime());
//test that setting day_of_week to monday gives a date in january
c.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
System.out.println("Date " + c.getTime());
//same for tuesday
c.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY);
System.out.println("Date " + c.getTime());
The results:
Date Mon Feb 13 10:29:41 CET 2012
Date Wed Feb 01 10:29:41 CET 2012
Date Mon Jan 30 10:29:41 CET 2012
Date Tue Jan 31 10:29:41 CET 2012
What about using Joda Time library... Take look at this answer...
in case you don't want to use Joda Time you can do like this to find the weeks -> (works on Android)
public static ArrayList<String> getWeeks(int month) {
ArrayList<String> arrayListValues = new ArrayList<>();
SimpleDateFormat sdf = new SimpleDateFormat("MMMM d");
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.MONTH, month);
int day = calendar.get(Calendar.DAY_OF_WEEK);
while (day != 1) {
calendar.add(Calendar.DATE, 1);
day = calendar.get(Calendar.DAY_OF_WEEK);
}
calendar.add(Calendar.DATE, -14);
String y1 = sdf.format(calendar.getTime());
calendar.add(Calendar.DATE, 6);
String y2 = sdf.format(calendar.getTime());
calendar.add(Calendar.DATE, 1);
arrayListValues.add(y1 + " - " + y2);
y1 = sdf.format(calendar.getTime());
calendar.add(Calendar.DATE, 6);
y2 = sdf.format(calendar.getTime());
calendar.add(Calendar.DATE, 1);
arrayListValues.add(y1 + " - " + y2);
for (int i = 0; i < 10; i++) {
y1 = sdf.format(calendar.getTime());
calendar.add(Calendar.DATE, 6);
y2 = sdf.format(calendar.getTime());
calendar.add(Calendar.DATE, 1);
arrayListValues.add(y1 + " - " + y2);
}
return arrayListValues;
}
For version Android 6.0 or grater use:
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
int day = 1, month = 7, year = 2018;
Calendar c = Calendar.getInstance();
c.setFirstDayOfWeek(Calendar.MONDAY);
c.set(year, month, day);
c.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); //change de day to monday
String dateMonday= sdf.format(c.getTime());
For version Android 5.1 or less it does not work appropriately, I created my own method.
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
int day = 1, month = 7, year = 2018;
Calendar c = Calendar.getInstance();
c.setFirstDayOfWeek(Calendar.MONDAY);
//set the date with your date or the current date c.set(new Date());
c.set(year, month, day);
int diaSemana = c.get(Calendar.DAY_OF_WEEK);
for (int i = 0; i < 7; i++) {
if (diaSemana != Calendar.MONDAY) {
day--;
c.set(year, month, day);
diaSemana = c.get(Calendar.DAY_OF_WEEK);
if (diaSemana == Calendar.MONDAY) break;
} else {
break;
}
}
String dateMonday= sdf.format(c.getTime());
Kotlin code. Works in older android versions
val c = Calendar.getInstance()
c.time = Date()
while (c.get(Calendar.DAY_OF_WEEK) != Calendar.MONDAY) {
c.add(Calendar.DAY_OF_WEEK, -1)
}
It won't work if the currents week monday is the month before... For example if today is Friday 1st of June... You should probably rather use the roll method...

Why does Java's Date.getYear() return 111 instead of 2011?

I am having a bit of trouble parsing a string date to a Date object. I use a DateFormat to parse the string, and when I print the value of the date, it gives me what I expect.
But when I try get the day, the month or the year it gives me the wrong values. For instance, the year is 2011, but when I do .getYear() it gives me 111. I have no idea why this is happening. Here is the relevant code segment:
Date dateFrom = null;
String gDFString = g.getDateFrom();
System.out.println(gDFString);
DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
try {
dateFrom = df.parse("04/12/2011");
System.out.println(dateFrom);
System.out.println(dateFrom.getYear());
} catch (ParseException e) {
e.printStackTrace();
}
When I out print dateFrom, I get Sun Dec 04 00:00:00 GMT 2011, which is what you would expect. But printing .getYear() returns 111.
I need to be able to get the day, month and year of the date for a time series graph.
Those methods have been deprecated. Instead, use the Calendar class.
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
public final class DateParseDemo {
public static void main(String[] args){
final DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
final Calendar c = Calendar.getInstance();
try {
c.setTime(df.parse("04/12/2011"));
System.out.println("Year = " + c.get(Calendar.YEAR));
System.out.println("Month = " + (c.get(Calendar.MONTH)));
System.out.println("Day = " + c.get(Calendar.DAY_OF_MONTH));
}
catch (ParseException e) {
e.printStackTrace();
}
}
}
Output:
Year = 2011
Month = 3
Day = 12
And as for the month field, this is 0-based. This means that January = 0 and December = 11. As stated by the javadoc,
Field number for get and set indicating the month. This is a
calendar-specific value. The first month of the year in the Gregorian
and Julian calendars is JANUARY which is 0; the last depends on the
number of months in a year.
Javadoc to the rescue:
Deprecated. As of JDK version 1.1, replaced by
Calendar.get(Calendar.YEAR) - 1900.
Returns a value that is the result of subtracting 1900 from the
year that contains or begins with the instant in time represented by
this Date object, as interpreted in the local time zone.
You should not use deprecated methods. Deprecated methods are methods which should not be used anymore. But whatever the method you're using, read its javadoc to know what it does.
President Evil nailed it, Date.getYear() returns a value that is the result of subtracting 1900 from the year that contains. And you you shouldn't use it.
But quick fix for the code in the question is:
Date dateFrom = null;
String gDFString = g.getDateFrom();
System.out.println(gDFString);
DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
try {
dateFrom = df.parse("04/12/2011");
System.out.println(dateFrom);
// Add 1900 to dateFrom.getYear()
System.out.println(dateFrom.getYear()+1900);
} catch (ParseException e) {
e.printStackTrace();
}
http://download.oracle.com/javase/1.4.2/docs/api/java/util/Date.html#getYear%28%29
The specification states that it returns the year minus 1900. Probably a good idea to avoid deprecated methods as well.
tl;dr
int year =
LocalDate.parse(
"04/12/2011" ,
DateTimeFormatter.ofLocalizedDate( FormatStyle.SHORT ).withLocale( Locale.US )
).getYear() ;
2011
java.time
The troublesome java.util.Date class and its siblings are now supplanted by the excellent java.time classes.
String input = "04/12/2011";
Locale locale = Locale.US;
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDate( FormatStyle.SHORT ).withLocale( locale );
LocalDate ld = LocalDate.parse( input , f );
The java.time classes utilize sane numbering, with:
Months 1-12 for January-December
2011 means 2011
Days of week are 1-7 for Monday-Sunday (per ISO 8601).
Interrogate the LocalDate for its constituent parts.
int year = ld.getYear(); // 2011
int month = ld.getMonthValue(); // 4
int dayOfMonth = ld.getDayOfMonth(); // 12
You can even ask for automatically localized name of month and name of day-of-week.
String monthName = ld.getMonth().getDisplayName( TextStyle.FULL_STANDALONE , Locale.CANDA_FRENCH ); // avril
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old date-time classes such as java.util.Date, .Calendar, & java.text.SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to java.time.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations.
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP (see How to use…).
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
This is only a guess, but the 111 could be the number of years since 1900. Take a look at documentation/do some tests to verify this (I can't check at the moment)

Categories