How do I find the difference in Days between two Joda-Time DateTime instances?
With ‘difference in days’ I mean if start is on Monday and end is on Tuesday I expect a return value of 1 regardless of the hour/minute/seconds of the start and end dates.
Days.daysBetween(start, end).getDays() gives me 0 if start is in the evening and end in the morning.
I'm also having the same issue with other date fields so I was hoping there would be a generic way to 'ignore' the fields of lesser significance.
In other words, the months between Feb and 4 March would also be 1, as would the hours between 14:45 and 15:12 be. However the hour difference between 14:01 and 14:55 would be 0.
Annoyingly, the withTimeAtStartOfDay answer is wrong, but only occasionally. You want:
Days.daysBetween(start.toLocalDate(), end.toLocalDate()).getDays()
It turns out that "midnight/start of day" sometimes means 1am (daylight savings happen this way in some places), which Days.daysBetween doesn't handle properly.
// 5am on the 20th to 1pm on the 21st, October 2013, Brazil
DateTimeZone BRAZIL = DateTimeZone.forID("America/Sao_Paulo");
DateTime start = new DateTime(2013, 10, 20, 5, 0, 0, BRAZIL);
DateTime end = new DateTime(2013, 10, 21, 13, 0, 0, BRAZIL);
System.out.println(daysBetween(start.withTimeAtStartOfDay(),
end.withTimeAtStartOfDay()).getDays());
// prints 0
System.out.println(daysBetween(start.toLocalDate(),
end.toLocalDate()).getDays());
// prints 1
Going via a LocalDate sidesteps the whole issue.
Days Class
Using the Days class with the withTimeAtStartOfDay method should work:
Days.daysBetween(start.withTimeAtStartOfDay() , end.withTimeAtStartOfDay() ).getDays()
you can use LocalDate:
Days.daysBetween(new LocalDate(start), new LocalDate(end)).getDays()
tl;dr
java.time.temporal.ChronoUnit.DAYS.between(
earlier.toLocalDate(),
later.toLocalDate()
)
…or…
java.time.temporal.ChronoUnit.HOURS.between(
earlier.truncatedTo( ChronoUnit.HOURS ) ,
later.truncatedTo( ChronoUnit.HOURS )
)
java.time
FYI, the Joda-Time project is now in maintenance mode, with the team advising migration to the java.time classes.
The equivalent of Joda-Time DateTime is ZonedDateTime.
ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime now = ZonedDateTime.now( z ) ;
Apparently you want to count the days by dates, meaning you want to ignore the time of day. For example, starting a minute before midnight and ending a minute after midnight should result in a single day. For this behavior, extract a LocalDate from your ZonedDateTime. The LocalDate class represents a date-only value without time-of-day and without time zone.
LocalDate localDateStart = zdtStart.toLocalDate() ;
LocalDate localDateStop = zdtStop.toLocalDate() ;
Use the ChronoUnit enum to calculate elapsed days or other units.
long days = ChronoUnit.DAYS.between( localDateStart , localDateStop ) ;
Truncate
As for you asking about a more general way to do this counting where you are interested the delta of hours as hour-of-the-clock rather than complete hours as spans-of-time of sixty minutes, use the truncatedTo method.
Here is your example of 14:45 to 15:12 on same day.
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime start = ZonedDateTime.of( 2017 , 1 , 17 , 14 , 45 , 0 , 0 , z );
ZonedDateTime stop = ZonedDateTime.of( 2017 , 1 , 17 , 15 , 12 , 0 , 0 , z );
long hours = ChronoUnit.HOURS.between( start.truncatedTo( ChronoUnit.HOURS ) , stop.truncatedTo( ChronoUnit.HOURS ) );
1
This does not work for days. Use toLocalDate() in this case.
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.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
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.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). 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 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 accepted answer builds two LocalDate objects, which are quite expensive if you are reading lot of data.
I use this:
public static int getDaysBetween(DateTime earlier, DateTime later)
{
return (int) TimeUnit.MILLISECONDS.toDays(later.getMillis()- earlier.getMillis());
}
By calling getMillis() you use already existing variables.
MILLISECONDS.toDays() then, uses a simple arithmetic calculation, does not create any object.
java.time.Period
Use the java.time.Period class to count days.
Since Java 8 calculating the difference is more intuitive using LocalDate, LocalDateTime to represent the two dates
LocalDate now = LocalDate.now();
LocalDate inputDate = LocalDate.of(2018, 11, 28);
Period period = Period.between( inputDate, now);
int diff = period.getDays();
System.out.println("diff = " + diff);
(KOTLIN) For Difference between a constant date and current date (Joda)
You can use Days.daysBetween(jodaDate1,jodaDate2)
Here is an example:
val dateTime: DateTime = DateTime.parse("14/09/2020",
DateTimeFormat.forPattern("dd/MM/yyyy"))
val currentDate = DateTime.now()
//To calculate the days in between
val dayCount = Days.daysBetween(dateTime,currentDate).days
//Set Value to TextView
binding.daysCount.text = dayCount.toString()
DateTime dt = new DateTime(laterDate);
DateTime newDate = dt.minus( new DateTime ( previousDate ).getMillis());
System.out.println("No of days : " + newDate.getDayOfYear() - 1 );
public static int getDifferenceIndays(long timestamp1, long timestamp2) {
final int SECONDS = 60;
final int MINUTES = 60;
final int HOURS = 24;
final int MILLIES = 1000;
long temp;
if (timestamp1 < timestamp2) {
temp = timestamp1;
timestamp1 = timestamp2;
timestamp2 = temp;
}
Calendar startDate = Calendar.getInstance(TimeZone.getDefault());
Calendar endDate = Calendar.getInstance(TimeZone.getDefault());
endDate.setTimeInMillis(timestamp1);
startDate.setTimeInMillis(timestamp2);
if ((timestamp1 - timestamp2) < 1 * HOURS * MINUTES * SECONDS * MILLIES) {
int day1 = endDate.get(Calendar.DAY_OF_MONTH);
int day2 = startDate.get(Calendar.DAY_OF_MONTH);
if (day1 == day2) {
return 0;
} else {
return 1;
}
}
int diffDays = 0;
startDate.add(Calendar.DAY_OF_MONTH, diffDays);
while (startDate.before(endDate)) {
startDate.add(Calendar.DAY_OF_MONTH, 1);
diffDays++;
}
return diffDays;
}
Related
I am new to Java and I already have c# code which I have to convert it into java, but am not able to find good alternative to it.
Below is the code that I want to convert:
private string GetDate(object value)
{
DateTime start = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
var lastWeek = DateTime.Today.AddDays(-6);
var date = start.AddMilliseconds((long)value).ToLocalTime();
if (date >= lastWeek)
{
if (date.DayOfWeek == DateTime.Now.DayOfWeek)
return "Today";
else
return date.DayOfWeek.ToString();
}
else
return date.ToString("dd-MM-yyy");
}
I tried using Calendar class at first, but it's giving error that integer number too large:
Calendar cal = Calendar.getInstance();
cal.set(1970, 0, 1, 0, 0, 0);
cal.set(Calendar.MILLISECOND, 0);
long result = cal.getTimeInMillis();
long value = result + 1406205185123;
Any solution/suggestion will be helpful.
I haven't checked if it satisfies all your requirements regarding the output, but I think it will give enough pointers to help you out. Depending on your needs you need a ZonedDateTime (which has a timezone), or a LocalDateTime, which is the date as people speak about it in a country.
private String getDate(long value) {
LocalDateTime now = LocalDateTime.now();
LocalDateTime start = LocalDateTime.of(1970, 1, 1, 0, 0, 0, 0);
LocalDateTime lastWeek = now.minusDays(6);
LocalDateTime date = start.plus(value, ChronoUnit.MILLIS);
if (lastWeek.isBefore(date)) {
DayOfWeek dayOfWeek = date.getDayOfWeek();
if (dayOfWeek == now.getDayOfWeek()) {
return "Today";
} else {
return dayOfWeek.name();
}
}
return date.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT));
}
I've also took the liberty to convert the code style to what is usual in Java, which is the placing of the opening brace, the capitalization of functions.
More on the date/time classes can be found in the Oracle Trail on date/time.
tl;dr
ZoneId z = ZoneId.of( "Pacific/Auckland" ) ; // The time zone of your business context.
LocalDate input = Instant.ofEpochMilli( yourMillis ).atZone( z ).toLocalDate() ;
LocalDate today = LocalDate.now( z ) ;
LocalDate weekAgo = today.minusDays( 6 ) ;
if ( input.isAfter( today ) ) { … error }
else if ( input.isEqual( today ) ) { return "Today" ; }
else if ( ! input.isBefore( weekAgo ) ) { return input.getDayOfWeek().getDisplayName( TextStyle.FULL , Locale.US ) ; }
else if ( input.isBefore( weekAgo ) ) { return input.format( DateTimeFormatter.ofPattern( "dd-MM-uuuu" ) ) ; }
else { … error, unreachable point }
Details
DateTime start = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
Instead, for a point on the timeline in UTC, use Instant. The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).
Your example of first moment of 1970 UTC happens to be the epoch reference used by the java.time framework. And it happens to be defined as a constant.
Instant start = Instant.EPOCH ;
Add your count of milliseconds.
Instant later = start.plusMillis( yourMillis ) ;
But if your count of milliseconds is always a count since the epoch reference, then you can shorten that code above.
Instant instantInput = Instant.ofEpochMilli( yourMillis ) ; // Determine a moment in UTC from a count of milliseconds since 1970-01-01T00:00Z.
Apparently your goal is to compare dates or day-of-week. Both of those require a time zone. You ignore this crucial issue in your Question. For any given moment, the date varies around the globe by zone. At this moment right now is Monday in the United States, but in New Zealand it is “tomorrow” Tuesday.
Apply a ZoneId to get a ZonedDateTime. Same moment, same point on the timeline, but seen through the wall-clock time used by the people of a particular region (a time zone).
ZoneId z = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdtInput = instantInput.atZone( z ) ;
Extract the date-only, without a time-of-day and without a time zone.
LocalDate ldInput = zdtInput.toLocalDate() ;
Extract the day-of-week, represented by the DayOfWeek enum.
DayOfWeek dowInput = ldInput.getDayOfWeek() ;
Subtract six days from now. Represent the six days as TemporalAmount, either six calendar days in a Period or six chunks of 24-hours as a Duration.
Period sixDays = Period.ofDays( 6 ) ;
LocalDate today = LocalDate.now( z ) ;
LocalDate sixDaysBeforeToday = today.minus( sixDays ); // Or LocalDate.now( z ).plusDays( 6 )
Compare. Let's simplify your branching logic. We will work chronologically in reverse order through five cases: future, today, past six days, prior, impossible.
if( ldInput.ifAfter( today ) ) {
System.out.println( "ERROR - input is in the future. Not expected." ) ;
} else if( ldInput.isEqual( today ) ) {
return "Today" ;
} else if ( ! ldInput.isBefore( sixDaysBeforeToday ) ) { // A shorter way of asking "is equal to OR later" is asking "is NOT before".
return dowInput.getDisplayName( TextStyle.FULL , Locale.US ) ; // Let java.time localize the name of the day-of-week.
} else if ( ldInput.isBefore ( sixDaysBeforeToday ) ) {
return ldInput.format( DateTimeFormatter.ofPattern( "dd-MM-uuuu" ) ) ;
} else {
System.out.println( "ERROR - Reached impossible point." ) ; // Defensive programming.
}
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.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
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.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). 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.
I would like to create a DateHelper class and for that I'm using DateUtils from Apache Commons Lang 2.6.
I'm having problems understanding the result returned when extract field from a date. Here is my test class which extract the day of month after truncate the date :
public class DateTest {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// Date date = createDate(2000, 1, 2, 3, 4, 5, 6);
Calendar calendar = createEmptyUTCCalendar();
calendar.set(Calendar.YEAR, 2000);
calendar.set(Calendar.MONTH, 0); // january
calendar.set(Calendar.DAY_OF_MONTH, 2);
calendar.set(Calendar.HOUR_OF_DAY, 3);
calendar.set(Calendar.MINUTE, 4);
calendar.set(Calendar.SECOND, 5);
calendar.set(Calendar.MILLISECOND, 6);
Date date = calendar.getTime();
System.out.println("Input date\n" + date);
// Truncate from day of month.
Date dateTruncate = getDatePart(date);
System.out.println("Truncate the date\n" + dateTruncate);
System.out.println("\n*** Extract day of month ***");
// Extract the field day of month from the truncated date.
int fieldDayOfMonth = getField(dateTruncate, Calendar.DAY_OF_MONTH);
System.out.println("Expected result is 2\nActual result is " + fieldDayOfMonth);
assert fieldDayOfMonth == 2;
}
public static int getField(Date date, int calendarField) {
Calendar calendar = createEmptyUTCCalendar();
calendar.setTime(date);
int value = calendar.get(calendarField);
if (calendarField == Calendar.MONTH) {
value++;
}
return value;
}
public static Date getDatePart(Date date) {
return DateUtils.truncate(date, Calendar.DAY_OF_MONTH);
}
private static Calendar createEmptyUTCCalendar() {
Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
return calendar;
}
}
I expect the result of extracting the field Calendar.DAY_OF_MONTH to be 2 but I got 1.
Input date
Sun Jan 02 04:04:05 CET 2000
Truncate the date
Sun Jan 02 00:00:00 CET 2000
*** Extract day of month ***
Expected result is 2
Actual result is 1
tl;dr
LocalDate.of( 2000 , Month.JANUARY , 2 )
.getDayOfMonth()
2
java.time
You can just use Java now, no need for Apache DateUtils. And truncation is the wrong way to think about it; just interrogate for the day-of-month property.
Specify your date using LocalDate class. Note that java.time uses sane month numbering, 1-12 for January to December.
LocalDate ld = LocalDate.of( 2000 , 1 , 2 ) ; // January 2, 2000.
Or use the Month enum.
LocalDate ld = LocalDate.of( 2000 , Month.JANUARY , 2 ) ; // January 2, 2000.
2000-01-02
Interrogate for day-of-month. You can call getDayOfMonth on a LocalDate, OffsetDateTime, and ZonedDateTime.
int dayOfMonth = ld.getDayOfMonth() ;
2
If receiving a Calendar object, it is likely a GregorianCalendar. If so, you can easily convert to java.time classes.
if( myCalendar instanceOf GregorianCalendar ) {
GregorianCalendar gc = ( GregorianCalendar ) myCalendar ; // Cast.
ZonedDateTime zdt = gc.toZonedDateTime() ; // Convert from legacy class to modern class.
int dayOfMonth = zdt.getDayOfMonth() ;
}
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.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
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.
It seems that the thing is on the timezones. Your calendar is on UTC and your date on your local zone, if you avoid the line:
calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
the thing should work.
When you pass calendar to Date, the date object gets default time zone CET in your case. Then you truncate and pass again to a UTC calendar, and due to the diffenrence between CET and UTC you day is the previous one.
I am wondering how I would loop through a date/time or any type of variable to go from 00:00 to 24:00 every 30 Mins?
So I need a variable that shows times in 24HR format (01:00, 09:00) and every time I loop through it, to add 30 mins to the time? I then need to use this value in a string.
The time needs to start at 00:00AM and will end with 24:00.
Any ideas how should I go with it?
output should be like this - 00:00 00:30 01:00 ....24:00
Possibly a little over kill, but it does all the auto rolling and allows the use of DateFormat
DateFormat df = new SimpleDateFormat("HH:mm");
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
int startDate = cal.get(Calendar.DATE);
while (cal.get(Calendar.DATE) == startDate) {
System.out.println(df.format(cal.getTime()));
cal.add(Calendar.MINUTE, 30);
}
You can't have 24:00 as it's 00:00...
Try to use this this code
private void displayTimeSlots() {
String timeValue = "T00:00:4.896+05:30";
SimpleDateFormat sdf = new SimpleDateFormat("'T'hh:mm:ss.SSS");
try {
Calendar startCalendar = Calendar.getInstance();
startCalendar.setTime(sdf.parse(timeValue));
if (startCalendar.get(Calendar.MINUTE) < 30) {
startCalendar.set(Calendar.MINUTE, 30);
} else {
startCalendar.add(Calendar.MINUTE, 30); // overstep hour and clear minutes
startCalendar.clear(Calendar.MINUTE);
}
Calendar endCalendar = Calendar.getInstance();
endCalendar.setTime(startCalendar.getTime());
// if you want dates for whole next day, uncomment next line
//endCalendar.add(Calendar.DAY_OF_YEAR, 1);
endCalendar.add(Calendar.HOUR_OF_DAY, 24 - startCalendar.get(Calendar.HOUR_OF_DAY));
endCalendar.clear(Calendar.MINUTE);
endCalendar.clear(Calendar.SECOND);
endCalendar.clear(Calendar.MILLISECOND);
SimpleDateFormat slotTime = new SimpleDateFormat("hh:mm a");
while (endCalendar.after(startCalendar)) {
startCalendar.add(Calendar.MINUTE, 30);
String Timeslots = slotTime.format(startCalendar.getTime());
Log.e("DATE", Timeslots);
}
} catch (ParseException e) {
// date in wrong format
}
}
tl;dr
myLocalTime.plusMinutes( gapInMinutes ) // Using `java.time.LocalTime` class.
Details
I am answering your Question as written, for a 24-hour day. But beware that days are not always that length. They may be 23, 25, or some other number of hours.
No such thing as 24:00 as that means rolling over to 00:00. So a duration of 30 minutes means ending at 23:30.
java.time
The modern approach uses the java.time classes that supplant the troublesome old date-time time classes.
LocalTime & Duration
The LocalTime class represents a time-of-day without date and without time zone. This class assumes a generic 24-hour day (unrealistic though that is).
The Duration class represents a span-of-time not attached to the timeline.
int gapInMinutes = 30 ; // Define your span-of-time.
int loops = ( (int) Duration.ofHours( 24 ).toMinutes() / gapInMinutes ) ;
List<LocalTime> times = new ArrayList<>( loops ) ;
LocalTime time = LocalTime.MIN ; // '00:00'
for( int i = 1 ; i <= loops ; i ++ ) {
times.add( time ) ;
// Set up next loop.
time = time.plusMinutes( gapInMinutes ) ;
}
System.out.println( times.size() + " time slots: " ) ;
System.out.println( times ) ;
See this code run live at IdeOne.com.
48 time slots:
[00:00, 00:30, 01:00, 01:30, 02:00, 02:30, 03:00, 03:30, 04:00, 04:30, 05:00, 05:30, 06:00, 06:30, 07:00, 07:30, 08:00, 08:30, 09:00, 09:30, 10:00, 10:30, 11:00, 11:30, 12:00, 12:30, 13:00, 13:30, 14:00, 14:30, 15:00, 15:30, 16:00, 16:30, 17:00, 17:30, 18:00, 18:30, 19:00, 19:30, 20:00, 20:30, 21:00, 21:30, 22:00, 22:30, 23:00, 23:30]
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.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
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.
try this -
Calendar instance = Calendar.getInstance();
instance.setTime(new SimpleDateFormat("hh:mm:ss a").parse("00:00:00 AM"));
System.out.println(instance.getTime());
int i=1;
while(i++!=49){
instance.add(Calendar.MINUTE, 30);
System.out.println(instance.getTime());
}
I would to get the number of the half month od the year starting from a date.
For example, I have 13-Mar-2012, and I have 6 as result.
I've tried with Calendar class, but doesn't work properly:
Calendar cal = (GregorianCalendar) Calendar.getInstance();
cal.set(Calendar.DAY_OF_MONTH,13);
cal.set(Calendar.MONTH, 2);
cal.set(Calendar.YEAR, 2012);
int weekNum = cal.get(Calendar.WEEK_OF_YEAR);
System.out.println("Weeknum:" + ((weekNum/2)));
Can anyone help me?
Assuming Half month as defined here: http://en.wikipedia.org/wiki/Half-month
Calendar cal = (GregorianCalendar) Calendar.getInstance();
cal.set(Calendar.DAY_OF_MONTH, 13);
cal.set(Calendar.MONTH, 2);
cal.set(Calendar.YEAR, 2012);
// remember, we have a zero based month
int halfMonth = cal.get( Calendar.MONTH ) * 2 + 1;
// 1-15 is first half-month 16-end of month is second
int remainder = cal.get( Calendar.DAY_OF_MONTH ) / 16;
halfMonth += remainder;
System.out.println( halfMonth );
Calendar cal = (GregorianCalendar) Calendar.getInstance();
cal.set(Calendar.DAY_OF_MONTH,13);
cal.set(Calendar.MONTH, 2);
cal.set(Calendar.YEAR, 2012);
int hafMonthCount = cal.get(Calendar.DAY_OF_YEAR) / 14 ;
//here you must multiply by 2 :)
System.out.println("HalfMonthCount:" + hafMonthCount );
---updated
As the concept you use is not implemented in Java (in french we have this concept of quizaine for 14 days but in english I can't say), you must compute it by yourself.
Details to show by example what happens with your code. Assume we have the following four different values of WEEK_OF_YEAR:
WEEK_OF_YEAR: 1
WEEK_OF_YEAR: 2
WEEK_OF_YEAR: 3
WEEK_OF_YEAR: 4
What will happen if we divide these values by 2?
WEEK_OF_YEAR: 1 (weekNum/2) = 1/2 = 0
WEEK_OF_YEAR: 2 (weekNum/2) = 2/2 = 1
WEEK_OF_YEAR: 3 (weekNum/2) = 3/2 = 1
WEEK_OF_YEAR: 4 (weekNum/2) = 4/2 = 2
So the issue with your code is that it will result in the first week of the year resulting in a value 0. So what you'd want to be doing in your code is to replace the (weekNum/2) with ((weekNum + 1)/2).
If the astronomy Half-Month is intended (not to be confused with an astronomy fortnight), then the Answer by jarrad is correct. But we have more modern classes at our disposal now, the java.time classes.
LocalDate
The LocalDate class represents a date-only value without time-of-day and without time zone.
A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate ld = LocalDate.now( z );
Get the month number, 1-12 for January-December.
int monthNumber = ld.getMonthValue(); // 1-12.
Multiply that month number by two, as there are two month-halves in every month. If early in the month, subtract one (so 6 becomes 5, for example).
int adjustment = ( ld.getDayOfMonth() < 16 ) ? 1 : 0 ; // If first half of month, back off the half-month-number by 1.
int halfMonthNumber = ( ( monthNumber * 2 ) - adjustment ); // 1-24.
The astronomy Half-Month labels each with a English letter, A-Y while omitting I. So we extract a letter from this subset alphabet of 24 letters by the half-month-number.
int index = ( halfMonthNumber - 1 ); // Subtract one for zero-based counting.
String alphaCode = "ABCDEFGHJKLMNOPQRSTUVWXY".substring( index , index + 1 );
I have not run that code, just typed off the top of my head. Use at your own risk, and please fix if needed.
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.
hi i want to make a program in java where days,weekNo is parameter ..Like First Friday of the month or second Monday of the month ..and it returns the date
Here's a utility method that does that, using DateUtils from Apache Commons / Lang:
/**
* Get the n-th x-day of the month in which the specified date lies.
* #param input the specified date
* #param weeks 1-based offset (e.g. 1 means 1st week)
* #param targetWeekDay (the weekday we're looking for, e.g. Calendar.MONDAY
* #return the target date
*/
public static Date getNthXdayInMonth(final Date input,
final int weeks,
final int targetWeekDay){
// strip all date fields below month
final Date startOfMonth = DateUtils.truncate(input, Calendar.MONTH);
final Calendar cal = Calendar.getInstance();
cal.setTime(startOfMonth);
final int weekDay = cal.get(Calendar.DAY_OF_WEEK);
final int modifier = (weeks - 1) * 7 + (targetWeekDay - weekDay);
return modifier > 0
? DateUtils.addDays(startOfMonth, modifier)
: startOfMonth;
}
Test code:
// Get this month's third thursday
System.out.println(getNthXdayInMonth(new Date(), 3, Calendar.THURSDAY));
// Get next month's second wednesday:
System.out.println(getNthXdayInMonth(DateUtils.addMonths(new Date(), 1),
2,
Calendar.WEDNESDAY)
);
Output:
Thu Nov 18 00:00:00 CET 2010
Wed Dec 08 00:00:00 CET 2010
And here's a JodaTime version of the same code (I've never used JodaTime before, so there's probably a simpler way to do it):
/**
* Get the n-th x-day of the month in which the specified date lies.
*
* #param input
* the specified date
* #param weeks
* 1-based offset (e.g. 1 means 1st week)
* #param targetWeekDay
* (the weekday we're looking for, e.g. DateTimeConstants.MONDAY
* #return the target date
*/
public static DateTime getNthXdayInMonthUsingJodaTime(final DateTime input,
final int weeks,
final int targetWeekDay){
final DateTime startOfMonth =
input.withDayOfMonth(1).withMillisOfDay(0);
final int weekDay = startOfMonth.getDayOfWeek();
final int modifier = (weeks - 1) * 7 + (targetWeekDay - weekDay);
return modifier > 0 ? startOfMonth.plusDays(modifier) : startOfMonth;
}
Test Code:
// Get this month's third thursday
System.out.println(getNthXdayInMonthUsingJodaTime(new DateTime(),
3,
DateTimeConstants.THURSDAY));
// Get next month's second wednesday:
System.out.println(getNthXdayInMonthUsingJodaTime(new DateTime().plusMonths(1),
2,
DateTimeConstants.WEDNESDAY));
Output:
2010-11-18T00:00:00.000+01:00
2010-12-08T00:00:00.000+01:00
public static Date getDate(int day, int weekNo, int month, int year) {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.DATE,1);
cal.set(Calendar.YEAR, year);
cal.set(Calendar.MONTH, month);
for (int i = 0; i < 31; i++) {
if (cal.get(Calendar.WEEK_OF_MONTH) == weekNo
&& cal.get(Calendar.DAY_OF_WEEK) == day) {
return cal.getTime();
}
cal.add(Calendar.DATE,1);
}
return null;
}
Calling code
System.out.println(""+getDate(Calendar.MONDAY, 2, Calendar.DECEMBER,2010));
Output
Mon Dec 06 15:09:00 IST 2010
Resource
Also look at Joda Time it is better
tl;dr
LocalDate firstFridayThisMonth =
LocalDate.now( ZoneId.of( "America/Montreal" ) )
.with( TemporalAdjusters.firstInMonth( DayOfWeek.FRIDAY ) )
Using java.time
The other Answers are now outdated. The troublesome old date-time classes (Date, Calendar, etc.) are now legacy, supplanted by the java.time classes.
LocalDate
The LocalDate class represents a date-only value without time-of-day and without time zone.
A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );
TemporalAdjuster
The TemporalAdjuster interface provides for manipulating date-time values. The java.time classes use immutable objects, so the result is always a fresh new object with values based on the original.
The TemporalAdjusters class (note plural name) provides several handy implementations. Amongst those are ones to get ordinal day-of-week within the month: firstInMonth(), lastInMonth(), and dayOfWeekInMonth(). All of these take an argument of a DayOfWeek enum object.
LocalDate firstFridayOfThisMonth =
today.with(
TemporalAdjusters.firstInMonth( DayOfWeek.FRIDAY )
)
;
…and…
LocalDate secondMondayOfThisMonth =
today.with(
TemporalAdjusters.dayOfWeekInMonth( 2 , DayOfWeek.MONDAY )
)
;
…and…
LocalDate thirdWednesdayOfNextMonth =
today.plusMonths( 1 )
.with(
TemporalAdjusters.dayOfWeekInMonth( 3 , DayOfWeek.WEDNESDAY )
)
;
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.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8 and SE 9 and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
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.
Calendar cal = Calendar.getInstance();
int dayofweek = cal.get(Calendar.DAY_OF_WEEK);
this should do what you want.
edit:
with some more calculate steps, you could have result :) (sorry for confuse your title)