Compute Week of Year issues with ZonedDateTime and Calendar API - java

I was trying to compute week of year from a ISO-8601 Date format String input. Initially I tried this with java.time.ZonedDateTime but it gives incorrect result for Input Date - 2-Jan-2049. Then I tried with Calendar API it also gives incorrect response for 31-Dec-2049.
I have attached the sample test code
public class ZonedDateTimeTest {
public static void main(String[] args) throws InterruptedException {
System.out.println("======================================");
String instantStr1 = "2049-01-02T03:48:00Z";
printYearAndWeekOfYear(instantStr1);
System.out.println("======================================");
String instantStr2 = "2049-12-31T03:48:00Z";
printYearAndWeekOfYear(instantStr2);
System.out.println("======================================");
}
public static void printYearAndWeekOfYear(String ISODate) {
System.out.println("Date provided -> " + ISODate);
ZonedDateTime utcTimestamp = parseToInstant(ISODate).atZone(ZoneOffset.UTC);
int year = utcTimestamp.getYear();
int weekOfYear = utcTimestamp.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR);
System.out.println("Using ZonedDateTime API:: Year " + year + " weekOfYear " + weekOfYear);
Date d1 = Date.from(parseToInstant(ISODate));
Calendar cl = Calendar.getInstance();
cl.setTime(d1);
int year1 = cl.get(Calendar.YEAR);
int weekOfYear1 = cl.get(Calendar.WEEK_OF_YEAR);
System.out.println("Using Calendar API:: Year " + year1 + " weekOfYear " + weekOfYear1);
}
public static Instant parseToInstant(String ISODate) {
return DateTimeFormatter.ISO_OFFSET_DATE_TIME.parse(ISODate, Instant::from);
}
}
Output from code above
======================================
Date provided 2049-01-02T03:48:00Z
Using ZonedDateTime API: Year 2049 weekOfYear 53
Using Calendar API: Year 2049 weekOfYear 1
======================================
Date provided 2049-12-31T03:48:00Z
Using ZonedDateTime API: Year 2049 weekOfYear 52
Using Calendar API: Year 2049 weekOfYear 1
======================================

There are four problems with your code to start with:
You're using the system default time zone when you use Calendar, which may well change which date the Instant falls on. If you set the calendar to use UTC you'll make it more consistent.
You're using Calendar.YEAR which will give you the calendar year rather than the week year. You need to use Calendar.getWeekYear() instead.
You're using ZonedDateTime.getYear() which is again the calendar year. You shuold be using utcTimestamp.get(IsoFields.WEEK_BASED_YEAR)
You're using Calendar.getInstance() which could give you a non-Gregorian calendar, or it could have first-day-of-week set inappropriately for the computation you want to perform
Fixing these issues (and naming conventions) we end up with:
import java.util.*;
import java.time.*;
import java.time.format.*;
import java.time.chrono.*;
import java.time.temporal.*;
public class ZonedDateTimeTest {
public static void main(String[] args) {
printYearAndWeekOfYear("2049-01-02T03:48:00Z");
String instantStr2 = "2049-12-31T03:48:00Z";
printYearAndWeekOfYear("2049-12-31T03:48:00Z");
}
public static void printYearAndWeekOfYear(String isoDate) {
System.out.println("Date provided -> " + isoDate);
Instant instant = DateTimeFormatter.ISO_OFFSET_DATE_TIME.parse(isoDate, Instant::from);
ZonedDateTime utcTimestamp = instant.atZone(ZoneOffset.UTC);
int year = utcTimestamp.get(IsoFields.WEEK_BASED_YEAR);
int weekOfYear = utcTimestamp.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR);
System.out.println("ZonedDateTime: Year " + year + " weekOfYear " + weekOfYear);
// Force the Gregorian calendar with ISO rules and using UTC
Calendar calendar = new GregorianCalendar();
calendar.setFirstDayOfWeek(Calendar.MONDAY);
calendar.setMinimalDaysInFirstWeek(4);
calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
calendar.setTime(Date.from(instant));
int calYear = calendar.getWeekYear();
int calWeekOfYear = calendar.get(Calendar.WEEK_OF_YEAR);
System.out.println("Calendar: Year " + calYear + " weekOfYear " + calWeekOfYear);
System.out.println();
}
}
Output:
Date provided -> 2049-01-02T03:48:00Z
ZonedDateTime: Year 2048 weekOfYear 53
Calendar: Year 2048 weekOfYear 53
Date provided -> 2049-12-31T03:48:00Z
ZonedDateTime: Year 2049 weekOfYear 52
Calendar: Year 2049 weekOfYear 52
Both of those look good to me.

