I need to identify the date which is 6 complete months ago. For example:
Feb-27, 2012(Today) - It is Feb and we don't count incomplete month, false
Feb-01, 2012 - Still Feb so don't count too, false
Jan-01, 2011 - Completed, false
Dec-01, 2011 - Completed, false
Nov-01, 2011 - Completed, false
Oct-01, 2011 - Completed, false
Sep-01, 2011 - Completed, false
Aug-01, 2011 - Completed, false
Jul-01, 2011 - Already pass 6 complete months, true
It should work in whatever date in the future.
I thought of current date minus 30*6=180 days, but it is not accurate.
It needs to be accurate because, for example, if we identify Jul 2011 is valid then we will housekeep all the data for that month.
Thanks.
I would try this simple logic to do the job.
Calendar cal = Calendar.getInstance(); //Get current date/month i.e 27 Feb, 2012
cal.add(Calendar.MONTH, -6); //Go to date, 6 months ago 27 July, 2011
cal.set(Calendar.DAY_OF_MONTH, 1); //set date, to make it 1 July, 2011
Hope this helps.
If you could use JodaTime, here is code for ±6 months calculation:
import org.joda.time.DateTime;
import org.joda.time.Months;
....
....
DateTime now = new DateTime();
DateTime then = new DateTime().withDate(2011, 8, 1);
if(Math.abs(Months.monthsBetween(now, then).getMonths()) > 6){
System.out.println("6 mo apart!");
//your logic goes here
}
Use a library like joda-time for your time and date needs. Offhand I think you could do this with:
new LocalDate().minusMonths(7).withDayOfMonth(1)
(7 months to cover any partial months... leaves an edge case of the first of the month... but eh :) )
YearMonth
The java.time.YearMonth class built into Java makes this task simple.
Get the current year-month. This requires a time zone as at any given moment the date varies around the globe by zone. On the first/last day of the month, the month can vary around the world by zone.
YearMonth ymCurrent = YearMonth.now( ZoneId.of( "America/Montreal" ) );
We know the current month is incomplete by definition. So move to the previous month.
YearMonth ymPrevious = ymCurrent.minusMonths( 1 ) ;
Move a further six months earlier if desired.
YearMonth ymSixMonthsMore = ymPrevious.minusMonths( 6 );
That YearMonth object itself may be useful in your code. You can pas these objects of this class around your code.
If you need the first day of a month, ask.
LocalDate ld = ymSixMonthsMore.atDay( 1 );
As I understand, you need to have a utility which will determine whether a variable date is 6 months before the reference date that you will set. Take a look at my code snippet for this problem. It just gets use of java.util.Calendar, you don't have to use some other libraries.
import java.util.Calendar;
public class Test
{
public static void main(String[] args)
{
Calendar cal1 = Calendar.getInstance();
cal1.set(2012, 2, 27);
Calendar cal2 = Calendar.getInstance();
cal2.set(2011, 8, 1);
boolean valid = isSixMonthsAgo(cal1, cal2);
System.out.println(valid);
}
public static boolean isSixMonthsAgo(Calendar referenceDate, Calendar dateToBeTested)
{
int year1 = referenceDate.get(Calendar.YEAR);
int month1 = referenceDate.get(Calendar.MONTH);
int year2 = dateToBeTested.get(Calendar.YEAR);
int month2 = dateToBeTested.get(Calendar.MONTH);
if ((year1 * 12 + month1) - (year2 * 12 + month2) > 6)
return true;
return false;
}
}
Related
I have verified that the date is read correctly from a file, but once I use SimpleDateFormat.format with the pattern "dd/MM/yy" it suddenly adds a month. This leads me to believe lenient mode is calculating the wrong value. But I have no idea what would make it add a full month.
Some example dates I read:
16/09/2013
23/09/2013
30/09/2013
07/10/2013
14/10/2013
21/10/2013
The code used to parse the date (it's a wrapper around Calendar I made):
public static SimpleDateTime parseDate(String date)
{
String[] dateParts = date.split("[-\\.:/]");
int day = Integer.parseInt(dateParts[0]);
int month = Integer.parseInt(dateParts[1]);
int year = Integer.parseInt(dateParts[2]);
return new SimpleDateTime(dag, maand, jaar);
}
The constructor used here:
public SimpleDateTime(int day, int month, int year)
{
date = Calendar.getInstance();
date.setLenient(true);
setDay(day);
setMonth(month);
setYear(year);
}
The setters for day, month and year:
public void setYear(int year)
{
date.set(Calendar.YEAR, year);
}
public void setMonth(int month)
{
date.set(Calendar.MONTH, month);
}
public void setDay(int day)
{
date.set(Calendar.DAY_OF_MONTH, day);
}
And the code used to format the date:
public String toString(String pattern)
{
String output = new SimpleDateFormat(pattern, Locale.getDefault()).format(date.getTime());
return output;
}
where the pattern passed is:
"dd/MM/yy"
Intended to print a date as:
16/09/13
23/09/13
Instead I get:
16/10/13
23/10/13
January is 0 in Java; February is 1 and so on.
See Calendar.JANUARY, Calendar.FEBRUARY.
So when you're reading 1 from the file
you think you read JAN but you read FEB.
You should do: date.set(Calendar.MONTH, month-1); to fix this.
Months are indexed from 0 not 1 so 10 is November and 11 will be December.
Calendar.MONTH
From documentation:
Field number for get and set indicating the month. This is a calendar-specific value. The first month of the year is JANUARY; the last depends on the number of months in a year.
So if you check JANUARY you see it starts in zero.
Make sure your month is in the interval 0-11. Possibly it is in 1-12.
The reason for this is that the counting starts at 0.
January == 0
February == 1
and so on. See the documentation.
THe problem is that you pass 9 to SimpleDateFormat and since month are indexed from 0 to 11 it will parse month '9' as the 10th month.
You need to subtract 1 from the month :)
Calendar class in Java holds months starting from 0, hence when you set the month as 0, it would consider it as January. SimpleDateFormat provides for a way to correctly display the value as 01.
Calendar cal = Calendar.getInstance();
cal.set(Calendar.MONTH, 0);
System.out.println(new SimpleDateFormat("dd/MM/yy").format(cal.getTime()));
Output:
29/01/14
The workaround for you to align you file that Calendar can work with (since December - or 12 would trickle over to the next year) or modify your logic to pick Constants like:
cal.set(Calendar.MONTH, Calendar.JANUARY);
The answer by peter.petrov is almost correct, except for one major problem. Like your question, it neglects to account for time zone.
For your information, this kind of work is much easier in Joda-Time (or new java.time.* classes in Java 8). Joda-Time is so much cleaner you won't even feel the need to create a wrapper class.
// Specify the time zone for which the incoming date is intended.
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Brussels" );
String input = "16/09/2013";
DateTimeFormatter formatter = DateTimeFormat.forPattern("dd/MM/yyyy").withZone( timeZone );
DateTime dateTime = formatter.parseDateTime( input );
String output = formatter.print( dateTime );
Dump to console…
System.out.println( "dateTime: " + dateTime );
System.out.println( "output: " + output );
System.out.println( "millis since Unix epoch: " + dateTime.getMillis() );
When run…
dateTime: 2013-09-16T00:00:00.000+02:00
output: 16/09/2013
millis since Unix epoch: 1379282400000
I manage some dates in my own date classes. I want to create a method like this in my date:
int getWeekdayIndex()
right now it lookes something like this:
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
cal.set(year, month+1, day); // data of this date
int weekdayIndex = cal.get(Calendar.DAY_OF_WEEK);
return weekdayIndex;
I know DAY_OF_WEEK returns 1(Sunday) to 7(Saturday), but if I test this method with
2014-01-06 I get index 5 (suppost to be 2)
2014-01-07 I get index 6 (suppost to be 3)
(I live in Berlin UTC+01:00 - if it matters)
You should use:
cal.set(year, month-1, day); // data of this date
Do note the month-1 part instead of month+1.
Assuming that month's value is:
1 for Jan
2 for Feb
3 for Mar
...
What is month in your scenario? If it's 0 for "January", you are adding 1 when calling the set method. But months in Java are zero-based, so you're setting "February", and February 6th, 2014 is a Thursday (5), and February 7th, 2014 is a Friday (6).
month - the value used to set the MONTH calendar field. Month value is 0-based. e.g., 0 for January.
Try changing
cal.set(year, month+1, day);
to
cal.set(year, month, day);
FYI, Joda-Time 2.3 has convenient methods for such work.
The DateTime class offers a dayOfWeek method. From that you can derive either the localized name of the day, and to your needs, the number. Joda-Time counts days using the international standard ISO 8601, where Monday is 1 and Sunday is 7.
Example code…
// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
// import org.joda.time.*;
DateTimeZone berlinTimeZone = DateTimeZone.forID( "Europe/Berlin" );
DateTime dateTime = new DateTime( 2013, DateTimeConstants.DECEMBER, 13, 14, 15, 16, berlinTimeZone );
String dayOfWeekAsText = dateTime.dayOfWeek().getAsText( Locale.GERMANY );
int dayOfWeekAsNumber = dateTime.dayOfWeek().get();
System.out.println( "dayOfWeekAsText: " + dayOfWeekAsText );
System.out.println( "dayOfWeekAsNumber: " + dayOfWeekAsNumber );
When run…
dayOfWeekAsText: Freitag
dayOfWeekAsNumber: 5
Easy to jump to another month.
DateTime previousMonthDateTime = dateTime.minusMonths( 1 );
DateTime nextMonthDateTime = dateTime.plusMonths( 1 );
int day = Integer.parseInt(request.getParameter("day")); // 25
int month = Integer.parseInt(request.getParameter("month")); // 12
int year = Integer.parseInt(request.getParameter("year")); // 1988
System.out.println(year);
Calendar c = Calendar.getInstance();
c.set(year, month, day, 0, 0);
b.setDob(c.getTime());
System.out.println(b.getDob());
Output is:
1988
Wed Jan 25 00:00:08 IST 1989
I am passing 25 12 1988 but I get 25 Jan 1989. Why?
Months are zero-based in Calendar. So 12 is interpreted as december + 1 month. Use
c.set(year, month - 1, day, 0, 0);
That's my favorite way prior to Java 8:
Date date = new GregorianCalendar(year, month - 1, day).getTime();
I'd say this is a bit cleaner than:
calendar.set(year, month - 1, day, 0, 0);
java.time
Using java.time framework built into Java 8
int year = 2015;
int month = 12;
int day = 22;
LocalDate.of(year, month, day); //2015-12-22
LocalDate.parse("2015-12-22"); //2015-12-22
//with custom formatter
DateTimeFormatter.ofPattern formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy");
LocalDate.parse("22-12-2015", formatter); //2015-12-22
If you need also information about time(hour,minute,second) use some conversion from LocalDate to LocalDateTime
LocalDate.parse("2015-12-22").atStartOfDay() //2015-12-22T00:00
Java's Calendar representation is not the best, they are working on it for Java 8. I would advise you to use Joda Time or another similar library.
Here is a quick example using LocalDate from the Joda Time library:
LocalDate localDate = new LocalDate(year, month, day);
Date date = localDate.toDate();
Here you can follow a quick start tutorial.
See JavaDoc:
month - the value used to set the MONTH calendar field. Month value is
0-based. e.g., 0 for January.
So, the month you set is the first month of next year.
Make your life easy when working with dates, timestamps and durations. Use HalDateTime from
http://sourceforge.net/projects/haldatetime/?source=directory
For example you can just use it to parse your input like this:
HalDateTime mydate = HalDateTime.valueOf( "25.12.1988" );
System.out.println( mydate ); // will print in ISO format: 1988-12-25
You can also specify patterns for parsing and printing.
This question already has answers here:
Is there a good way to get the date of the coming Wednesday?
(6 answers)
Closed 3 years ago.
I asked How to detect if a date is within this or next week in Java? but the answers were confusing, so now I think if I can find the past Sunday and the coming Sunday, any day in between is this week, and any day between the coming Sunday and the Sunday after that is next week, am I correct ?
So my new question is : How to get the past Sunday and the coming Sunday in Java ?
java.time
Briefly:
LocalDate.now().with( next( SUNDAY ) )
See this code run live at IdeOne.com.
Details
I thought I'd add a Java 8 solution for posterity. Using LocalDate, DayOfWeek, and TemporalAdjuster implementation found in the TemporalAdjusters class.
final LocalDate today = LocalDate.of(2015, 11, 20);
final LocalDate nextSunday = today.with(next(SUNDAY));
final LocalDate thisPastSunday = today.with(previous(SUNDAY));
This approach also works for other temporal classes like ZonedDateTime.
import
As written, it assumes the following static imports:
import java.time.LocalDate;
import static java.time.DayOfWeek.SUNDAY;
import static java.time.temporal.TemporalAdjusters.next;
import static java.time.temporal.TemporalAdjusters.previous;
How about this :
Calendar c=Calendar.getInstance();
c.set(Calendar.DAY_OF_WEEK,Calendar.SUNDAY);
c.set(Calendar.HOUR_OF_DAY,0);
c.set(Calendar.MINUTE,0);
c.set(Calendar.SECOND,0);
DateFormat df=new SimpleDateFormat("EEE yyyy/MM/dd HH:mm:ss");
System.out.println(df.format(c.getTime())); // This past Sunday [ May include today ]
c.add(Calendar.DATE,7);
System.out.println(df.format(c.getTime())); // Next Sunday
c.add(Calendar.DATE,7);
System.out.println(df.format(c.getTime())); // Sunday after next
The result :
Sun 2010/12/26 00:00:00
Sun 2011/01/02 00:00:00
Sun 2011/01/09 00:00:00
Any day between the first two is this week, anything between the last two is next week.
Without using a better time/date package...
DateFormat df = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL);
Calendar now = new GregorianCalendar();
Calendar start = new GregorianCalendar(now.get(Calendar.YEAR),
now.get(Calendar.MONTH), now.get(Calendar.DAY_OF_MONTH) );
while (start.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY) {
start.add(Calendar.DAY_OF_WEEK, -1);
}
Calendar end = (Calendar) start.clone();
end.add(Calendar.DAY_OF_MONTH, 7);
System.out.println(df.format(now.getTime()) );
System.out.println(df.format(start.getTime()) );
System.out.println(df.format(end.getTime()) );
If today is Sunday, it is considered the start of the time period. If you want a period of this week and next week (as it sounds from your question), you can substitute 14 instead of 7 in the end.add(...) line. The times are set to midnight for comparison of another object falling between start and end.
First, don't use the Date/Time package from Java. There is a much better utility package called Joda-Time - download that and use it.
To determine if your time is in this week, last week, or any week at all, do this:
Create two Interval objects - one for last week and one for this week
Use the contains( long ) method to determine which interval holds the date you are looking for.
There are several cool ways you can create two back to back weeks. You could set up a Duration of one week, find the start time for the first week, and just create two Intervals based on that start time. Feel free to find any other way that works for you - the package has numerous ways to get to what you want.
EDIT:
Joda-Time can be downloaded here, and here is an example of how Joda would do this:
// Get the date today, and then select midnight of the first day of the week
// Joda uses ISO weeks, so all weeks start on Monday.
// If you want to change the time zone, pass a DateTimeZone to the method toDateTimeAtStartOfDay()
DateTime midnightToday = new LocalDate().toDateTimeAtStartOfDay();
DateTime midnightMonday = midnightToday.withDayOfWeek( DateTimeConstants.MONDAY );
// If your week starts on Sunday, you need to subtract one. Adjust accordingly.
DateTime midnightSunday = midnightMonday.plusDays( -1 );
DateTime midnightNextSunday = midnightSunday.plusDays( 7 );
DateTime midnightSundayAfter = midnightNextSunday.plusDays( 7 );
Interval thisWeek = new Interval( midnightSunday, midnightNextSunday );
Interval nextWeek = new Interval( midnightNextSunday, midnightSundayAfter );
if ( thisWeek.contains( someDate.getTime() )) System.out.println("This week");
if ( nextWeek.contains( someDate.getTime() )) System.out.println("Next week");
Given bellow next Sunday code and you can easily figure out how to find past Sunday.
private static void nextSunday() throws ParseException
{
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date());
int weekday = calendar.get(Calendar.DAY_OF_WEEK);
int days = Calendar.SUNDAY - weekday;
if (days < 0)
{
days += 7;
}
calendar.add(Calendar.DAY_OF_YEAR, days);
System.out.println(sdf.format(calendar.getTime()));
}
I recently developed Lamma Date which is designed to solve this use case:
Date today = new Date(2014, 7, 1); // assume today is 2014-07-01
Date previousSunday = today.previousOrSame(DayOfWeek.SUNDAY); // 2014-06-29
Date nextSunday = today.next(DayOfWeek.SUNDAY); // 2014-07-06
http://download.oracle.com/javase/1.4.2/docs/api/java/util/Date.html
I recommend Calendar.get(Calendar.DAY_OF_WEEK)
You could try to work with the Calendar.WEEK_OF_YEAR field, which gives you the numeric representation of the week within the current year.
#Test
public void testThisAndNextWeek() throws Exception {
GregorianCalendar lastWeekCal = new GregorianCalendar(2010,
Calendar.DECEMBER, 26);
int lastWeek = lastWeekCal.get(Calendar.WEEK_OF_YEAR);
GregorianCalendar nextWeekCal = new GregorianCalendar(2011,
Calendar.JANUARY, 4);
int nextWeek = nextWeekCal.get(Calendar.WEEK_OF_YEAR);
GregorianCalendar todayCal = new GregorianCalendar(2010,
Calendar.DECEMBER, 27);
int currentWeek = todayCal.get(Calendar.WEEK_OF_YEAR);
assertTrue(lastWeekCal.before(todayCal));
assertTrue(nextWeekCal.after(todayCal));
assertEquals(51, lastWeek);
assertEquals(52, currentWeek);
// New Year.. so it's 1
assertEquals(1, nextWeek);
}
My Solution:
LocalDate date = ...;
LocalDate newWeekDate = date.plusDays(1);
while (newWeekDate.getDayOfWeek() != DayOfWeek.SATURDAY &&
newWeekDate.getDayOfWeek() != DayOfWeek.SUNDAY) {
newWeekDate = date.plusDays(1);
}
I have the start date and the end date. I need to iterate through every day between these 2 dates.
What's the best way to do this?
I can suggest only something like:
Date currentDate = new Date (startDate.getTime ());
while (true) {
if (currentDate.getTime () >= endDate.getTime ())
break;
doSmth ();
currentDate = new Date (currentDate.getTime () + MILLIS_PER_DAY);
}
ready to run ;-)
public static void main(String[] args) throws ParseException {
GregorianCalendar gcal = new GregorianCalendar();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd");
Date start = sdf.parse("2010.01.01");
Date end = sdf.parse("2010.01.14");
gcal.setTime(start);
while (gcal.getTime().before(end)) {
gcal.add(Calendar.DAY_OF_YEAR, 1);
System.out.println( gcal.getTime().toString());
}
}
Ditto on those saying to use a Calendar object.
You can get into surprising trouble if you try to use a Date object and add 24 hours to it.
Here's a riddle for you: What is the longest month of the year? You might think that there is no answer to that question. Seven months have 31 days each, so they are all the same length, right? Well, in the United States that would be almost right, but in Europe it would be wrong! In Europe, October is the longest month. It has 31 days and 1 hour, because Europeans set their clocks back 1 hour for Daylight Saving Time in October, making one day in October last 25 hours. (Americans now begin DST in November, which has 30 days, so November is still shorter than October or December. Thus making that riddle not as amusing for Americans.)
I once ran into trouble by doing exactly what you're trying to do: I used a Date object and added 24 hours to it in a loop. It worked as long as I didn't cross Daylight Saving Time boundaries. But when I did, suddenly I skipped a day or hit the same day twice, because Midnight March 8, 2009 + 24 hours = 1:00 AM March 10. Drop off the time, as I was doing, and March 9 was mysteriously skipped. Likewise midnight Nov 1, 2009 + 24 hours = 11:00 PM Nov 1, and we hit Nov 1 twice.
Use a Calendar object if you want to manipulate dates.
Calendar c = Calendar.getInstance();
// ... set the calendar time ...
Date endDate = new Date();
// ... set the endDate value ...
while (c.getTime().before(endDate) {
// do something
c.add(Calendar.DAY_OF_WEEK, 1);
}
Or use Joda Time
I highly recommend using Joda time:
Java Joda Time - Implement a Date range iterator