The old Calendar-stuff indeed enables a solution since Java-7 so I show it as supplement to the Java-8-related answer of Jon Skeet:
String instantStr1 = "2049-01-02T03:48:00Z";
String instantStr2 = "2049-12-31T03:48:00Z";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
Date d1 = sdf.parse(instantStr1);
Date d2 = sdf.parse(instantStr2);
GregorianCalendar gcal = new GregorianCalendar();
gcal.setFirstDayOfWeek(Calendar.MONDAY);
gcal.setMinimalDaysInFirstWeek(4);
gcal.setTime(d1);
System.out.println(
"Using Calendar API: Year " + gcal.getWeekYear() + " weekOfYear "
+ gcal.get(Calendar.WEEK_OF_YEAR)
); // Using Calendar API: Year 2048 weekOfYear 53
gcal.setTime(d2);
System.out.println(
"Using Calendar API: Year " + gcal.getWeekYear() + " weekOfYear "
+ gcal.get(Calendar.WEEK_OF_YEAR)
); // Using Calendar API: Year 2049 weekOfYear 52
For Android-users where this API is standard: The method getWeekYear() is available since API-level 24.

Related

Same day prevous year (previous year, same week and day of week)

I want to retrieve same day previous year.
e.g. today is 2019-03-30 that is year 2019, week 26(week of year), day 7 (day of week).
I need to construct LocalDate which is year 2018, week 26(week of year), day 7 (day of week).
I could not find from java.time package which can built LocalDate like this.
It seems like you want the previous year date with same week of year and day of week as the given date. Below code with give you that result.
LocalDate currentLocalDate = LocalDate.now();
int dayOfWeek = currentLocalDate.getDayOfWeek().getValue();
int weekOfYear = currentLocalDate.get(ChronoField.ALIGNED_WEEK_OF_YEAR);
LocalDate resultLocalDate = currentLocalDate
.minusYears(1)
.with(ChronoField.ALIGNED_WEEK_OF_YEAR, weekOfYear)
.with(ChronoField.DAY_OF_WEEK, dayOfWeek);
Full Example (live copy):
import java.time.*;
import java.time.format.*;
import java.time.temporal.*;
class Example
{
private static void showDateInfo(LocalDate ld) {
int weekOfYear = ld.get(ChronoField.ALIGNED_WEEK_OF_YEAR);
int dayOfWeek = ld.getDayOfWeek().getValue();
System.out.println(ld.format(DateTimeFormatter.ISO_LOCAL_DATE) + " is week " + weekOfYear + ", day " + dayOfWeek);
}
public static void main (String[] args) throws java.lang.Exception
{
LocalDate currentLocalDate = LocalDate.of(2019, 6, 30);
showDateInfo(currentLocalDate);
int dayOfWeek = currentLocalDate.getDayOfWeek().getValue();
int weekOfYear = currentLocalDate.get(ChronoField.ALIGNED_WEEK_OF_YEAR);
LocalDate resultLocalDate = currentLocalDate
.minusYears(1)
.with(ChronoField.ALIGNED_WEEK_OF_YEAR, weekOfYear)
.with(ChronoField.DAY_OF_WEEK, dayOfWeek);
showDateInfo(resultLocalDate);
}
}
Output:
2019-06-30 is week 26, day 7
2018-07-01 is week 26, day 7
I believe that the other answers are close but not quite there yet. As far as I understand, you want to use the week scheme of the default locale, which the other answers don’t do. My suggestion is:
WeekFields wf = WeekFields.of(Locale.getDefault());
LocalDate today = LocalDate.now(ZoneId.of("Africa/Casablanca"));
int week = today.get(wf.weekOfYear());
int dow = today.get(wf.dayOfWeek());
System.out.println("Today is " + today + ", "
+ today.getDayOfWeek() + " of week " + week);
LocalDate correspondingDayLastYear = today.minusYears(1)
.with(wf.weekOfYear(), week)
.with(wf.dayOfWeek(), dow);
System.out.println("Last year was " + correspondingDayLastYear + ", "
+ correspondingDayLastYear.getDayOfWeek()
+ " of week " + correspondingDayLastYear.get(wf.weekOfYear()));
When running on my computer just now the output was:
Today is 2019-06-30, SUNDAY of week 26
Last year was 2018-07-01, SUNDAY of week 26
When I set my locale to US I get the same date, but a different week number since American weeks are defined differently:
Today is 2019-06-30, SUNDAY of week 27
Last year was 2018-07-01, SUNDAY of week 27
I believe that there will also be cases where different locales will give you different dates.
wf.dayOfWeek() gives you a field that numbers the days from 1 to 7 according to the first day of week in that particular locale. It’s important not just to use withDayOfWeek or equivalent, or you would risk sliding into a different week if not using ISO weeks.
Still my answer will not work always! If today is within week 53 of the year, it may very well be that last year didn’t have a week 53. Not much we can do about that. Another problem we can’t solve: In American weeks week 1 starts on January 1. If this is a Sunday, it is the first day for the week, but then week 1 of the previous year started on a Friday or Saturday, so week 1 didn’t have any Sunday.
If you're looking for an ISO week-year compatible function, this is working for me - so far =].
public class FiscalDateUtil {
private static Logger log = LoggerFactory.getLogger(FiscalDateUtil.class);
static public LocalDate previousYearComparisonDate(LocalDate date) {
final int weekYear = date.get(IsoFields.WEEK_BASED_YEAR);
final int weekLastYear = weekYear-1;
final DayOfWeek dayOfWeek = date.getDayOfWeek();
final int weekOfYear = date.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR);
final LocalDate adjustedLastYear = date
.with(IsoFields.WEEK_BASED_YEAR, weekLastYear)
.with(IsoFields.WEEK_OF_WEEK_BASED_YEAR, weekOfYear)
.with(TemporalAdjusters.nextOrSame(dayOfWeek));
if (log.isTraceEnabled()) {
log.trace("starting date {}", date.toString());
log.trace("starting date dow {}", date.getDayOfWeek());
log.trace("lastYear {}", weekLastYear);
log.trace("lastYear dow {}", dayOfWeek);
log.trace("adjustedLastYear {}", adjustedLastYear.toString());
log.trace("adjustedLastYear dow {}", adjustedLastYear.getDayOfWeek());
}
return adjustedLastYear;
}
}
You can add the number of days since beginning of year of the current date to the beginning of the year before.
This should do the trick:
String dateStr = "2019-03-30";
LocalDate date = LocalDate.parse(dateStr);
LocalDate newDate = LocalDate.parse(date.getYear() + "-01-01").plusDays(date.getDayOfYear());
System.out.println(newDate);

Get Start day and End day of a Week? [Java]

I am developing an app that constantly monitors the user's physical activity and inactivity levels. I am trying to figure out out to get the starting and ending day of a week when a date is provided. For example, 3 Mar is the date that I am providing and I want to get the starting and ending day of this week -> 27 Feb - 5 Mar. Is it possible to do that?
I am trying to achieve the following design
The following code that I currently have just concatenates the last and first date of the list of activities (one for every day is created).
private String formatDate(List<Activity> activities) {
Calendar calendar = Calendar.getInstance(Locale.UK);
Date date = activities.get(activities.size() - 1).getDate();
calendar.setTime(date);
String output = "" + calendar.get(Calendar.DAY_OF_MONTH) + " "
+ calendar.getDisplayName(Calendar.MONTH, Calendar.SHORT, Locale.UK);
calendar.setTime(activities.get(0).getDate());
output += " - " + calendar.get(Calendar.DAY_OF_MONTH) + " "
+ calendar.getDisplayName(Calendar.MONTH, Calendar.SHORT, Locale.UK);
return output;
}
Note: I have to mention that the List as a parameter are all of the activities grouped per week already
However, with this approach it becomes problematic when the person is not using the app (i.e. not logged in -> the app stops monitoring) and the text label could look something like that
(e.g. only one activity for this week)
Any advice please?
It is as simple as doing:
calendar.set(Calendar.DAY_OF_WEEK, calendar.getFirstDayOfWeek());
What is considered the first day of the week depends on the Locale used.
To get the last day of the week then do:
calendar.add(Calendar.DAY_OF_YEAR, 6);
java.time
The legacy date-time API (java.util date-time types and their formatting type, SimpleDateFormat etc.) is outdated and error-prone. It is recommended to stop using it completely and switch to java.time, the modern date-time API*.
Solution using java.time, the modern API:
For ISO 8601 week (Monday to Sunday), you can use ChronoField.DAY_OF_WEEK as 1 for the first day of the week and as 7 for the last day of the week.
import java.time.LocalDate;
import java.time.Month;
import java.time.temporal.ChronoField;
public class Main {
public static void main(String[] args) {
LocalDate date = LocalDate.of(2017, Month.MARCH, 3);
LocalDate firstDayOfTheWeek = date.with(ChronoField.DAY_OF_WEEK, 1);
System.out.println(firstDayOfTheWeek); // 2017-02-27
LocalDate lastDayOfTheWeek = date.with(ChronoField.DAY_OF_WEEK, 7);
System.out.println(lastDayOfTheWeek); // 2017-03-05
}
}
Alternatively,
import java.time.LocalDate;
import java.time.Month;
import java.time.temporal.WeekFields;
public class Main {
public static void main(String[] args) {
LocalDate date = LocalDate.of(2017, Month.MARCH, 3);
LocalDate firstDayOfTheWeek = date.with(WeekFields.ISO.getFirstDayOfWeek());
System.out.println(firstDayOfTheWeek); // 2017-02-27
LocalDate lastDayOfTheWeek = firstDayOfTheWeek.plusDays(6);
System.out.println(lastDayOfTheWeek); // 2017-03-05
}
}
Use WeekFields#of(Locale locale) to get the Locale-specific result (thanks, Ole V.V. for the suggestion):
import java.time.LocalDate;
import java.time.Month;
import java.time.temporal.WeekFields;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
LocalDate date = LocalDate.of(2017, Month.MARCH, 3);
System.out.println("France:");
LocalDate firstDayOfTheWeek = date.with(WeekFields.of(Locale.FRANCE).getFirstDayOfWeek());
System.out.println(firstDayOfTheWeek);
LocalDate lastDayOfTheWeek = firstDayOfTheWeek.plusDays(6);
System.out.println(lastDayOfTheWeek);
System.out.println();
System.out.println("USA:");
firstDayOfTheWeek = date.with(WeekFields.of(Locale.US).getFirstDayOfWeek());
System.out.println(firstDayOfTheWeek);
lastDayOfTheWeek = firstDayOfTheWeek.plusDays(6);
System.out.println(lastDayOfTheWeek);
}
}
Output:
France:
2017-02-27
2017-03-05
USA:
2017-03-05
2017-03-11
The documentation of WeekFields.ISO.getFirstDayOfWeek() says:
Gets the first day-of-week.
The first day-of-week varies by culture. For example, the US uses
Sunday, while France and the ISO-8601 standard use Monday. This method
returns the first day using the standard DayOfWeek enum.
Learn more about java.time, the modern date-time API* from Trail: Date Time.
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
You just need to use the Calendar.DAY_OF_WEEK parameter to work out how many days to subtract - for example to print the start and end of the current week:
public static void main(String[] args) {
Calendar calendar = GregorianCalendar.getInstance();
// Subtract number of days to start of week
calendar.add(Calendar.DATE, -(calendar.get(Calendar.DAY_OF_WEEK)-1));
String output = "" + calendar.get(Calendar.DAY_OF_MONTH) + " "
+ calendar.getDisplayName(Calendar.MONTH, Calendar.SHORT, Locale.UK);
calendar.add(Calendar.DATE, 6);
output += " - " + calendar.get(Calendar.DAY_OF_MONTH) + " "
+ calendar.getDisplayName(Calendar.MONTH, Calendar.SHORT, Locale.UK);
System.out.println(output);
}
Thanks to #BarrySW19 and #john16384, here is the working method:
private String formatDate(List<Activity> activities) {
Calendar calendar = Calendar.getInstance(Locale.UK);
Date date = activities.get(activities.size() - 1).getDate();
calendar.setTime(date);
calendar.set(Calendar.DAY_OF_WEEK, calendar.getFirstDayOfWeek());
String output = "" + calendar.get(Calendar.DAY_OF_MONTH) + " "
+ calendar.getDisplayName(Calendar.MONTH, Calendar.SHORT, Locale.UK);
calendar.add(Calendar.DAY_OF_YEAR, 6);
output += " - " + calendar.get(Calendar.DAY_OF_MONTH) + " "
+ calendar.getDisplayName(Calendar.MONTH, Calendar.SHORT, Locale.UK);
return output;
}

Java getter and setter for a date field

I am beginning Java and I have been ask to write a class myDate. Such a class has fields for year, month and day.
I should use the following syntax to set the date:
setDate(long timeElapsed)
I know that I can do the following:
Date tempDate = new Date();
long lngDate = tempDate.getTime();
System.out.println("lngDate: " + lngDate);
How do I calculate the "long timeElapsed" parameter from a given year, month and day?
Now, I should use GregorianCalendar to display the date, for which I have done the following:
GregorianCalendar cal = new GregorianCalendar(year, month, day);
System.out.println("Year: " + cal.YEAR);
System.out.println("Month: " + cal.MONTH);
System.out.println("Day: " + cal.DAY_OF_MONTH);
But the results I get are as follow:
Year: 1
Month: 2
Day: 5
How can I use GregorianCalendar to display a date in myDate class? I have been working on this issue for a while without success.
I will very much appreciate your feedback.
Respectfully,
Jorge Maldonado
Calendar.YEAR as well as MONTH and DAY_OF_THE_MONTH are constants to use in get() method. so
System.out.println("Year: " + cal.get(Calendar.YEAR));
System.out.println("Month: " + cal.get(Calendar.MONTH));
System.out.println("Day: " + cal.get(Calendar.DAY_OF_MONTH));
does what you need.
BTW on top you do not need to create new Date to get time value:
long lngDate = System.currentTimeMillis();
System.out.println("lngDate: " + lngDate);
value is the same. When new Date created it uses System.currentTimeMillis()
PS. Just keep in mind cal.get(Calendar.MONTH) returns month number -1. Jan is month 0, Feb is month 1 and so on.
Just call the following method to get the date as a long from a calendar:
cal.getTimeInMillis()
Here is the corresponding class:
public class MyDate {
public void setDate(long timeElapsed) {
final GregorianCalendar cal = new GregorianCalendar();
cal.setTime(new Date(timeElapsed));
this.year = cal.get(Calendar.YEAR);
this.month = cal.get(Calendar.MONTH);
this.day = cal.get(Calendar.DAY_OF_MONTH);
}
public long getLong() {
final GregorianCalendar cal = new GregorianCalendar(this.year, this.month, this.day);
return cal.getTimeInMillis();
}
private int year, month, day;
}

write a program to prompt number of days to add to current date and print new date as well as today's date [duplicate]

This question already has answers here:
how to add days to java simple date format
(2 answers)
Closed 7 years ago.
print out today's date. this should be in the form MM/DD/YYYY. Months should start for 1 instead of 0. prompt to read number of days to be added to current date and print the new date.
please anyone help me out
import java.util.calendar;
import java.util.Date;
import java.util.GregorianCalendar;
public class JavaDateAdd {
public static void main(String[] args) {
Date date = new Date();
System.out.println("Today's Date Is: " + (now.get(Calendar.MONTH) + 1) + "/" + now.get(Calendar.DATE) + "/" + now.get(Calendar.YEAR));
System.out.print("Number of Days You Want To ADD: ");
int AddDays = in.nextInt();
Date newDate = addDays(date,AddDays);
System.out.println("Java Date after adding "+AddDays+" days: "+(now.get(Calendar.MONTH) + 1) + "/" + now.get(Calendar.DATE) + "/" + now.get(Calendar.YEAR));
}
}`
You can modify the code to accept take no of days and to accept your date format.
public static void main(String[] args) {
Calendar cal = Calendar.getInstance();
// print current date
System.out.println("The current date is : " + cal.getTime());
// add 20 days to the calendar
cal.add(Calendar.DATE, 20);
System.out.println("20 days later: " + cal.getTime());
Date tommrrow = cal.getTime();
SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yy");
String date = formatter.format(tommrrow);
System.out.println("20 days in dd-MM-yy: " + date);
}
Date Formatting using SimpleDateFormat:
SimpleDateFormat is a concrete class for formatting and parsing dates in a locale-sensitive manner. SimpleDateFormat allows you to start by choosing any user-defined patterns for date-time formatting. For example:
import java.util.*;
import java.text.*;
public class HelloWorld {
public static void main(String args[]) {
Date dNow = new Date( );
SimpleDateFormat sdf =
new SimpleDateFormat ("MM/dd/yyyy ");
System.out.println("Current Date: " + sdf.format(dNow));
Calendar c = Calendar.getInstance();
c.setTime(new Date()); // Now use today date.
c.add(Calendar.DATE, 35); // Adding 35 days
String output = sdf.format(c.getTime());
System.out.println("New Date: "+ output);
}
}
This would produce the following result:
Current Date: 09/24/2015
New Date: 10/29/2015
print out today's date. this should be in the form MM/DD/YYYY. Months should start for 1 instead of 0.
Start by taking a look at DateTimeFormatter, for example:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yyyy");
System.out.println("Today is " + formatter.format(LocalDateTime.now()));
prompt to read number of days to be added to current date
Start by having a look at Scanning, for example:
Scanner scanner = new Scanner(System.in);
System.out.print("How many days to add: ");
int days = scanner.nextInt();
and print the new date.
Start by having a look at Java 8's Date Time API, for example:
LocalDateTime ldt = LocalDateTime.now();
ldt = ldt.plusDays(days);
System.out.println(formatter.format(ldt));

Java: check if a given date is within current month

I need to check if a given date falls in the current month, and I wrote the following code, but the IDE reminded me that the getMonth() and getYear() methods are obsolete. I was wondering how to do the same thing in newer Java 7 or Java 8.
private boolean inCurrentMonth(Date givenDate) {
Date today = new Date();
return givenDate.getMonth() == today.getMonth() && givenDate.getYear() == today.getYear();
}
//Create 2 instances of Calendar
Calendar cal1 = Calendar.getInstance();
Calendar cal2 = Calendar.getInstance();
//set the given date in one of the instance and current date in the other
cal1.setTime(givenDate);
cal2.setTime(new Date());
//now compare the dates using methods on Calendar
if(cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR)) {
if(cal1.get(Calendar.MONTH) == cal2.get(Calendar.MONTH)) {
// the date falls in current month
}
}
java.time (Java 8)
There are several ways to do it with the new java.time API (tutorial). You can do it using .get(ChronoField.XY), but I think this is prettier:
Instant given = givenDate.toInstant();
Instant ref = Instant.now();
return Month.from(given) == Month.from(ref) && Year.from(given).equals(Year.from(ref));
For better re-usability you can also refactor this code to "temporal query":
public class TemporalQueries {
//TemporalQuery<R> { R queryFrom(TemporalAccessor temporal) }
public static Boolean isCurrentMonth(TemporalAccessor temporal) {
Instant ref = Instant.now();
return Month.from(temporal) == Month.from(ref) && Year.from(temporal).equals(Year.from(ref));
}
}
Boolean result = givenDate.toInstant().query(TemporalQueries::isCurrentMonth); //Lambda using method reference
Time Zone
The other answers ignore the crucial issue of time zone. A new day dawns earlier in Paris than in Montréal. So at the same simultaneous moment, the dates are different, "tomorrow" in Paris while "yesterday" in Montréal.
Joda-Time
The java.util.Date and .Calendar classes bundled with Java are notoriously troublesome, confusing, and flawed. Avoid them.
Instead use either Joda-Time library or the java.time package in Java 8 (inspired by Joda-Time).
Here is example code in Joda-Time 2.5.
DateTimeZone zone = DateTimeZone.forID( "America/Montreal" );
DateTime dateTime = new DateTime( yourJUDate, zone ); // Convert java.util.Date to Joda-Time, and assign time zone to adjust.
DateTime now = DateTime.now( zone );
// Now see if the month and year match.
if ( ( dateTime.getMonthOfYear() == now.getMonthOfYear() ) && ( dateTime.getYear() == now.getYear() ) ) {
// You have a hit.
}
For a more general solution to see if a moment falls within any span of time (not just a month), search StackOverflow for "joda" and "interval" and "contain".
java.time (Java 8)
Java 8 provides the YearMonth class which represents a given month within a given year (e.g. January 2018). This can be used to compare against the YearMonth of the given date.
private boolean inCurrentMonth(Date givenDate) {
ZoneId timeZone = ZoneOffset.UTC; // Use whichever time zone makes sense for your use case
LocalDateTime givenLocalDateTime = LocalDateTime.ofInstant(givenDate.toInstant(), timeZone);
YearMonth currentMonth = YearMonth.now(timeZone);
return currentMonth.equals(YearMonth.from(givenLocalDateTime));
}
Note that this approach will work for any of the Java 8 time classes that have both a month and a date part (LocalDate, ZonedDateTime, etc.) and not just LocalDateTime.
As far as I know the Calendar class and all derived from it return the date using the get(). See the documentation for this class. Also here is an example taken from here:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy MMM dd HH:mm:ss");
Calendar calendar = new GregorianCalendar(2013,1,28,13,24,56);
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH); // Jan = 0, dec = 11
int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
int weekOfYear = calendar.get(Calendar.WEEK_OF_YEAR);
int weekOfMonth= calendar.get(Calendar.WEEK_OF_MONTH);
int hour = calendar.get(Calendar.HOUR); // 12 hour clock
int hourOfDay = calendar.get(Calendar.HOUR_OF_DAY); // 24 hour clock
int minute = calendar.get(Calendar.MINUTE);
int second = calendar.get(Calendar.SECOND);
int millisecond= calendar.get(Calendar.MILLISECOND);
System.out.println(sdf.format(calendar.getTime()));
System.out.println("year \t\t: " + year);
System.out.println("month \t\t: " + month);
System.out.println("dayOfMonth \t: " + dayOfMonth);
System.out.println("dayOfWeek \t: " + dayOfWeek);
System.out.println("weekOfYear \t: " + weekOfYear);
System.out.println("weekOfMonth \t: " + weekOfMonth);
System.out.println("hour \t\t: " + hour);
System.out.println("hourOfDay \t: " + hourOfDay);
System.out.println("minute \t\t: " + minute);
System.out.println("second \t\t: " + second);
System.out.println("millisecond \t: " + millisecond);
which outputs
2013 Feb 28 13:24:56
year : 2013
month : 1
dayOfMonth : 28
dayOfWeek : 5
weekOfYear : 9
weekOfMonth : 5
hour : 1
hourOfDay : 13
minute : 24
second : 56
millisecond : 0
I think it was replaced because the new way offers a much simpler handling using a single function, which is much easier to remember.

Categories